Rate limits
Requests are metered per user, not per key. If you have three API keys under one account, they all draw from the same quota.
Limits by tier
| Endpoint type | Free | Dev | Pro | Team |
|---|---|---|---|---|
| Live endpoints | 30/min | 60/min | 120/min | 120/min |
| Historical endpoints | — | 30/min | 100/min | 100/min |
| Bulk / export endpoints | — | — | — | Unrestricted |
Numbers are illustrative defaults and may be adjusted based on observed traffic patterns.
What a 429 looks like
When you exceed your quota, the API returns HTTP 429 Too Many Requests with a JSON body:
json
{
"error": "rate limit exceeded"
}Rate-limit headers
429 responses include three headers:
| Header | Value |
|---|---|
| X-RateLimit-Limit | Your tier's req/sec limit for this endpoint |
| X-RateLimit-Remaining | 0 (you're over limit) |
| Retry-After | 1 second |
These headers are only present on 429 responses. Successful requests do not include a remaining-count header.
Handling 429s
Use exponential backoff with jitter. Don't hammer the API on a fixed interval — that pattern tends to keep you in the limit window. A simple approach in Python:
python
import time, random, httpx
def fetch_with_backoff(url, headers, retries=5):
delay = 1.0
for attempt in range(retries):
resp = httpx.get(url, headers=headers)
if resp.status_code != 429:
return resp
jitter = random.uniform(0, delay * 0.1)
time.sleep(delay + jitter)
delay = min(delay * 2, 60) # cap at 60s
raise RuntimeError("Rate limit retries exhausted")If you're consistently hitting limits, consider caching responses locally or upgrading your plan. See pricing for higher-limit tiers.