Requests are metered per API key. Every response — including errors — carries the current state:
| Header | Meaning |
|---|---|
RateLimit-Limit |
Requests allowed in the window |
RateLimit-Remaining |
Requests left in it |
RateLimit-Reset |
Seconds until the window resets |
Because the headers are on every response, a client never needs to hit the limit
to discover it. Read RateLimit-Remaining as you go and pace against it. That is
strictly better than retrying after a 429, which wastes the request that got
rejected.
If you do exceed it, the response is rate_limit_exceeded with a Retry-After
header. Honour it rather than retrying immediately — retrying into a closed window
just consumes the next one.
The budget is per key, not per connection. Splitting an export across ten
concurrent workers using the same key gives you the same throughput as one worker,
plus contention. Use a larger limit per page instead: one request returning 200
records costs one request, and the maximum page size is 200.
GET /v1/health and GET /v1/version take no credential, so they are metered by
IP. An endpoint without a credential is not an endpoint without a budget.