Our thoughts on Anthropic's OpenTelemetry traces

Javier Rodriguez
Anthropic now exports OpenTelemetry traces for the Claude API. We compare them with signed AI session evidence and describe an OTLP receiver that would turn those traces into attestations.

TL;DR: Anthropic now exports OpenTelemetry traces for the Claude API and Managed Agents. They are great for debugging and cost tracking, but spans can be lost or dropped and know nothing about your code, so they cannot prove what an agent shipped. chainloop trace already produces that proof for Claude Code, opencode and Cursor, as a complete, signed record of each session tied to the commits, releases and other SDLC stages it touched and checked against your policies. Next, we are looking into a receiver that turns Claude API and Managed Agents sessions into signed evidence too. Get started with Chainloop AI Sessions

What Anthropic shipped

The Claude API OpenTelemetry export is in beta. An admin adds a destination in the Console, and from then on every Messages API request and Managed Agents session in the selected workspaces sends spans to any OTLP/HTTP endpoint. A second path through the SDK needs no admin rights and joins client and server spans into one trace.

You get anthropic.messages.create, one anthropic.model_request per model run, anthropic.tool_use and anthropic.mcp_tool_use spans per tool call, and anthropic.session.turn for agent turns. Each span carries the model, token counts, cache usage, and organization and workspace IDs. Full content mode adds prompts, responses, tool arguments and tool results, up to 0.75 MB per span.

The spans follow the OpenTelemetry GenAI semantic conventions, so Datadog, Grafana, Honeycomb and Langfuse read them without a custom integration, and any agent vendor that adopts the same conventions can use the same pipeline. That helps anyone running agents at scale. We build chainloop trace, our open source AI session collector, so we read the spec closely.

How this relates to the Chainloop AI Session Collector

Earlier this month we open sourced the AI Session Collector, which ships as the chainloop trace command in the Chainloop CLI. It builds on the AI agent governance support we added in March, which made agent sessions and agent configuration first-class evidence in Chainloop.

After Anthropic’s announcement, the obvious question is whether the collector is still needed now that the API emits traces. It is.

chainloop trace init installs hooks in Claude Code, opencode and Cursor, plus a git pre-push hook. While the agent works, the hooks snapshot every file before and after each Edit or Write, so Chainloop knows the exact line ranges the agent touched. On git push, the CLI replaces any secrets in the session with placeholders and pushes a signed CHAINLOOP_AI_CODING_SESSION attestation tied to the commits it produced.

Chainloop stores that attestation as evidence next to your SBOMs and build provenance, and Rego policies check it for approved models, allowed MCP servers, destructive shell commands and a token budget. A violation can block the push, and on the platform it fails a Chainloop AI Policies check on the pull request.

For CI jobs and sandboxes, chainloop trace run -- claude -p "..." wraps one agent run and attests it even when it produced no commits. Capture, attribution, redaction, signing and policy evaluation all run in the open source CLI.

Telemetry and evidence answer different questions

Anthropic’s spans and chainloop trace both watch an agent calling a model and its tools, and both report which models and tools ran and how many tokens they used. They differ in what they promise about the record.

Anthropic’s docs say delivery is best effort, so spans can be lost or arrive twice, and a caller can drop its own spans by clearing the sampled flag in the traceparent header. The docs recommend the Usage API for complete records. When you are debugging a slow agent or charting spend per workspace, those are the right trade-offs.

An auditor, a merge gate or a CRA technical file needs a record that is complete, signed and tied to the artifact that shipped. Traces also stop at the API boundary. They cannot say which part of the model’s output is in commit a1b2c3d, or which lines a human rewrote before review.

chainloop trace runs inside the agent through its hooks, so it can act on the session as well as watch it. It attributes every changed line to the agent or a human, and it enforces guardrails on the developer’s machine before anything is pushed. The hooks can also instruct the agent, for example to record the spec or ticket it works from.

Anthropic OTel traceschainloop trace
Built forObservability: debugging, latency, costGovernance: audit, policy, merge gates
SourceClaude API and Managed Agents, server sideAgent hooks on the developer machine or CI runner
Agents coveredAnything calling the Claude API (Claude Code has its own separate OTel export)Claude Code, opencode, Cursor (experimental)
Tied to codeNo repository or commit contextCommits, branch, per-line AI vs human attribution
IntegrityBest effort, can drop or duplicate, caller can opt outSigned attestation, missing sessions fail the PR check
ContentMetadata only or full content, up to 0.75 MB a spanSecret redaction before upload, fails closed
EnforcementNone, it is data for dashboardsRego policies block the push or the merge
Agent interactionPassive, read onlyInjects instructions, captures specs, runs guardrails client side

So we do not see the traces as competition, since Chainloop’s job is to turn signals like these into evidence and decisions.

Designing a Chainloop OTLP receiver

Hooks stay our primary path, but they need a process on a machine you control.

A Managed Agents session runs on Anthropic’s infrastructure, and an internal app calling the Messages API has no .claude/settings.json to hook into. For those workloads Anthropic’s traces are the only record. We are looking into accepting them as a second source of session evidence.

The design is an OTLP/HTTP receiver in the Chainloop control plane, which you add in the Anthropic Console as a Custom destination with a Chainloop API token in the authorization header. Teams that already run an OpenTelemetry Collector add Chainloop as a second exporter, so Datadog or Grafana still receive the same spans.

Diagram with two paths into one signed record of each agent session. Claude API spans, from the Messages API and Managed Agents, go to a proposed Chainloop OTLP receiver and, as the same spans, to Datadog or Grafana. Coding agent hooks from Claude Code, opencode and Cursor go to the chainloop trace CLI. Both paths produce a signed AI coding session attestation, which Rego policies evaluate for the push gate and the pull request check.

Two paths lead to one signed record of each agent session. The OTLP receiver, shown dashed, is a design we are looking into, not a shipped feature.

The receiver deduplicates spans by trace and span ID and groups them by anthropic.session.id, or by gen_ai.conversation.id for Messages API threads. It closes a session after its final turn plus an idle window, then maps the spans onto the CHAINLOOP_AI_CODING_SESSION schema in generic mode, the same mode chainloop trace run uses for sessions without a repository.

Span dataSession evidence field
gen_ai.request.model, gen_ai.response.modelmodel.models_used
gen_ai.usage.* input, output, cache read and write tokensusage, with estimated cost
anthropic.tool_use, anthropic.mcp_tool_use, anthropic.custom_tool_usetools_used.summary
anthropic.mcp.server.nameinput to the MCP-servers-allowed policy
anthropic.tool.evaluated_permissionnew policy input: tools that ran without asking
gen_ai.input.messages, gen_ai.output.messages (full content mode)redacted transcript for the no-secrets policy

Unlike the CLI path, the receiver signs data that Anthropic reported, and the attestation records that source. Because delivery is best effort, each attestation also lists the gaps it can detect, such as a turn with no model request, in its warnings field. Policies can then reject an incomplete session.

On developer machines, Claude Code ignores OTEL_* variables in repository settings, so only managed settings can turn its telemetry on. Its spans carry no per-line attribution either, so hooks stay the better source there. Where a team runs both, the receiver can attach Claude Code’s own trace spans to the hook-based attestation and cross-check token counts between the two.

Try it

With Claude Code, opencode or Cursor, run chainloop trace init in one repository and push a branch, as the AI Sessions quickstart shows.

If you run Managed Agents or call the Claude API from internal services and want those sessions attested, tell us about the workload, because those conversations decide what the OTLP receiver supports first.

Continue Reading

; ---