Rate Limits
To ensure fair usage and platform stability, all API requests are subject to rate limiting. Understand your limits and how to handle them gracefully.
Limits by Plan
How Rate Limiting Works
Sliding Window
We use a sliding window counter. Your limit resets gradually — not all at once. Each second, used capacity from 60 seconds ago is freed up.
Burst Allowance
A burst allowance lets you send a short spike of requests (e.g., 10 at once on Free) before the per-minute limit kicks in. Useful for batch loading.
Daily Reset
Daily limits reset at midnight UTC. Once exceeded, all requests return 429 until the next reset period begins.
Rate Limit Headers
Every API response includes headers that tell you your current rate limit status. Use these to build adaptive request logic.
Response Header Example
Here's what the response headers look like on a real request:
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 150
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1721824530
X-RateLimit-DailyLimit: 25000
X-RateLimit-DailyRemaining: 18340
X-Request-Id: req_8f14e45fceea167a5a36dedd4bea2543
When You Hit the Limit
When you exceed your rate limit, the API returns a 429 Too Many Requests status with a structured error body:
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Retry after 12 seconds.",
"status": 429,
"details": {
"limit": 150,
"remaining": 0,
"reset_at": "2025-07-24T10:15:30Z",
"retry_after": 12,
"daily_limit": 25000,
"daily_remaining": 18340
}
}
}
How to Handle Rate Limits
Follow these strategies to build resilient integrations that never break under load.
async function fetchWithBackoff(url, options = {}, maxRetries = 5) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) return response;
// Respect the Retry-After header
const retryAfter = response.headers.get('Retry-After');
const waitTime = retryAfter
? parseInt(retryAfter) * 1000
: Math.min(1000 * Math.pow(2, attempt), 30000);
console.warn(`Rate limited. Retrying in ${waitTime}ms...`);
await new Promise(r => setTimeout(r, waitTime));
}
throw new Error('Max retries exceeded');
}
Best Practices
Respect the Retry-After header
Always read the Retry-After header from 429 responses. Don't guess — the server tells you exactly how long to wait.
Use exponential backoff with jitter
When the Retry-After header is absent, use exponential backoff (1s, 2s, 4s, 8s…) with random jitter to avoid thundering herd scenarios.
Cache responses when possible
Sports and league lists rarely change. Cache them locally for 5–15 minutes to dramatically reduce API calls and stay well under your limits.
Monitor your usage in real-time
Log X-RateLimit-Remaining on every request. Set up alerts at 80% and 95% consumption to catch issues before they hit production.
Don't poll endpoints unnecessarily
Avoid polling unchanged data. Use WebSocket connections (coming soon) for live odds instead of repeatedly hitting GET endpoints.
Don't share API keys across services
Each service should have its own key so rate limits are isolated. One misbehaving service shouldn't bring down another.
Usage Gauge
Here's a visual representation of how your per-minute quota depletes and recovers over time:
Endpoint-Specific Notes
Some endpoints have additional constraints beyond your plan limits:
Live endpoints are more restrictive
Endpoints returning live/in-play data (/live-events, /markets/v2) consume 2x the normal rate limit quota per request.
Bulk endpoints have lower frequency limits
Endpoints that return large datasets (/leagues/{id}/matches, /leagues/{id}/results) are limited to 1 request per 5 seconds regardless of your plan.
List endpoints are lightweight
Simple list endpoints (/sports, /sports/{id}/leagues) consume 0.5x the normal rate — they're cheap and fast.
Frequently Asked Questions
429 until midnight UTC. Your per-minute limit continues to function independently within the daily cap. Consider upgrading your plan if you're consistently hitting daily limits.
Need more headroom?
Upgrade to Pro or Business for 5–20x more requests, or talk to us about a custom Enterprise plan.