Platform
Rate limits
Burst and daily limits, plus the headers that tell you where you stand.
Limits
| Limit | Value | Scope |
|---|---|---|
| Burst | 60 requests/minute | Per API key, rolling window |
| Daily | 10,000 requests/day | Per API key, UTC day |
| Sandbox burst | 30 requests/minute | Test keys only |
NOTEHitting the daily limit returns
429 rate_limit_exceeded with a Retry-After header counting down to midnight UTC. Contact support to raise your quota.Response headers
Every response includes your current usage for the rolling minute:
X-RateLimit-Limit— requests allowed per minute.X-RateLimit-Remaining— requests left in the current window.X-RateLimit-Reset— Unix timestamp when the window resets.
Handling 429s
Back off for the full Retry-After window, then continue. Do not retry immediately in a tight loop — that compounds the pressure that caused the 429.
JavaScript
async function getOdds(url, key) {
const res = await fetch(url, {
headers: { "X-API-Key": key }
});
if (res.status === 429) {
const retryAfter = Number(res.headers.get("retry-after")) || 1;
await new Promise((r) => setTimeout(r, retryAfter * 1000));
return getOdds(url, key);
}
return res.json();
}Python
import time
import requests
def get_odds(url, key):
res = requests.get(url, headers={"X-API-Key": key})
if res.status_code == 429:
retry_after = float(res.headers.get("Retry-After", 1))
time.sleep(retry_after)
return get_odds(url, key)
return res.json()Recommended polling
Odds refresh every 30 seconds. Polling the odds endpoint more than twice per minute returns the same payload — cache for 30 seconds instead. See Get Odds.