Rate Limits
Understanding and handling rate limits.
LEAPERone applies per-user rate limits on a sliding window to ensure fair usage and service stability.
Current Limits
Limits are applied per user, per endpoint over a 1-minute window. Different endpoints may have different thresholds depending on the compute cost of each request.
Specific rate limit numbers may change over time. Always check the X-RateLimit-* response headers for the current values that apply to your request.
Rate Limit Headers
Every API response includes these headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum number of requests allowed in the current window. |
X-RateLimit-Remaining | Number of requests remaining in the current window. |
X-RateLimit-Reset | Unix timestamp (seconds) when the current window resets. |
Retry-After | Seconds until you can retry (only present on 429 responses). |
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1700000060Handling 429 Responses
When you exceed the rate limit, the API returns a 429 status:
{
"error": {
"message": "Rate limit exceeded. Please slow down.",
"type": "rate_limit_error",
"code": "rate_limit_exceeded"
}
}Use the Retry-After header to determine how long to wait before sending the next request.
Exponential Backoff
The recommended strategy for handling rate limits is exponential backoff with jitter:
async function fetchWithBackoff(url, options, maxRetries = 5) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.ok) return response;
if (response.status === 429) {
const retryAfter = response.headers.get("Retry-After");
const waitMs = retryAfter
? parseInt(retryAfter, 10) * 1000
: Math.min(1000 * 2 ** attempt, 30000);
const jitter = Math.random() * 1000;
console.warn(
`Rate limited. Retrying in ${Math.round((waitMs + jitter) / 1000)}s...`
);
await new Promise((r) => setTimeout(r, waitMs + jitter));
continue;
}
// Non-retryable error
throw new Error(`Request failed with status ${response.status}`);
}
throw new Error("Max retries exceeded");
}Best Practices
- Monitor the headers. Check
X-RateLimit-Remainingproactively and slow down before hitting zero. - Queue requests. If you are making many calls in a batch, use a queue to space them out evenly across the window.
- Use jitter. Always add random jitter to backoff delays to prevent synchronized retries from multiple clients.
- Cache responses. If you call the same endpoint with the same parameters, cache the result to avoid unnecessary requests.