Skip to main content
Making additional accounts or API keys will not affect your rate limits, as we govern capacity globally. We do however have different rate limits for different models, so you can share the load that way if you do run into issues.
OpenRouter enforces two kinds of limits:

Checking your limits

To check the rate limit or credits left on an API key, make a GET request to https://openrouter.ai/api/v1/key. If you submit a valid API key, you should get a response of the form:
TypeScript

Credit limits

Credit limits govern how much you can spend. They come from three places:
  1. Account balance, your available credits across the account. If your account has a negative credit balance, you may see errors, including for free models. Adding credits to put your balance above zero allows you to use those models again.
  2. Per-key credit limits, an optional spending cap configured on an individual API key. The limit, limit_reset, and limit_remaining fields in the GET /api/v1/key response above describe this cap and how much of it remains.
  3. In-flight spending budget, a cap on the estimated token cost of the paid requests you have running or recently completed, relative to your balance. See In-flight spending budget below.

In-flight spending budget

OpenRouter charges a request when it finishes, so many requests running at the same time could commit more than your balance covers before any of them settles. To prevent that, OpenRouter estimates each paid request’s token cost up front, at the endpoint’s prices: the input tokens, plus the completion tokens allowed by max_tokens up to a fixed per-request cap (the cap is used when max_tokens is not set). Only token prices are estimated; per-request fees, plugin charges, and image pricing are not part of the estimate, so a request whose cost has no token component is not held. The estimate is held against your account while the request runs. When the request completes or fails, the hold is replaced by the request’s actual cost for a short settlement window, and then released. The total that can be held at once is your in-flight spending budget: a fraction of your current credit balance, up to a fixed ceiling. A request whose estimated cost does not fit alongside your running and recently completed requests is rejected with before it reaches a provider, even though your balance is positive. The error’s metadata says which case you hit:
  • "reason": "in_flight_budget_exhausted" with "limit_source": "openrouter_in_flight_budget": your running and recently completed requests already fill the budget. This is transient and can occur with no request still running, while recent costs are settling. The response includes a Retry-After header; wait for it and retry.
  • "reason": "weight_exceeds_budget" with "limit_source": "openrouter_credits": this single request’s estimated cost is larger than your whole budget, so retrying will not help. Lower max_tokens or the prompt size, or add credits.
Every whose metadata carries limit_source also carries remedy_hint, a one-line human-readable next step for that source. It is meant for people reading logs; branch on limit_source, not on the hint text.
The budget applies to prepaid accounts spending their own credits, and only to a subset of them: accounts whose balance is below a threshold, and, while the mechanism is being rolled out, newer accounts without an established spending history. A larger balance raises the budget up to the ceiling, and a balance at or above the threshold is not subject to it at all. It does not apply to requests to free models, to requests served entirely with your own provider keys (see BYOK) that use no paid plugins, or to enterprise, paid-subscription, or invoice-billed accounts.

Handling 402 errors

To resolve errors:
  • Check error.metadata.limit_source in the response body. openrouter_in_flight_budget means your running and recently completed requests filled your in-flight spending budget, not your balance: wait for the Retry-After header and retry. openrouter_key_limit means the API key’s credit limit is exhausted. openrouter_credits means your balance cannot cover the request, or the single request is too expensive for your in-flight budget.
  • Add credits to bring your account balance above zero, or to raise your in-flight spending budget.
  • Check per-key limits. If limit_remaining on the key is exhausted, raise the key’s credit limit or wait for it to reset (see limit_reset).
  • Reduce the request size (fewer input tokens or a lower max_tokens) so its estimated cost fits your balance and in-flight budget.
  • Monitor proactively. Call GET /api/v1/key as shown above to track limit_remaining and usage before requests start failing.

Rate limits

Rate limits govern how many requests you can make. There are a few rate limits that apply to certain types of requests, regardless of account status:
  1. Free usage limits: If you’re using a free model variant (with an ID ending in :), the following limits apply:
The free_model_daily_requests field in the GET /api/v1/key response above reports the daily counter and ceiling that gate your free-model requests when these limits apply to your account. Accounts and endpoints exempt from free-model limits, and BYOK requests, are not gated by it, so remaining reflects the tier policy rather than an enforced ceiling for them. The per-minute limit is not reported there. The limit tier is selected by all-time credits purchased, independently of is_free_tier. To absorb rounding and top-up fees, the higher daily ceiling is granted starting one credit below the table’s threshold (currently credits); an account that has purchased fewer credits than that reports is_free_tier: false together with the lower daily ceiling.
  1. DDoS protection: Cloudflare’s DDoS protection will block requests that dramatically exceed reasonable usage.

Handling 429 errors

Requests rejected with fail with a standard error response:
A error can come from two places:
  1. OpenRouter, when you hit one of the platform limits above (free-model requests per minute or per day, or DDoS protection).
  2. The upstream provider, when the provider serving your request is rate limiting or at capacity. In this case error.metadata.provider_code carries the provider’s original error code when available, and fallback routing retries other providers for the same model automatically before the error reaches you. You can also specify fallback models to try a different model when all providers for the first are exhausted.
Successful inference responses do not include X-RateLimit-* headers. When OpenRouter itself returns a error for a platform limit, the error response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers describing the limit that was hit. When every attempted provider returned a retry hint, the error response also carries a Retry-After header. To monitor your remaining quota before hitting a limit, call GET /api/v1/key as shown above.
To resolve errors:
  • Retry with exponential backoff. Rate limits are transient; wait and retry rather than immediately re-sending. Honor the Retry-After header when present.
  • On free variants, purchase at least credits to raise your daily limit, or switch to the paid variant of the model, which has no platform-level request cap.
  • For provider-side limits, add fallback models or relax provider routing preferences so more providers are eligible to serve the request.

Mid-stream rate limits

If a rate limit is hit after streaming has started, the error arrives as an SSE event with finish_reason: "error" instead of an HTTP , since the status was already sent:
See Handling Errors During Streaming for details and code examples.