Rate limits

Read the budget off every response rather than guessing.

Requests are limited on a fixed window. Every response tells you where you stand, so a well-behaved client never has to discover the limit by hitting it.

HeaderMeaning
X-RateLimit-LimitRequests permitted per window.
X-RateLimit-RemainingRequests left in the current window.
X-RateLimit-ResetWhen the window resets, as a UTC epoch timestamp in seconds.
Retry-AfterSeconds to wait. Sent only on a 429.

The first three appear on every response, including successful ones. Watch X-RateLimit-Remaining and slow down as it approaches zero rather than waiting to be refused.

How the limit is partitioned

Your budget is scoped to your credential, not to the whole institution:

  • API key — the limit is per key. Two keys for the same institution have independent budgets.
  • Bearer session — the limit is per institution and user combined.

So a runaway job on one key cannot exhaust another integration’s budget.

When you are limited

A breach returns 429 with the JSON error object and rate_limit_exceeded:

1{
2 "error": {
3 "type": "rate_limit_error",
4 "code": "rate_limit_exceeded",
5 "message": "API rate limit exceeded. Slow down and retry after the period indicated by the Retry-After header."
6 }
7}

Wait the number of seconds in Retry-After, then retry. Do not retry immediately, and do not retry on a fixed short interval — that turns one throttled client into a sustained one.

Backing off well

Retry with exponential backoff and jitter, seeded by Retry-After rather than a constant of your own choosing. Two clients that both retry after exactly the interval will collide again on the next window; jitter is what stops a thundering herd rebuilding itself.

429 is safe to retry. It means the request was never processed, so no partial write happened — and combining a retry with an Idempotency-Key means a 429 that was actually delivered still cannot produce a duplicate.

Paging without burning budget

The cheapest way to stay inside the limit while reading a lot of data is a larger page rather than more requests. limit is capped at 100, so reading 1,000 records costs 10 requests at limit=100 and 40 at the default 25. See Pagination.