Rate Limits
Rate limits protect the API and ensure fair usage across all customers.
Limits by tier
| Tier | Requests/min | Requests/day | Burst | Monthly credits |
|---|---|---|---|---|
| Free | 10 | 1,000 | 5 | 10,000 |
| Standard | 100 | 50,000 | 50 | 500,000 |
| Professional | 1,000 | Unlimited | 200 | Unlimited |
| Enterprise | Custom | Custom | Custom | Custom |
Rate limit headers
Every API response includes these headers:
| Header | Description | Example |
|---|---|---|
X-RateLimit-Limit | Max requests per minute | 10 |
X-RateLimit-Remaining | Remaining in current window | 7 |
X-RateLimit-Reset | Unix timestamp when window resets | 1712345678 |
429 Too Many Requests
When you exceed the rate limit:
Response 429 Too Many Requests
json
{
"status": 429,
"error": "Too Many Requests",
"message": "Rate limit exceeded. Retry after 42s",
"timestamp": "2026-04-04T14:30:00Z"
}The response includes a Retry-After header (seconds until the window resets).
Retry strategy
Use exponential backoff with jitter:
typescript
async function callWithRetry(url: string, apiKey: string, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const res = await fetch(url, {
headers: { 'X-API-Key': apiKey },
});
if (res.status !== 429) return res;
const retryAfter = parseInt(res.headers.get('Retry-After') || '1');
const backoff = retryAfter * Math.pow(2, attempt);
const jitter = Math.random() * 0.5;
await new Promise(r => setTimeout(r, (backoff + jitter) * 1000));
}
throw new Error('Rate limit exceeded after all retries');
}Best practices
- Cache responses — wallet balances and prices rarely change sub-second
- Use batch endpoints — one batch call uses fewer rate limit tokens than N individual calls
- Monitor headers — track
X-RateLimit-Remainingto preemptively slow down - Upgrade your plan — if you consistently hit limits, you likely need more capacity