Skip to content

Rate limits

Limits are enforced per organization (optionally tighter per key), and every response tells you where you stand. This page also lists the OpenAI request fields the gateway accepts but deliberately ignores.

The four limits

LimitWindowWhen exceeded
Requests per minute (rpm)Sliding 60s429 rpm_exceeded with retry-after = seconds left in the window
Tokens per minute (tpm)Sliding 60s, checked against an estimate of prompt + expected output429 tpm_exceeded with retry-after
Concurrent requestsIn-flight at any instant429 rpm_exceeded with a distinct message ("Concurrency limit: ...") and retry-after: 1
Daily budget (USD)Calendar day, resets at 00:00 UTC429 daily_budget_exceeded — retrying is useless until reset

Your organization's numbers are visible in the dashboard; per-key rpm/tpm and daily budget can be set lower than the organization's (see Authentication). A rejected request does not consume quota — a 429 never digs you deeper.

Reading your position from headers

Every response carries the rpm window state of your organization:

on every response
x-ratelimit-limit: 60
x-ratelimit-remaining: 57
x-ratelimit-reset: 1774694460
  • x-ratelimit-limit — your rpm.
  • x-ratelimit-remaining — requests left in the current window.
  • x-ratelimit-reset — epoch seconds of the next minute window's start.
  • retry-after — attached to every 429 and 503: seconds to wait before the next attempt has a chance.

Which 429s are worth retrying

rpm_exceeded and tpm_exceeded mean "wait for the window": retrying after retry-after succeeds, and the OpenAI SDKs do it automatically. daily_budget_exceeded means "waiting within the day is useless": the budget stays spent until 00:00 UTC. Branch on error.code and stop retrying — raise the budget in the dashboard if the cap is the problem, details in Idempotency — SDK auto-retries.

Separate from your limits: 503 no_capacity means service capacity is momentarily exhausted. It carries retry-after: 10 and the failed request is not billed.

Output length caps

  • Omit max_tokens and the gateway applies a default of 4096 output tokens — a spending cap, not a suggestion to the model.
  • Requests above your organization's output cap (default 16384) are rejected with 400 max_tokens_exceeds_cap; the message states the current cap.
  • If both max_tokens and max_completion_tokens are sent, max_completion_tokens wins (newer OpenAI semantics).

Accepted, ignored

These OpenAI request fields are valid schema that SDKs and frameworks attach on their own. The gateway accepts them and deliberately ignores them — they are stripped before the request is forwarded, with no error, because rejecting them would break "change the base URL and it runs":

accepted, ignored
logit_bias · logprobs · top_logprobs · store · service_tier · modalities · audio · prediction · web_search_options · stream_options.* (except include_usage)

Two gateway extension fields are reserved: transforms (accepted, not yet active) and models (fallback list — reserved, no-op for now). Sending them today is safe and does nothing.

Unknown fields are rejected on purpose

Any other top-level field returns 400 unknown_parameter with the field name in param. Silently swallowing a typo like max_token would make the mistake invisible — failing fast is cheaper than a support ticket. Legacy completions-API fields (functions, function_call, prompt, input) get a 400 with a hint for the modern equivalent.