Skip to main content
Two different things stop a request: rate limits, which are transient and you should retry, and plan quotas, which are not transient and you must not retry. Telling them apart is the whole skill.
For the per-plan numbers behind these quotas, see Plans. For the full list of status codes, see Status codes.

Rate limits

Requests are limited to 50 requests per second per IP. Exceeding it returns 429.
The limit is per IP, not per key. If your backend fans out across instances behind a shared egress IP, they all share one budget of 50 requests per second.

Backing off

Exponential backoff with jitter. A fixed delay from many workers at once just queues up again immediately.
Where the SDK exposes response headers, prefer the server’s retry-after. The JavaScript SDK surfaces it as res.error.headers[“retry-after”]; the others do not expose headers, so use the computed backoff there.

Plan quotas

When you exhaust a quota on your plan, the API returns 426 Plan limit exceeded and data reports exactly how far over you are.
Never retry a 426. Retrying cannot help — the quota only changes when you upgrade, the period rolls over, or you delete something. Putting it in the same retry loop as 429 just burns rate-limit budget.
AI token quota is checked with a projection, not just current usage: the API estimates what your request will cost and rejects it if used + estimated would exceed the limit. A request that would have fit can still fail if it is large. Check Plans for what each plan includes.

Which errors are worth retrying


Handling it in the SDKs

The SDKs return errors as values rather than raising, so you can branch without a try/catch. Set the throw option if you would rather have exceptions.
The Go SDK’s ThrowOnError panics rather than returning an error, and the panic value is a plain string. Prefer checking res.Ok there.

Plans

What each plan includes, limit by limit.

Status codes

Every code and its default message.