Cloud invoices arrive monthly and aggregate everything. The usage object on each API response arrives instantly and describes one request. If you want dashboards, alerts, per-feature unit economics, or chargeback, the raw material is the same on every platform: log the usage fields from every response into your own cost store.
The fields to capture
Four token counters cover billing:
| Field | What it counts | Billed at |
|---|---|---|
input_tokens | Input after the last cache breakpoint | Base input price |
cache_creation_input_tokens | Tokens written to the prompt cache | 1.25x (5m) or 2x (1h) input price |
cache_read_input_tokens | Tokens served from cache | 0.1x input price |
output_tokens | Everything generated, including thinking | Output price |
Total input processed is the sum of the first three — a common FinOps bug is logging only input_tokens and concluding that caching made traffic disappear. Also worth storing: usage.output_tokens_details.thinking_tokens (the reasoning share of output; always ≤ output_tokens, which remains the authoritative billing total), usage.service_tier (whether the request ran Priority, standard, or batch), and usage.inference_geo where data residency's 1.1x multiplier applies.
A minimal capture wrapper
from anthropic import AnthropicFoundry
client = AnthropicFoundry(api_key=KEY, resource="my-resource")
def log_usage(resp, tags):
u = resp.usage
emit_event({ # to your queue / warehouse
**tags,
"model": resp.model,
"input_tokens": u.input_tokens,
"cache_write": u.cache_creation_input_tokens or 0,
"cache_read": u.cache_read_input_tokens or 0,
"output_tokens": u.output_tokens,
})
The response shape, including usage, is consistent across the Claude API, Claude Platform on AWS, Bedrock's current Messages surface, Vertex AI, and Foundry — so one wrapper serves a multi-platform estate.
Streaming and other edge cases
Streaming: usage arrives incrementally in message_delta events, and the counts are cumulative — log the final values at message_stop, don't sum the deltas.
Server-side compaction: if you use the compaction beta, the top-level token counts do not include compaction iterations; sum everything in usage.iterations for the true billed total.
Batches: results stream back as a .jsonl file — parse each line's usage into the same event schema, and record the batch context so the 50% discount is applied when you convert to dollars.
Failures: refused structured-output requests return HTTP 200 with stop_reason: "refusal" and are billed; log them. Expired batch requests are not billed.
Converting tokens to dollars
Store tokens raw and convert to currency at query time using a versioned price table — prices change (Sonnet 5's introductory $2/$10 rate ends August 31, 2026, moving to $3/$15) and modifiers stack (batch 50%, cache multipliers, 1.1x US-only inference, 10% regional-endpoint premium on Bedrock/Vertex). Baking dollars into events at write time makes historical data wrong every time the price list moves.
Keep the events granular. It is tempting to pre-aggregate to hourly sums to save storage, but per-request events are what let you answer the questions that actually save money later: which feature has the fattest prompts, which sessions blow past your token budget, whether cache reads are actually dominating after a deploy. Token-count events are tiny relative to the value of the queries they enable; aggregate in views, not at ingestion.
What the response can't tell you
Two things need estimating before the call rather than logging after it. For pre-flight budget checks, the free token-counting endpoint (POST /v1/messages/count_tokens) accepts the same inputs as message creation and returns an estimate — with its own generous rate limits, separate from message creation. And when migrating models, re-baseline everything: Opus 4.7-and-later models and Sonnet 5 use a newer tokenizer that produces roughly 30% more tokens for the same text, so week-over-week token comparisons across a model migration are apples to oranges unless you annotate the cutover in your data.
/v1/organizations/usage_report/messages, data typically visible within 5 minutes) and Cost API give the official org-level numbers — your event store should match them. Note these endpoints are not available on Claude Platform on AWS or the other cloud platforms, where the marketplace bill and cloud-native monitoring are the reference instead.Where to go next
Add attribution dimensions with request tagging, then build alerts per cost anomaly alerting. The token bill anatomy article decodes each line item.