Rate limits
Per-token request limits, the default and the maximum, and what a 429 tells you to do next.
Rate limits are per token, not per team, per user or per IP. Two tokens belonging to the same team have independent budgets, which is the reason to give each integration its own token rather than sharing one.
| requests per minute | |
|---|---|
| default for a new token | 60 |
| maximum configurable | 600 |
The limit is chosen at token creation and can be changed by editing the token. A
value outside 1..600 is refused at creation with VALIDATION_ERROR rather than
silently clamped — a limit you did not get is worth an error, not a surprise.
The window is a rolling 60 seconds, enforced at the API gateway before your request reaches a service. A refused request never runs, so it costs you nothing beyond the round trip.
What a 429 looks like
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json
{
"error": "RATE_LIMIT_EXCEEDED",
"message": "API token rate limit exceeded"
}
Retry-After carries whole seconds until the budget frees up. It is present
whenever the limiter can compute it, and may be absent — an absent header is
not permission to retry immediately. Back off either way.
What to do about it
429 is transient. Retry it. That distinguishes it from every 4xx above it: a 400 or a 403 will fail identically forever, but a 429 succeeds once the window moves.
- Honour
Retry-Afterwhen it is present; use exponential backoff with jitter when it is not. Uniform retries from many workers re-synchronise into the same spike that caused the 429. - Put a ceiling on retries and surface a failure rather than looping forever.
- Prefer fewer, larger pages when walking a collection —
limit=100costs one request wherelimit=10costs ten. See Pagination. - Prefer webhooks over polling. A poll loop spends the budget asking whether something happened; a webhook spends nothing and tells you when it did.
Two refusals that are not rate limits
Both are 4xx and neither clears on its own:
- 403
IP_NOT_ALLOWED— the token carries an IP whitelist and the request did not come from one of the listed addresses. Add the address, or issue a token without a whitelist. - 403
INSUFFICIENT_SCOPE— the token is not scoped for what it asked for. Retrying only spends the rate-limit budget; the token has to be re-issued. See Authentication.