The budget
The window is fixed. It starts with the first request the key makes after the previous window ended, and it resets 60 seconds later. Every request that passes authentication counts, whatever its result: a
200, a 400, a 404 or a 429 all use one unit. Requests keep counting while you are over the limit, but they do not make the window longer.
Requests refused with 401 api_keys.invalid or 403 api_keys.scope_missing are rejected before the budget is checked: they do not count and they carry no rate-limit headers.
These are the current values. Read the budget from the response headers instead of hard-coding it, so that your integration follows any change.
Headers on every response
Every response to an authenticated request reports the state of the budget in two header families: the widely usedX-RateLimit-* headers and the IETF draft RateLimit headers.
When you go over: 429
The request that goes over the budget is refused with 429 Too Many Requests, a Retry-After header with the number of seconds to wait, the same rate-limit headers, and a problem document with the code common.too_many_requests.
Retry-After seconds is safe.
How to back off
- Wait for
Retry-Afteron every429. Retrying sooner only adds refused requests to the same window. - Slow down before you hit the wall. When
X-RateLimit-Remaininggets close to0, waitX-RateLimit-Resetseconds before the next burst. - Use large pages. Walk paginated lists with
limit=200(see Pagination). - Cache what rarely changes. Locations, warehouses and categories do not need to be read on every run.
- Poll exports calmly. One poll every few seconds is enough while an export is being built (see Exports).
- Do not run overlapping jobs with the same key. Schedule them one after the other.
- Use one key per integration. Each key has its own budget, so a busy job does not starve another.