Find what's burning your API credits
A runaway loop, a forgotten cron, a retry storm: how to find the call that's draining a balance, from the burn rate down to the endpoint.
The usual suspects
| Leak | What it looks like |
|---|---|
| Retry loop on a non-transient error | Thousands of identical calls in minutes. Worst when the provider's out-of-credit error looks retryable: OpenAI returns 429, Perplexity 401. |
| A cron that ran wider than intended | A step in the balance at the same hour every day. A backfill that never got its date filter. |
| Agent loop with a growing context | Input tokens per call climb run over run while output stays flat. Cost per call doubles, then doubles again. |
| Prompt cache misses | Cached tokens drop to zero after a deploy that changed the prompt prefix. Same traffic, higher bill. |
| Crawl depth | Firecrawl charges about a credit per page, so a crawl without a page limit spends in proportion to the site, not your intent. |
| Staging on the production key | Spend with no matching production traffic. Only visible if calls carry an environment tag. |
Narrow it down
- 1Find the provider
Today's burn over the 7-day average. Argus raises
spend_spikewhen a provider is up 50% or more week over week, andcredits_lowwhen the new rate leaves seven days or less. - 2Find the hour
A balance polled hourly gives you a time series even for providers with no usage API. A step at 02:00 every night is a schedule. A ramp that started at 15:40 is a deploy or something you ran.
- 3Find the call
Group per-call records by endpoint, model and status. Look for paid calls that returned errors, the same endpoint called with the same parameters, and input tokens that grow per call.
- 4Find the caller
Endpoints don't tell you which job made the call. Put that in
metadataon each event (string key/values, up to 2 KB):{ "id": "01JABZ6Q4V8R3M", "hostname": "api.firecrawl.dev", "endpoint": "/v2/scrape", "method": "POST", "status": 200, "latency_ms": 2310, "units": { "requests": 1 }, "metadata": { "job": "nightly-enrich", "env": "staging" } } - 5Cap it
One key per service, each with its own limit. OpenRouter keys take a credit limit (visible as
limitandlimit_remainingon/api/v1/key). OpenAI supports spend limits per project. Anthropic supports spend limits per workspace.
Hand it to your agent
With the Argus MCP server connected, the whole hunt is one prompt:
Use Argus. Call get_advisories, then get_request_costs for any provider with spend_spike or credits_low (limit 100). Group the calls by endpoint, model and status, and tell me which one accounts for most of the cost and when it started.
- Per-call records need the SDK or ingest API. Polling alone gives you the provider and the hour, not the call.
- Stop a leak at the source: don't retry 402s, out-of-credit 429s or Perplexity's 401. Every provider's error at zero.
Questions
- How do I find which API key is using my OpenRouter credits?
- GET https://openrouter.ai/api/v1/key with each key returns that key's usage and limit. Give every service its own key with its own limit and the leaking one identifies itself.
- Why did my credits drain overnight?
- The usual causes are a scheduled job that ran more than intended, a retry loop on an error that isn't transient (such as an out-of-credit 429 or 401), or an agent loop resending a growing context. The hourly balance series shows which: a step points at a schedule, a steady ramp at a loop.
Related
Give Claude Code, Cursor or Codex a read-only view of every metered API you build with, so it can check what a run cost, spot a leak, and notice a provider running dry.
The status code and error each provider returns at zero balance. Several look like rate limits or bad keys, so they get retried instead of fixed.
Point your coding agent at Argus and ask which endpoint is spending the most. It reads the same ledger you would.