Rate Limits
Understanding API rate limits and how to work within them.
Rate Limit Tiers
LedgerLink implements tiered rate limiting based on your subscription:
| Tier | Requests/Minute | Requests/Hour | Requests/Day |
|---|---|---|---|
| Free | 60 | 1,000 | 10,000 |
| Pro | 300 | 10,000 | 100,000 |
| Enterprise | Custom | Custom | Custom |
Rate Limit Headers
Every API response includes rate limit information in the headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1642694400
X-RateLimit-Limit- Maximum requests allowed in the current windowX-RateLimit-Remaining- Requests remaining in the current windowX-RateLimit-Reset- Unix timestamp when the rate limit resets
Handling Rate Limits
429 Too Many Requests
When you exceed the rate limit, you'll receive a 429 response:
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Please retry after 30 seconds.",
"retryAfter": 30
}
}
Best Practices
1. Monitor Headers
const response = await fetch(url, options);
const remaining = response.headers.get('X-RateLimit-Remaining');
const reset = response.headers.get('X-RateLimit-Reset');
if (remaining < 10) {
console.warn('Approaching rate limit');
}
2. Implement Exponential Backoff
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}
3. Batch Requests
// Instead of multiple single requests
const symbols = ['BTC-USD', 'ETH-USD', 'SOL-USD'];
// Use the unified query engine
const response = await fetch('http://localhost:8090/api/v1/query', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
connector: 'market-data',
filters: {
symbol: { $in: symbols }
}
})
});
4. Cache Responses
const cache = new Map();
const CACHE_TTL = 60000; // 1 minute
async function fetchWithCache(url, options) {
const cacheKey = url;
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const response = await fetch(url, options);
const data = await response.json();
cache.set(cacheKey, {
data,
timestamp: Date.now()
});
return data;
}
Upgrading Your Tier
Need higher rate limits? Contact us:
- 📧 Email: [email protected]
- 🌐 Dashboard: https://dashboard.ledgerlink.io/upgrade
WebSocket Alternative
For real-time data, consider using our WebSocket API which has separate, more generous limits:
const ws = new WebSocket('ws://localhost:8090/ws/ws');
ws.onopen = () => {
ws.send(JSON.stringify({
action: 'subscribe',
channel: 'candles',
symbol: 'BTC-USD'
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('New candle:', data);
};
Next Steps
- Quick Start - Make your first API call
- API Reference - Explore all endpoints
- Market Intelligence - Real-time market data