Rate Limiting
The API uses a token-bucket rate limiter. Each client gets a bucket of tokens that refills linearly over the window period. Requests that exceed the limit receive HTTP 429 Too Many Requests.
Default Limits
| Parameter | Value |
|---|---|
| Max requests per window | 100 |
| Window duration | 60 seconds |
| Refill rate | ~1.67 requests/second |
Response Headers
Every response includes rate limit headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per window |
X-RateLimit-Remaining | Tokens remaining in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Retry-After | Seconds to wait (only on 429 responses) |
429 Response
HTTP/1.1 429 Too Many Requests
Retry-After: 3
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
{
"ok": false,
"error": "Too many requests",
"retry_after_seconds": 3
}Retry Strategy
When you receive a 429, wait for the number of seconds in the Retry-After header before retrying. Exponential backoff is recommended for burst scenarios:
async function fetchWithRetry(url, opts, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const res = await fetch(url, opts);
if (res.status !== 429) return res;
const retryAfter = Number(res.headers.get("Retry-After") ?? 1);
await new Promise((r) => setTimeout(r, retryAfter * 1000));
}
throw new Error("Rate limit exceeded after retries");
}