How to Audit Claude API Usage Logs
Auditing Claude API usage logs means systematically reviewing who called the API, when, with what inputs, and at what cost — so you can catch billing surprises, security issues, and misuse before they become expensive problems. This isn't optional once more than one person or service has a key: without structured logs, you're debugging blind when a bill triples or a customer reports strange output.
This guide covers what to log, how to structure an audit trail, what patterns to look for, and how to turn raw logs into something you can actually act on.
What "auditing" actually means here
An audit isn't just "check the logs exist." It's answering five concrete questions on a recurring basis:
- Who made each call (which API key, which user, which service)?
- What was sent and received (prompt, response, tool calls)?
- When did it happen, and at what rate?
- How much did it cost, in tokens and currency?
- Why did a call fail, retry, or get flagged?
If your current logging can't answer all five, that's the gap to close first.
What to capture in every log entry
At minimum, each API call should produce a structured record with:
{
"timestamp": "2024-05-14T09:12:03Z",
"key_id": "sub_live_a1b2c3",
"user_id": "team_member_42",
"model": "claude-3-5-sonnet",
"endpoint": "/v1/messages",
"input_tokens": 842,
"output_tokens": 310,
"cache_read_tokens": 0,
"latency_ms": 2140,
"status_code": 200,
"stop_reason": "end_turn",
"tool_calls": [],
"request_id": "req_9f8e7d6c"
}
A few fields matter more than people expect:
key_id/user_id— without per-key or per-user attribution, you can't trace a spike back to a source. This is the single most common gap in self-built logging.request_id— lets you correlate a log entry with a raw prompt/response pair if you need to investigate further.stop_reason— distinguishes normal completions from truncated responses, refusals, or tool-use halts. A rising rate of non-end_turnstops is itself a signal worth tracking.cache_read_tokens— if you use prompt caching, separate these from regular input tokens or your cost math will be wrong.
Raw prompt/response bodies are useful for debugging but expensive to store and can contain sensitive data. A common pattern is to log full bodies for a short retention window (7–14 days) and keep only metadata long-term.
Structuring the audit trail
Don't treat logs as an unstructured text dump. Pull them into a queryable store — even a simple table — with these dimensions so you can slice by any axis:
- By key/user — which keys drive the most volume and cost
- By endpoint —
/v1/messagesvs streaming vs tool-use calls - By model — cost and latency differ significantly across models
- By time bucket — hourly/daily rollups to spot trends and spikes
- By status/stop_reason — error rates and abnormal completions
A simple SQL-style query answers most audit questions:
SELECT key_id, DATE(timestamp) AS day,
SUM(input_tokens + output_tokens) AS total_tokens,
COUNT(*) AS requests,
AVG(latency_ms) AS avg_latency
FROM usage_logs
WHERE timestamp > NOW() - INTERVAL '30 days'
GROUP BY key_id, day
ORDER BY total_tokens DESC;
Run this weekly, not just when something breaks. Audits are only useful as a recurring habit, not a one-time forensic exercise.
Patterns worth flagging
When reviewing logs, look specifically for:
- Sudden volume spikes from a single key — could be a bug in a retry loop, a leaked key, or a legitimate traffic increase. Check the delta against the prior week, not just absolute numbers.
- Unusually large prompts relative to historical baseline — often a sign of unbounded context growth (e.g., appending full conversation history without trimming).
- High error or timeout rates concentrated in one time window — points to upstream issues or a misconfigured client, not the model itself.
- Calls outside expected hours for internal tools — a key used at 3 AM by a service that should only run during business hours deserves a look.
- Tool-use calls with repeated identical arguments — can indicate a loop where the model (or your orchestration code) isn't terminating correctly.
None of these require anomaly-detection software. A weekly glance at grouped totals, sorted descending, catches most of this.
Keeping audits manageable at scale
As teams grow, the hard part of auditing shifts from "gather the data" to "don't drown in it." A few practical rules:
- Give every service and every person their own API key so attribution is automatic, not reconstructed after the fact.
- Set retention policies deliberately — full bodies short-term, aggregated metadata long-term.
- Export usage data somewhere queryable (warehouse, even a spreadsheet for small teams) rather than relying on raw provider dashboards you can't filter.
- Review cost and volume together, not separately — a key with high request count but low tokens-per-request is a different problem than one with few requests but huge payloads.
This is one of the reasons teams move off raw provider keys and onto a layer that handles per-key metadata natively. SubToAPI issues separate sub_live_... keys per application or team member, and every request carries usage metadata (tokens, model, latency) in the response, so the audit data is there from day one instead of something you bolt on later. See the docs for the metadata format, or the quickstart to get a key issued.
A minimal audit checklist
Run through this monthly at minimum:
- [ ] Every key attributable to a specific person or service
- [ ] Token and cost totals reviewed per key, not just in aggregate
- [ ] Error/timeout rate checked against the prior period
- [ ] Any new keys or services since the last audit documented
- [ ] Retention policy still matches actual storage usage and compliance needs
If you can't check every box without manual digging, that's the signal to invest in better logging infrastructure before the next billing cycle, not after.
questions
Do I need to log full prompts and responses, or just metadata? Metadata (tokens, latency, status, key ID) is enough for cost and anomaly audits. Keep full bodies only for a short retention window for debugging, since they're larger and may contain sensitive content.
How often should usage logs actually be audited? Weekly for cost/volume review, monthly for a full checklist pass covering key attribution and retention. Waiting until a bill spike forces the review defeats the purpose.
What's the fastest way to attribute usage to the right team or service? Issue a distinct API key per person, team, or service rather than sharing one key. If you're using SubToAPI, this is built in — see /pricing for seat-based plans that make per-user keys practical at team scale.