Claude API Audit Logging for Teams: What to Track
Why audit logging matters for Claude API teams
If more than one person on your team touches a Claude API key, you need a record of who called the API, when, with what key, and what happened — not after an incident, but from day one. Audit logging for Claude API usage means capturing request metadata (caller, timestamp, model, token counts, status) in a durable, queryable log that's separate from your application's business logs. Without it, you can't answer basic security questions: did a leaked key get used after rotation? Which service account is burning through your budget? Who accessed a customer's data through the API last Tuesday?
The direct answer to "how do I set up Claude API audit logging for teams" is: log every API call with actor identity, key identifier, timestamp, model, endpoint, token usage, and outcome; store those logs somewhere immutable and access-controlled; and separate audit logs from debug logs so they survive log rotation and can't be edited by the same people being audited. The rest of this post covers what to capture, where it should live, and how to do it without building a logging pipeline from scratch.
What a Claude API audit log actually needs
A useful audit trail for a team using Claude's API is not the same as application debug logging. It needs to answer "who did what, when, with what result" months later, even if the person who made the call has left the company. At minimum, each entry should include:
- Actor — the human or service account, not just "the API key." A shared key with no actor attribution is the single biggest gap in most teams' Claude API logging.
- Key identifier — which key was used, ideally scoped to a project, environment, or individual rather than one shared secret for the whole org.
- Timestamp — in UTC, with enough precision to reconstruct a sequence of events.
- Model and endpoint —
claude-opus-4,/v1/messages, streaming vs non-streaming, tool calls included. - Token counts — input and output tokens, useful for both cost attribution and detecting anomalous usage patterns.
- Status and latency — success, rate limited, error code, response time.
- Request/response content (optional and sensitive) — logging prompts and completions gives you the most forensic value but raises data retention and privacy questions. Many teams log metadata only, and keep full content logging opt-in per project.
Why "who used which key" is the hard part
Anthropic's own API key system is flat: a key is a key. If three engineers and a CI pipeline share one sk-ant-... key, your audit log can tell you that a call happened, but not who made it, unless you build an attribution layer in your own application code — tagging every outgoing request with a user ID in a header or metadata field, and correlating that with your own database.
This is the point where most teams either build custom middleware or move to a provider-level key system that issues a distinct, named key per person or service. SubToAPI's dashboard does this: every team member or environment gets its own sub_live_... key, scoped under one Claude subscription, so your logs already have the actor identity baked into the key itself rather than requiring custom instrumentation. See /docs/quickstart for how key issuance works per seat.
Where audit logs should live
Three options, in order of how most teams evolve:
- Application logs (fine for small teams, bad for audits). Easy to start, but gets mixed with debug noise and is usually mutable by the same engineers you'd want to audit.
- Centralized log pipeline (CloudWatch, Datadog, a self-hosted ELK stack). Good separation of concerns, but you have to instrument every call site yourself to capture actor, key, and token data consistently.
- Provider-level usage dashboard. If your API gateway already tracks per-key usage with metadata, you get audit data for free without instrumenting every call site.
A practical middle ground: keep your centralized log pipeline for request/response debugging, but rely on a dedicated usage dashboard for the audit-specific fields — actor, key, cost, token volume — since that data is attached to the key automatically rather than something your code has to remember to log every time.
A minimal logging wrapper
If you're logging audit metadata in your own code, keep it close to the request itself so no call path can skip it:
async function callClaude(messages, { actor, keyId }) {
const start = Date.now();
const res = await fetch("https://api.anthropic.com/v1/messages", {
method: "POST",
headers: {
"x-api-key": process.env.CLAUDE_API_KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
},
body: JSON.stringify({ model: "claude-opus-4", max_tokens: 1024, messages }),
});
const data = await res.json();
auditLog.write({
actor,
keyId,
model: "claude-opus-4",
status: res.status,
latencyMs: Date.now() - start,
inputTokens: data.usage?.input_tokens,
outputTokens: data.usage?.output_tokens,
timestamp: new Date().toISOString(),
});
return data;
}
This works, but every engineer has to call callClaude with the right actor — nothing enforces it. If someone calls the raw API directly, the audit trail has a gap.
Per-key visibility removes the enforcement problem
The more robust pattern is to make the audit data structural rather than optional: each person or service gets a separately issued key, and usage against that key is tracked automatically regardless of whether the calling code remembers to log anything.
With SubToAPI, each sub_live_... key maps to a specific team member or environment under your Solo, Team, or Scale plan. Usage metadata — tokens, requests, model, timestamps — is attached to the key automatically and visible in the dashboard, so audit data exists even for calls your logging code forgot to instrument. That doesn't replace an immutable log store for compliance-grade retention, but it closes the "shared key, no attribution" gap that causes most audit failures on small teams. See /docs/messages for the request format and /pricing for how seats map to keys.
Retention and access control
Two policy questions matter as much as the logging mechanism itself:
- Retention period — define how long audit logs are kept before deletion. 90 days is a common baseline; regulated industries often require a year or more.
- Who can read the audit log — if the people being audited can also edit or delete the audit trail, it isn't an audit trail. Write access should be automated (the logging pipeline itself), and read access should be restricted to a small admin group.
Getting started
For a small team, the fastest path to real audit coverage is: issue separate keys per person or service rather than sharing one, capture actor/token/status metadata on every call, and store that data somewhere the calling engineers can't edit. If you don't want to build the key-issuance and usage-tracking layer yourself, /signup gets you a working per-seat key setup in a few minutes, with streaming and tool use supported — see /docs/streaming and /docs/tools for details.
questions
Does Claude's API have built-in audit logging? Anthropic's API itself doesn't expose a per-user audit dashboard — usage is tied to the API key, not the individual caller. Teams need to add actor attribution themselves, either in application code or by issuing distinct keys per person through a gateway.
What's the minimum data I should log for compliance purposes? Actor identity, key identifier, timestamp, model used, token counts, and request status. Logging full prompt/response content is optional and should be a deliberate decision given data retention and privacy implications.
How do I track usage per team member if everyone shares one Claude API key? You either tag every request with a user ID in your own logging layer, or switch to a system that issues separate keys per person so usage is attributed automatically — the latter requires no code changes to get accurate per-user data.