Rate limits
The public API enforces multiple limits. When you exceed any of them the server returns 429 Too Many Requests with error.code = "rate_limited".
Limits
| Scope | Default limit | Window |
|---|---|---|
| Per API key | 600 requests | 60 seconds |
| Per tenant (sum across keys) | 6000 requests | 60 seconds |
Per IP on /api/v1/* | 1200 requests | 60 seconds |
Per IP on auth endpoints (POST /auth/login, POST /auth/register, etc.) | 5 requests | 900 seconds |
Some endpoints have additional safety limits (for example, bulk import). Where applicable, the operation page calls them out.
Headers on every response
Every successful or rate-limited response includes:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Total allowed requests in the current window |
X-RateLimit-Remaining | Requests remaining in the window |
X-RateLimit-Reset | Epoch seconds when the window resets |
Handling 429 responses
A 429 response includes a Retry-After header (seconds) and the standard error envelope:
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded for this API key.",
"correlation_id": "5b1cba7c-f2c2-4a55-9d3a-1e22b7e04e33"
}
}
Recommended client behaviour
- Read
X-RateLimit-Remainingand slow down before you hit zero. - On
429, wait at leastRetry-Afterseconds before retrying. Do not retry sooner. - Use exponential backoff with full jitter for repeated
429s:delay = random(0, base * 2^attempt)capped at 60 seconds. - If you regularly run into limits, batch operations instead of issuing one request per item, or contact us about a higher-tier limit.