← RouterPlex Blog
Spend safety4 min read

OpenRouter Negative Balance and 402 Errors: Causes and Fixes

See why an OpenRouter balance can show below zero, what a 402 insufficient credits error means, how to recover, and how to limit the next incident.

An OpenRouter 402 error means the request cannot proceed because the account does not have sufficient credit. If the dashboard also shows a negative balance, the practical recovery is to stop the workload, inspect recent activity, and add enough credit to bring the balance above zero before retrying.

The important engineering question is not only how to clear the error. It is how a prepaid-looking account crossed zero and how to reduce the blast radius next time.

OpenRouter documents its credit system and credit monitoring in the billing section of its FAQ. Error behavior and provider responses can change, so use the current activity page as the source of truth for your account.

Why a balance can cross zero #

LLM billing is finalized after tokens are generated. At request start, a gateway knows the current balance and an estimate of what the request might cost. It does not yet know the final output length.

Several normal API behaviors can create a small accounting gap:

  • Streaming: the response starts before the final output-token count is known.
  • Concurrency: multiple requests pass the same pre-request balance check at nearly the same time.
  • Retries: an SDK, proxy, or agent may retry a request without making the retry obvious in the UI.
  • Long outputs: a missing or high max_tokens value lets a response cost much more than expected.
  • Agent loops: tools can call the model repeatedly until a task ends, multiplying a small per-call cost.
  • Delayed usage posting: provider usage can arrive after the response completes.

Imagine an account with $0.08 left and four concurrent requests. Each request sees a positive balance at the start. If each eventually costs $0.04, the final combined cost is $0.16 and the resulting balance is -$0.08.

How to recover from a 402 #

  1. Stop the process that is sending requests. Do not let an automatic retry loop keep firing.
  2. Open the activity or usage log and filter to the affected API key and time window.
  3. Check whether requests were concurrent, retried, or unexpectedly long.
  4. Rotate the key if the traffic is not yours.
  5. Add enough credit to restore a positive available balance.
  6. Send one small request manually before restarting the full workload.

For an automated service, treat a 402 as a billing-state error, not a transient network error. Blind exponential retries cannot create credit and may hide the actual failure from an operator.

python
from openai import OpenAI, APIStatusError
 
client = OpenAI(
base_url="https://api.example.com/v1",
api_key="sk-...",
)
 
try:
client.chat.completions.create(
model="your-model",
messages=[{"role": "user", "content": "Summarize this file"}],
max_tokens=500,
)
except APIStatusError as error:
if error.status_code == 402:
# Alert an operator and pause the queue. Do not auto-retry forever.
raise RuntimeError("LLM credit exhausted") from error
raise

Four controls that matter more than a low-balance alert #

An alert is useful, but it fires after spend has already happened. Stronger controls stop or constrain the request path.

1. One key per workload

Do not share the same key across production, local development, CI, and coding agents. Separate keys make attribution and revocation straightforward.

2. A hard key budget

A server-side key budget is better than a dashboard target. Set the maximum amount that a key is allowed to consume. If a local experiment should cost at most $10, its credential should not be able to reach the other $490 in the account.

3. Output and concurrency limits

Set max_tokens, bound the number of parallel requests, and cap agent steps. These limits reduce both expected cost and the uncertainty between request start and final accounting.

4. Fail closed when balance data is unavailable

If your own service cannot retrieve the current gateway balance, do not display a made-up zero or assume the full lifetime top-up remains available. Mark the balance unavailable and pause high-risk jobs until billing state is trustworthy.

The prepaid design alternative #

RouterPlex uses a prepaid account balance and lets every API key carry a hard lifetime spend budget. The intended behavior is to stop requests at the available prepaid limit instead of turning a negative amount into debt that must be repaid.

The safest setup still uses defense in depth: a $10 key budget, explicit output limits, bounded concurrency, and a low-balance alert. No single billing check can replace application-level controls for an autonomous agent.

For the exact setup, read API keys and budgets. You can also create a $5 prepaid account and test the failure behavior with a deliberately small key budget.

Frequently asked questions

What does HTTP 402 mean on OpenRouter?

It generally means the account does not have enough available credit for the request. Check the account balance and activity records before retrying.

Why can an LLM API balance go negative?

Streaming requests, concurrent requests, and delayed final usage accounting can allow several requests to pass a balance check before their final token costs are posted.

How do I prevent a coding agent from draining my balance?

Use a dedicated key with a hard server-side budget, keep concurrency bounded, set output-token limits, and alert on spend before the account-wide balance is exhausted.

Run the smallest paid test.

Add $5, cap the key, and verify the result with your own workload.

Related reading