OpenRouter 402 insufficient credits: three causes and how to fix each
Your client starts getting HTTP 402 with “insufficient credits,” but the dashboard still shows a balance, or the key limit looks fine. OpenRouter's docs split that one status into three credit checks. Here's how to tell them apart, when to retry, and what to set up so a 402 doesn't take production down silently.
Last reviewed 6 Nov 2026
The short version
- OpenRouter
402is a credit refusal, not a rate limit. Checkerror.metadata.limit_sourcebefore you act. openrouter_credits: balance can't cover the request (or one request's estimate is larger than the whole in-flight budget). Add credits or shrink the request; don't retry in a loop.openrouter_key_limit: this API key's credit limit is used up. Raise it or wait forlimit_reset.openrouter_in_flight_budget: balance can still be positive; running/recent requests filled the temporary hold. Wait forRetry-After, then retry.- Org budgets and guardrails are a different path: they return
403, not402.
1. Which 402 is it?
OpenRouter's errors page describes 402 as “Your account or API key has insufficient credits.” The limits page (read 6 Nov 2026) says credit limits come from three places, and every 402 whose metadata carries limit_source also carries a human-readable remedy_hint. Branch on limit_source, not on the hint text:
limit_source | What it means | Retry? | Fix |
|---|---|---|---|
openrouter_in_flight_budget | Running and recently finished requests fill the in-flight spending budget (reason often in_flight_budget_exhausted) | Yes, after Retry-After | Wait the header seconds; lower concurrency if it repeats. Adding credits raises the budget up to a ceiling |
openrouter_credits | Balance can't cover the request, or this one request's estimated cost is larger than the whole in-flight budget (weight_exceeds_budget) | No | Add credits at settings/credits, or lower max_tokens / prompt size. Stop the client first if the balance is already negative |
openrouter_key_limit | This key's own credit limit is exhausted | No (until reset) | Raise the key limit in API keys, or wait for limit_reset (daily / weekly / monthly / never) |
A negative account balance can return 402 even on free models. Putting the balance above zero restores those. Official OpenAI, Anthropic, Vercel AI and OpenRouter SDKs do not retry a 402 on their own, so for the in-flight case you must catch it, read Retry-After, and retry yourself.
2. The in-flight spending budget (why a positive balance still 402s)
OpenRouter charges a request when it finishes. Many requests running at once 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 (input tokens plus completion tokens allowed by max_tokens, up to a per-request cap when max_tokens is unset) and holds that estimate while the request runs. After completion or failure, the hold is replaced by the actual cost for a short settlement window, 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 estimate does not fit is rejected with 402 before it reaches a provider, even though the balance is still positive. Docs notes (6 Nov 2026):
- It applies to a subset of prepaid accounts (balance below a threshold; newer accounts during rollout). Larger balances raise the budget up to the ceiling; balances at or above the threshold are not subject to it.
- It does not apply to free-model requests, pure BYOK requests with no paid plugins, or enterprise / paid-subscription / invoice-billed accounts.
- Only token prices are estimated; per-request fees, plugin charges and image pricing are not part of the hold.
3. 402 vs 403: don't mix credit and budget errors
Credit limits return 402. Separately, OpenRouter checks org-configured budget limits and returns 403 when one is spent: guardrail budgets, workspace budgets, then the key's own limit once its spend window is spent as a budget. Those responses use limit_source values such as openrouter_guardrail_budget, openrouter_workspace_budget or openrouter_key_limit, with resets_at rather than a short Retry-After. See our OpenRouter API key limits guide for per-key caps, BYOK and workspace budgets.
4. Handle 402 in your app
async function chat(body) {
const res = await fetch("https://openrouter.ai/api/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (res.status !== 402) return res;
const payload = await res.json().catch(() => ({}));
const source = payload?.error?.metadata?.limit_source;
if (source === "openrouter_in_flight_budget") {
const wait = Number(res.headers.get("Retry-After"));
if (Number.isFinite(wait) && wait > 0) {
await new Promise((r) => setTimeout(r, wait * 1000));
return fetch("https://openrouter.ai/api/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
}
}
// openrouter_credits or openrouter_key_limit: alert a human; do not tight-loop
throw new Error(`OpenRouter 402: ${source || "unknown"}`);
}To see trouble coming, call GET https://openrouter.ai/api/v1/key and watch limit_remaining, usage fields and effective_budget before a long job. A 402 without Retry-After is not a wait-and-retry case.
Checklist when production starts returning 402
- Log
error.metadata.limit_source(andreasonif present). Don't page on “insufficient credits” alone. - If
openrouter_in_flight_budget: honourRetry-After, lower concurrency ormax_tokensif it keeps happening. - If
openrouter_credits: stop automatic retries, check the balance (including negative), add credits, then resume. - If
openrouter_key_limit: raise the key's credit limit or wait for its reset; don't share one uncapped key across agents. - Confirm you didn't hit a
403budget instead (guardrail / workspace). - BYOK: remember key credit limits ignore BYOK by default unless “Include BYOK usage in limit” is on (BYOK docs).
- Something outside the app that tells you the same day when spend is far above normal.
Not sure about the rest of your OpenRouter, OpenAI and Anthropic limit settings? The free AI key limit audit checks them in a few minutes (no sign-up, no key needed). For agents that can loop, see Runaway AI agent cost; for setting the key caps themselves, see OpenRouter API key limits.
Where KeyBark fits (and where it doesn't)
KeyBark reads OpenRouter key usage from our servers about every 15 minutes during the beta (via /api/v1/key, or /api/v1/keys/{hash} with a Management key) and emails you when a daily or monthly dollar threshold you set is crossed, or when today's spend jumps above your 7-day average. That covers the “spend is far above normal” item in the checklist. On paid plans an opt-in kill switch (beta) can disable a named key when a threshold is crossed.
Limits, honestly: KeyBark does not see 402 responses from your app, does not read the in-flight budget or auto top-up settings, and does not count BYOK usage. Checks run on a schedule, so an alert can arrive after money has been spent. KeyBark is not a proxy and can't block a request. Set OpenRouter's own credit and budget limits first; KeyBark is a second line of warning on top.
FAQ
What does OpenRouter HTTP 402 mean?
OpenRouter's errors page says 402 means your account or API key has insufficient credits. The limits page splits that into three cases under credit limits: account balance, the key's own credit limit, and the in-flight spending budget. Read error.metadata.limit_source to tell them apart.
Should I retry an OpenRouter 402?
Only when limit_source is openrouter_in_flight_budget and the response has a Retry-After header: wait that many seconds, then retry. For openrouter_credits or openrouter_key_limit, retrying will not help until you add credits, raise the key limit, wait for the key's reset, or shrink the request. Official SDKs do not retry 402 on their own.
Why do I get 402 with a positive OpenRouter balance?
Often the in-flight spending budget. OpenRouter estimates each paid request's token cost up front and holds it while requests run and settle. If running and recent requests fill that budget, you get 402 with limit_source openrouter_in_flight_budget even though the balance is still positive. Wait for Retry-After, or lower concurrency / max_tokens.
Is a 402 the same as a 403 budget error?
No. Credit limits (balance, key credit cap, in-flight budget) return 402. Org-configured budget limits (guardrail budgets, workspace budgets, and the key's own limit once its spend window is spent as a budget) return 403 with a different limit_source. Branch on status and limit_source separately.
Sources (read 6 Nov 2026): OpenRouter API Credit & Rate Limits, Errors and Debugging, Spend controls and BYOK. KeyBark is not affiliated with OpenRouter.
KeyBark watches your OpenAI, Anthropic and OpenRouter spend from the server and flags a crossed threshold or spike by email and on your dashboard. Free for one key.