Rate limits
Requests are limited per API key (per IP address for unauthenticated requests). The default is 120 requests per minute; individual deployments may configure a different value. Read the rate-limit headers on every response and back off when you're throttled.
Rate-limit headers
Every response carries the current bucket state, in two families:
Response headers
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
RateLimit-Limit: 120
RateLimit-Remaining: 118
They describe one budget, not two: the IETF RateLimit-* pair mirrors the X- pair value for value. Read whichever your HTTP client already understands. The legacy X- pair stays for a deprecation window and will not be removed without an announcement in the changelog.
- Name
RateLimit-Limit / X-RateLimit-Limit- Type
- integer
- Description
The maximum number of requests allowed per minute for this key.
- Name
RateLimit-Remaining / X-RateLimit-Remaining- Type
- integer
- Description
Requests remaining in the current window. When it hits
0, further requests are rejected until the window resets.
The reset headers do not mirror
This is the one place the two families disagree, because they disagree about what a reset is. Both are sent only on a 429:
| Header | Value | Example |
|---|---|---|
X-RateLimit-Reset | Unix timestamp of the moment the window resets | 1784729460 |
RateLimit-Reset | Delta seconds until it resets, per the IETF draft | 17 |
Retry-After | Delta seconds — the same number as RateLimit-Reset | 17 |
Do not treat the two Reset headers as interchangeable. 17 and 1784729460 are the same instant expressed two ways, and reading one as the other is the difference between waiting seventeen seconds and waiting until the heat death of your retry budget.
All of these are readable from a browser
X-Request-Id, Retry-After, both RateLimit families and Idempotent-Replayed are listed in Access-Control-Expose-Headers, so a cross-origin client can act on a rate limit and detect an idempotent replay rather than having them silently stripped by CORS.
When you exceed the limit
Over-limit requests return 429 with a Retry-After header (in seconds) and a rate_limit_error:
429 Too Many Requests
{
"error": {
"type": "rate_limit_error",
"code": "rate_limit_exceeded",
"message": "Too many requests. Slow down and retry after the interval in the Retry-After header."
}
}
Guidance
Honor Retry-After — wait the specified number of seconds before retrying.
Hammering a throttled endpoint only extends the backoff.
- Spread bulk work. Prefer one mass import over thousands of individual passport creations — it's dramatically fewer requests and far kinder to the limit.
- Keys aren't a throughput multiplier. Each key has its own bucket, but issuing more keys to sidestep the limit isn't supported. If you consistently need more headroom, contact support.
- Watch
X-RateLimit-Remaining. Slow down proactively as it approaches0rather than waiting for a429.