Rate limiting
Fixed-window counters per API key, enforced per tier. Limits are DB-backed, so they hold across serverless instances.
How it works
Each key has two windows: a minute window and a day window, both anchored at the epoch (a minute window is [floor(t/60)*60, +60s)). Every request increments both counters in a single UPSERT; when a counter exceeds the tier limit the request is rejected with 429.
| Tier | Per minute | Per day |
|---|---|---|
admin | 500 | 50,000 |
internal | 240 | 20,000 |
standard | 60 | 10,000 |
free | 10 | 1,000 |
Rate-limit headers
Every authenticated response — successful or not — carries the current quota:
Response headers
X-RateLimit-Limit-Minute: 60
X-RateLimit-Remaining-Minute: 42
X-RateLimit-Reset-Minute: 1760000000
X-RateLimit-Limit-Day: 10000
X-RateLimit-Remaining-Day: 8123
X-RateLimit-Reset-Day: 1760054400Reset-* values are epoch seconds when the respective window rolls over. On a 429, a Retry-After header gives the seconds until the minute window resets.
Handling 429
- Wait at least
Retry-Afterseconds before retrying. - Back off exponentially on repeated 429s; do not retry in a tight loop.
- Cache responses on your side — data changes weekly at most (see Caching), so there is rarely a reason to re-fetch within an hour.