Skip to content

Rate limits

One limit per key, its defaults, and the honest caveat about how it is enforced.

4 min read

Your limit

One limit applies to you: requests per minute, per API key, over a sliding 60-second window. A key with its own rate_limit_rpm uses that. Otherwise it falls back to a default set by the account’s trust level, which rises as an account establishes itself.

Trust is measured in settled dollars and elapsed days, not in how many times someone pressed a button. It used to count payments, which meant three top-ups at the $5 minimum bought the top tier — a price a card tester is delighted to pay.

Trust levelDescription
0200 requests per minute. No settled payment yet, so the balance is empty by definition and this tier is BYOK traffic and zero-cost routes. Still the tightest by a wide margin: it is the only tier reachable on the day of signup, and a stolen card that can only push 200 a minute is a far smaller loss than one that can drain a provider account before the chargeback lands.
15,000 requests per minute. At least one card payment that settled and was not later refunded or disputed.
2 or above50,000 requests per minute. $250 or more of settled credit accumulated over at least fourteen days, measured from the first settled payment — both conditions, because $250 in one go on a fresh account is exactly what a stolen card looks like and $250 over a fortnight is exactly what it does not. A chargeback drops the account back to 0 immediately.
These are blast-radius controls, not quotas
They went up roughly tenfold, deliberately. The old tier-1 default of 600 rpm is ten requests a second, which an ordinary production service with a worker pool reaches on a quiet afternoon — so the first thing a paying customer met after handing us a card was a 429 on traffic they were funding. Tier 2 is now set above what a single instance can serve at all, which is the point: a real business should never see this limit. What bounds your spend is the balance, the per-key spend cap and the monthly ceiling, all three denominated in money rather than requests.

GET /key reports the limit that actually applies to the calling key, so you never have to work it out from this table.

Batch management calls share the same bucket as live traffic, deliberately — a polling loop that did not count against the limit would be the cheapest way to ignore it.

What a 429 looks like

StatusCodeRetryMeaning
429rate_limitedYesThe message states the limit and the wait. Retry-After is authoritative.

A throttled request is refused before anything reaches a provider, so it costs nothing — and before the idempotency claim, so it does not take ownership of a key it will never fill in.

X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset ride on successful responses too, not just the 429. That is the point of them: an adaptive-concurrency controller has to be able to see the headroom shrinking while it still has some, otherwise it drives blind into a refusal. Reset is seconds until the window empties, relative rather than a timestamp, so it needs no clock agreement between you and us.

A 429 you get from upstream saturation carries the same rate_limited code but says so in the message — that every route for the model is currently rate limited, that it is not your key’s limit and not your balance. The provider’s own words are not quoted back at you: they are a statement about our account with them, and one of them politely suggests you check a billing plan that is not yours.

Provider limits are different

A 429 from a provider is not your limit and is not handled the same way. It is a transient upstream condition: we retry the same provider with backoff, honour its Retry-After if it sent one, and move to the next provider if it does not clear. You only see it if the whole chain is rate-limited at once. See failover and retries.

How it is enforced

The limiter is per process
It is an in-memory sliding window, which is exactly right for a single-instance deployment and costs nothing. On a horizontally scaled deployment each instance counts independently, so the effective limit is the configured one multiplied by the number of instances. That is a real limitation and it is stated here rather than discovered in production.

Treat the limit as a blast-radius control rather than a precise quota: it stops a leaked key from doing unbounded damage, and it is not the thing standing between you and a provider’s own throttling.

Something here disagrees with what the API actually did? That is a bug in this page, and worth reporting.

Report it