Skip to main content

Rate limits

The API allows 100 requests per minute per organization, measured as a sliding 60-second window rather than a fixed clock minute. A request made now counts against your budget for the next 60 seconds, so the limit refills continuously instead of resetting on the minute.

The budget is shared across every key in the organization. Two integrations running with separate keys draw from the same 100.

Rate limit headers​

Every response — successful or not — carries your current budget:

HeaderMeaning
X-RateLimit-LimitRequests allowed in the window (100).
X-RateLimit-RemainingRequests still available right now.
X-RateLimit-ResetWhen the window frees up, as a Unix timestamp in seconds.

Read X-RateLimit-Remaining as you go rather than waiting to be rejected — throttling yourself when it gets low is cheaper than handling 429s.

When you exceed it​

Requests over the limit return 429 with code TOO_MANY_REQUESTS, and a Retry-After header giving the number of seconds until the oldest request leaves the window:

HTTP/1.1 429 Too Many Requests
Retry-After: 37
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
{
"code": "TOO_MANY_REQUESTS",
"status": 429,
"message": "Rate limit exceeded. Try again in 37 seconds."
}

Prefer Retry-After over X-RateLimit-Reset when handling a 429. Retry-After is the point at which one request frees up, which is usually much sooner than the full window turning over.

429 is safe to retry — the request was rejected before doing anything, so nothing partially happened. Wait out Retry-After, then retry with exponential backoff and jitter. Retrying immediately, or in lockstep across parallel workers, just burns the refilled budget the moment it appears.

Staying under it​

  • Prefer list endpoints to loops. One GET /products beats a hundred GET /products/{id}.
  • Cache what rarely changes. The catalog does not need refetching per quote.
  • Serialize bulk work. A backfill that runs a few requests per second finishes; one that fires 500 in parallel spends most of its time backing off.
  • Spread scheduled jobs. Nightly syncs that all start exactly on the hour collide with each other.

If your integration has a legitimate need for more throughput — an initial import, or a high-volume sync — get in touch rather than designing around retries.