Rate limits
Per organization, per minute, in two cost classes. The limits exist to stop a runaway loop, not to shape ordinary traffic.
Limits apply per organization, per fixed one-minute window, and are counted in two buckets by request method:
| Bucket | Methods | Limit |
|---|---|---|
| Reads | GET |
600 per minute |
| Writes | POST, PATCH, DELETE |
60 per minute |
Both are far above what an ordinary integration uses. A nightly sync that pages a 5,000-product catalog at 100 per page makes 50 reads; an import of 2,000 products is one write.
Headers
Every response carries the state of the bucket it was counted in:
X-RateLimit-Limit: 600X-RateLimit-Remaining: 597X-RateLimit-Reset: 1756910040X-RateLimit-Reset is Unix seconds.
How the window works
The window is a fixed clock minute, not a sliding one. Every window starts on the minute (:00), the count resets to zero when it ends, and X-RateLimit-Reset is the start of the next window. All keys of the same organization share the window.
Two consequences worth knowing:
- A steady rate at or below the limit never trips it, whatever the burst pattern inside a minute: 60 writes sent in the first second of a window are fine, and so are 60 spread across it.
- A burst that straddles a boundary can exceed the nominal rate briefly: up to 60 writes in the last seconds of one window and 60 more in the first seconds of the next. Do not rely on that headroom; size your loop to the limit.
When you exceed a limit
{ "error": { "type": "rate_limited", "code": "rate_limit_exceeded", "message": "Rate limit of 60 write requests per minute exceeded for this organization. Retry after 23s." }}The response carries Retry-After in seconds; wait that long and retry. A 429 is not a failure of the operation. Nothing was created, no credits were spent and no Idempotency-Key was consumed, so it is always safe to retry with the same request.
Polling
GET /v1/imports/{id} and GET /v1/exports/{id} carry Retry-After: 5 while a job is running. Polling at that interval keeps even a tight loop well inside the read bucket. A webhook removes the need to poll at all.