Anthropic
Full coverage of sync, async, streaming, and errors, with prompt-cache token accounting. Includes the one streaming shape that is not recorded.
Fully covered, and verified against the live API on every release.
pip install anthropic capsera
import anthropic
import capsera
capsera.init(api_key=os.environ["CAPSERA_API_KEY"])
client = anthropic.Anthropic()
init() patches Messages and AsyncMessages on the class, so a client constructed
before or after is recorded either way.
Coverage
| Call | Recorded |
|---|---|
client.messages.create(...) | Yes |
await async_client.messages.create(...) | Yes |
with client.messages.stream(...) | Yes |
async with async_client.messages.stream(...) | Yes |
| provider errors on any of the above | Yes |
Streaming
Use the context manager. Token counts only exist once the stream finishes, and the proxy reads them on context exit:
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Explain agent cost attribution."}],
) as stream:
for chunk in stream.text_stream:
print(chunk, end="")
Async uses async with and async for.
Iterating the stream without the context manager is not recorded:
# Not recorded
for event in client.messages.stream(model=..., messages=[...]):
...
This is a known gap, tracked as a failing test in the SDK.
Prompt caching
Anthropic bills cached tokens at three rates, and all three are recorded separately:
input_tokens, cache_write_tokens (typically 1.25x input), and cache_read_tokens
(typically 0.1x input). Cost sums all of them, so a cached workload reports the saving.
client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{
"type": "text",
"text": LONG_PREAMBLE,
"cache_control": {"type": "ephemeral"},
}
],
messages=[{"role": "user", "content": question}],
)
Capsera's cache-hit-rate reporting is computed from these fields. See Prompt analysis.
Errors
A provider error is recorded as a zero-cost event carrying the exception type, such as
RateLimitError, BadRequestError, or APIConnectionError, and is then re-raised
unchanged. Your except clauses behave as they did before instrumentation.
The message is not recorded, because Anthropic errors often quote the prompt.
Claude through Bedrock or Vertex
Claude on AWS Bedrock or Google Vertex uses a different client and is documented separately. See Bedrock and Mistral, Cohere and Vertex AI.
Pricing differs by platform, and the catalog keys them separately.
anthropic.claude-3-5-sonnet-20241022-v2:0 on Bedrock is a different entry from
claude-3-5-sonnet-20241022 direct.
Models
The catalog covers the current Claude line across Opus, Sonnet, and Haiku, and prefix
matching means dated snapshots such as claude-sonnet-4-6-20260101 inherit the price of
claude-sonnet-4-6.