How to Monitor Claude API Usage Costs
If you're calling the Claude API in production, "monitoring usage costs" means answering three questions on demand: how much am I spending right now, who or what is driving that spend, and will I get blindsided by a spike before the invoice arrives. The short answer is that you need per-request cost data (not just a monthly total), broken down by key or feature, with alerts that fire before you're over budget — not after.
This guide walks through what to track, how to get the numbers out of Claude's API responses, and the tooling options that turn raw token counts into something you can actually act on.
What "usage" actually means for Claude API costs
Claude bills by tokens, split into input and output, and rates differ by model. A single response from the API includes a usage object with the exact token counts for that call:
{
"usage": {
"input_tokens": 512,
"output_tokens": 187
}
}
To turn that into cost you need to multiply by the per-model rate and keep a running total. That's straightforward for a single script, but it breaks down fast once you have:
- Multiple services or environments calling the API
- Several team members with their own scripts or notebooks
- Different models in use (Haiku for cheap tasks, Opus for heavy reasoning)
- Streaming responses, where token counts arrive at the end of the stream, not the start
None of this is hard individually — it's the aggregation and visibility that's the actual problem.
Track usage at the source: log every response's usage field
The most reliable approach is boringly simple: log the usage object from every API response into a table you control, tagged with metadata (which service, which user, which feature) at write time.
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: prompt }],
});
await logUsage({
model: response.model,
input_tokens: response.usage.input_tokens,
output_tokens: response.usage.output_tokens,
feature: "support-bot",
user_id: currentUser.id,
timestamp: new Date().toISOString(),
});
This gives you a queryable ledger instead of a single opaque number on a billing page. You can group by feature to see which part of your product is expensive, group by user to spot abuse or runaway loops, and group by day to catch trends before they become a problem.
The catch: you have to build and maintain the logging table, the cost calculation (rates change and vary by model), the dashboard, and the alerting. That's fine for a side project, but it's a real maintenance burden once several people are shipping features against the API independently.
Separate API keys by purpose, not just by team
Cost monitoring is only useful if you can tell spend apart. If every service shares one API key, your usage log is a single undifferentiated blob and you're stuck reverse-engineering which feature caused a spike from timestamps and guesswork.
Issue separate keys per service, environment, and ideally per major feature:
stagingvsproductionsupport-botvsinternal-toolsvscustomer-facing-search- One key per external partner if you expose Claude-backed functionality to other companies
Then your cost report is just: group usage by key. This single change removes most of the pain in figuring out "why did the bill jump this month."
Set alerts before you hit a limit, not after
A monthly total is a postmortem, not a monitoring system. You want a threshold-based alert: "notify me when spend crosses €X this week" or "notify me if any single key's daily usage is 3x its 7-day average." The second kind catches bugs — an infinite retry loop, a prompt that accidentally includes an entire document on every call, a scraper that got stuck — much faster than a monthly total ever will.
If you're rolling your own, this means running a scheduled job (cron, or a serverless function) that sums recent usage per key and compares it against a stored threshold, then posts to Slack or email when it's exceeded. It's not complicated, but it's another piece of infrastructure to keep alive.
Using a gateway instead of building this yourself
If maintaining a usage-logging pipeline, per-key breakdowns, and alerting isn't something you want to own, a gateway in front of the Claude API can give you this out of the box. SubToAPI sits between your application and Claude, issuing separate sub_live_... application keys per service or team member, and every request through those keys is recorded with token counts and usage metadata automatically — visible in one dashboard instead of scattered across logs.
Practically, that means:
- Each service or teammate gets its own key, so cost breakdown by feature or person is automatic, not something you build.
- Usage metadata (tokens in, tokens out, per request) is already captured — you don't need to instrument every call yourself.
- Streaming and tool-use requests are tracked the same way as standard messages, so you're not missing usage data for the request types that are easiest to under-count.
Setup takes the shape of a normal Claude integration — send requests to https://api.subtoapi.app/v1/messages with your sub_live_... key in the Authorization header — but the usage and cost visibility comes free with the account. See the quickstart for the full request format, or the messages docs if you're integrating an existing codebase. Plans start at Solo €9/month, with Team (€19/seat) and Scale (€49/seat) tiers if you need multiple keys and seats managed centrally — full details on pricing.
A minimal checklist
Whether you build this yourself or use a gateway, the essentials are the same:
- Log
usage.input_tokensandusage.output_tokenson every call, not just the final response. - Tag every request with a key, service, or user identifier so spend can be broken down, not just totaled.
- Convert tokens to cost using current per-model rates, and recompute when rates change.
- Alert on anomalies (spikes vs. baseline), not just on absolute thresholds.
- Review weekly, not just at the end of the billing cycle — catching a runaway loop on day 3 instead of day 30 is the entire point of monitoring in the first place.
Frequently asked questions
Does the Claude API return cost directly, or only token counts? Only token counts, in the usage object on each response. You need to multiply by the current per-model rate yourself to get a dollar or euro figure, and update that rate if pricing changes.
How do I track streaming usage, since tokens arrive incrementally? The token totals for a streamed response are delivered in the final event of the stream, not per-chunk, so you log usage once the stream completes — the same way you'd log a non-streaming call. See streaming for the event format.
What's the fastest way to see costs broken down by feature without building a dashboard? Use separate API keys per feature or service and check per-key usage in a provider dashboard. A gateway like SubToAPI does this automatically for every key issued from your account — no custom logging pipeline required.