Rate Limits
Limits are applied per API key, per minute, and per day. Response headers make consumption observable.
Limits by Tier
| Tier | Requests / min | Requests / day | Concurrent |
|---|---|---|---|
| Orbit & Fabric | 100 | 10,000 | 5 |
| Core | 500 | 50,000 | 20 |
| Atlas | Custom | Custom | Custom |
Response Headers
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Total requests allowed in the current window. |
X-RateLimit-Remaining | Requests remaining before the limit resets. |
X-RateLimit-Reset | Unix timestamp when the window resets. |
Retry-After | Seconds to wait after a 429 response before retrying. |
Handling 429 with Exponential Backoff
import time, random, requests
def call_with_backoff(url, headers, max_retries=5):
for attempt in range(max_retries):
r = requests.get(url, headers=headers)
if r.status_code != 429:
return r
retry_after = int(r.headers.get("Retry-After", 0))
delay = retry_after or min(60, 2 ** attempt) + random.random()
time.sleep(delay)
r.raise_for_status()Best Practices
- Read X-RateLimit-Remaining and slow down before you hit zero.
- Always honor Retry-After on 429 responses.
- Use batch endpoints for high-volume workloads instead of per-item calls.
- Cache stable results (historical data, model metadata) to reduce request volume.
- Add jitter to backoff to avoid thundering-herd retries.