Anthropic or AsyncAnthropic client in place and instruments the messages surface:
client.messages.create(...), non-streaming andstream=Trueclient.messages.stream(...), the context-manager helper- the async equivalents on
AsyncAnthropic
Install
Wrap and call
Streaming
Both streaming styles are instrumented. Usage is captured from the finalmessage_delta event, which is where Anthropic reports the completed token counts.
Async
WrapAsyncAnthropic the same way. The SDK detects the async client and instruments create and stream with async wrappers.
Python
Per-call override
extra_lago / lago before forwarding, so Anthropic’s strict request validation never sees it.
What gets captured
Reasoning tokens are not exposed. Anthropic folds extended-thinking tokens into
output_tokens. Billing on llm_output_tokens already captures thinking. llm_reasoning_tokens stays at zero and no event is emitted for it.service_tier, inference_geo, server_tool_use) land in CanonicalUsage.extras so provider drift is visible instead of silently dropped.
Pricing
In price mode, native Anthropic clients are priced from OpenRouter’s public model list, per token, refreshed hourly on the background thread.Claude models accessed through Bedrock are priced from AWS’s bulk price list instead, which currently omits the newest Claude models. If you need dollar-cost billing for Claude and you are on Bedrock, see the Bedrock page.
What is and isn’t instrumented
wrap() patches exactly two methods — messages.create and messages.stream — on both the sync Anthropic and async AsyncAnthropic clients.
Everything else on the client passes through unmetered, and each of these is billable:
If you use any of these, build a
CanonicalUsage yourself and pass it to sdk.emit().
Next steps
Configuration reference
Every config knob, in both SDKs.
Charges with filters
Price cache reads and cache writes at different rates.