Rate Limits by Tier
| Tier | Requests/sec | Chains | Burst |
|---|---|---|---|
| Free | 100 | 2 | 20 |
| Pro | 1,000 | All | 200 |
| Enterprise | Unlimited | All | Unlimited |
Rate Limit Headers
Every response includes:
| Header | Description |
|---|---|
X-RateLimit-Limit | Max requests per second |
X-RateLimit-Remaining | Requests remaining in window |
X-RateLimit-Reset | Unix timestamp of window reset |
Handling 429 Responses
When rate limited, the API returns HTTP 429 with a Retry-After header (seconds).
Best Practices
- Use WebSocket subscriptions instead of polling
- Cache chain status and block numbers locally
- Batch bundle submissions where possible
- Implement exponential backoff on 429s
- Upgrade to Pro tier for production workloads
Rate Limit Handling Example
async function apiCall(
url: string,
options: RequestInit,
retries = 3
) {
const res = await fetch(url, options);
if (res.status === 429 && retries > 0) {
const retryAfter = res.headers.get("Retry-After");
const delay = parseInt(retryAfter || "1") * 1000;
console.log(`Rate limited. Retry in ${delay}ms`);
await new Promise((r) => setTimeout(r, delay));
return apiCall(url, options, retries - 1);
}
// Log rate limit state
console.log({
limit: res.headers.get("X-RateLimit-Limit"),
remaining: res.headers.get("X-RateLimit-Remaining"),
reset: res.headers.get("X-RateLimit-Reset"),
});
return res.json();
}