Errors & rate limits
Docs · API

Errors & rate limits

Every error status the gateway returns, what each one means, and the rate limits that apply to your key.

Every error is a standard HTTP status with a JSON body, so your existing retry and backoff logic works unchanged.

Error format#

Errors come back as an error object inside detail. It has a stable code and a human-readable message; type repeats the code. Branch on detail.error.code in code, and use message for logs and for people.

json
{
  "detail": {
    "error": {
      "message": "Invalid API key",
      "type": "invalid_api_key",
      "code": "invalid_api_key"
    }
  }
}

Some errors add fields to the same object. A spend-limit error, for example, also says which limit was hit.

Status codes#

StatusMeaningWhat to do
400Bad request: malformed body, an unsupported parameter, or an invalid provider value.Check the request against the upstream API schema. Unknown parameters are rejected, not silently forwarded.
401Invalid or missing API key. This also covers a disabled or expired key, and a key whose owner has left the organization.Check the auth header. In Console → API keys, look for a Disabled, Expired, or Owner removed status. Rotate the key if it leaked.
402A spend limit was reached (period_quota_exceeded), or the wallet is out of funds (insufficient_quota).Raise the budget in Console → Budgets, or add credits in Console → Credits. A spend-limit error includes the period, limit, used, resets_at, and target_type.
429Rate limit reached (rate_limit_exceeded).Back off and retry. See below.
502Upstream network error reaching the model provider.Transient. Retry with backoff.
503No provider could serve the request. Either all routing retries were used up, or no upstream meets your data policy (no_provider_matches_data_policy).Retry, choose another model, or relax the data policy.
504The upstream model timed out.Lower max_tokens or pick a faster model.

Why a 401 says so little#

The response is the same for a disabled key, an expired key, a removed owner, and a key that never existed. This is deliberate: if it differed, anyone holding an old key could probe whether a person is still in an organization. To find out why a key fails, check the key list in the console.

Spend-limit errors#

A 402 with period_quota_exceeded means a daily, weekly, or monthly budget was hit. Budgets reset on a fixed UTC schedule.

json
{
  "detail": {
    "error": {
      "message": "Daily spend limit reached",
      "type": "period_quota_exceeded",
      "code": "period_quota_exceeded",
      "period": "daily",
      "limit": 50000000,
      "used": 50000000,
      "resets_at": "2026-10-14T00:00:00.000Z",
      "target_type": "workspace"
    }
  }
}
FieldMeaning
perioddaily, weekly, or monthly.
limit, usedThe limit and the spend so far, in quota units: 500,000 units = $1. The example above is a $100 daily limit.
resets_atWhen the limit starts over, in UTC.
target_typeWhose budget was hit: workspace or member. Use it to tell the caller who can raise the limit. Handle the case where it is absent.

An out-of-funds wallet is a 402 with insufficient_quota. Add credits to clear it. See Credits.

Rate limits#

Each account can send up to 600 requests per minute, counted across all of its API keys. Image generation is limited to 60 per minute. Requests over the limit get a 429 with rate_limit_exceeded. Wait and retry.