Claude Platform Docs
AdminOpenTelemetry

OpenTelemetry for the Claude API

Trace your Messages API requests, tool uses, and Managed Agents sessions with OpenTelemetry spans from the Claude SDK and the Claude API.

The Claude API and the SDK can trace your Messages API requests, tool uses, and Managed Agents sessions with OpenTelemetry. You can view these traces in the observability platform you already have. Use them to debug failed or slow requests, track token spend and latency, and build evals from real traffic. You can also see each request inside your application's own traces, linked to the user or feature that sent it.

OpenTelemetry is a vendor-neutral standard that most observability platforms support. A trace is the full record of one request through your system. A span is one step in a trace, such as a model request or a tool use. The API and the SDK use attributes from the GenAI semantic conventions, so platforms that support the conventions can recognize the spans without extra setup.

Get started

You can set up SDK tracing, API tracing, or both. Set up both to see a request's SDK and API spans in one trace, as in the example traces. For requests to Claude Platform on AWS, the API spans are in their own traces instead.

Install the SDK and register a tracer provider.

Add a destination in the Claude Console.

Look up spans and their attributes.

What you getSDK tracingAPI tracingBoth together
Messages API requests
Sessions API requests
Token usage
Each model run within a request
Managed Agents turns
Server tools, run by the API
Client tools, run by the tool runner
Tools in a self-hosted sandbox
Other API requests, such as uploading files
SetupCodeConsoleBoth
Required permissionNoneAdminAdmin
CoverageClients using the SDKAny clientAny client
Cloud platform supportAnyClaude Platform
Claude Platform on AWS
Claude Platform
Claude Platform on AWS

For Claude Code, the Agent SDK, or Cowork, see Claude Code monitoring, Agent SDK observability, or Cowork activity monitoring.

Send traces to a partner platform

Send traces to any observability platform that accepts OTLP, including these partners:

Unified observability and evaluation platform for AI.

Active observability platform for agents.

Unified AI control plane for observability and evaluation.

AI-powered observability and security.

Fully managed open observability platform.

Observability platform for the new shape of software.

Open-source agent observability and evaluation platform.

LangSmith agent engineering platform.

Intelligent observability platform.

All-in-one platform for building successful products.

Debug your broken code and misbehaving agents.

Observe, evaluate, and secure agents.

Content modes

Each destination and each SDK client has a content mode, which sets whether spans include model prompts and responses. Set it when you add a destination or configure the SDK.

  • Metadata only (metadata_only in the SDK): The default. Spans include identifiers, timing, status, token counts, and text that you choose, such as the names and descriptions of your agents and tools and the names of your MCP servers.
  • Full content (content in the SDK): Most visibility. Spans include model prompts and responses, and everything in Metadata only.

With Full content, you can also see why a run failed or was slow, read full conversations, and build evals from real traces. In the OpenTelemetry span reference, attributes that hold prompts and responses are tagged Content.

If your organization has a HIPAA, FERPA, or K-12 data-handling restriction with Anthropic, destinations export only metadata regardless of their content mode. SDK spans aren't affected.

With zero data retention, you can still use Full content. For Messages API requests, the API holds the exported content only in memory until it delivers it to the destination. Claude Managed Agents isn't eligible for zero data retention, and its data retention stays the same when you use OpenTelemetry.

Content limits

With Full content, each span holds up to 0.75 MB of content by default. That fits a 200k-token context window of English text and stays below the 1 MB request limit of many observability platforms and proxies. If you choose a partner platform as the Provider, the Console sets a limit that the platform accepts.

When content is over the limit, the SDK or the API shortens it and sets anthropic.content.truncated to true. Request spans drop the system prompt and the earliest messages first, and tool spans drop blocks from the end of the result. Images and documents appear only as their type.

Change the limit in these cases:

  • Your observability platform accepts larger payloads: Raise or remove the limit to keep long prompts and responses whole. A full 1M-token context window needs about 4 MB.
  • Your observability platform or a proxy in front of it rejects large requests: Lower the limit.

In the SDK, set traces.max_content_bytes. In the Console, set Content mode to Full content when you add a destination, then set Maximum content size in MB under Advanced settings.

Example traces and how to read them

A Messages API request

Under the API span for a request that creates a message, the API adds a span for each model request and a tool span for each use of a server tool or an MCP connector tool that the API runs.

In this example, your application calls the tool runner, the SDK helper that runs your tools and sends their results back to Claude. Each request that the tool runner sends has a client span from the SDK and a server span from the API. The spans appear in the following order:

  1. Your application starts the answer_question span and calls the Messages tool runner inside it (shown as the anthropic.messages.tool_runner span).
  2. The tool runner sends the first request (shown as the first anthropic.messages.create client span and the spans under it). In this request, the API runs the web search tool between two model requests.
  3. In the second model request, the model asks to use the custom get_weather tool, so the first request ends.
  4. The tool runner runs get_weather (shown as the anthropic.custom_tool_use get_weather span).
  5. The tool runner sends the second request with the tool result (shown as the second anthropic.messages.create client span and the spans under it).
  6. In the second request, the model gives the final answer.
answer_questionyour codeIt starts the trace.anthropic.messages.tool_runnerSDKIt starts with its parent and runs for most of it.anthropic.messages.createCLIENTSDKIt starts with its parent and runs for about half of it.asks to use a toolanthropic.messages.createSERVERAPIIt starts with its parent and ends with its parent.anthropic.model_requestAPIIt starts with its parent and runs for about a third of it.anthropic.tool_use web_searchAPIIt starts after the span before it and runs for a short part of it.the API runs the toolanthropic.model_requestAPIIt starts after the span before it and ends with its parent.anthropic.custom_tool_use get_weatherSDKIt starts after the span before it and runs for a short part of it.runs your toolanthropic.messages.createCLIENTSDKIt starts after the span before it and ends with its parent.final answeranthropic.messages.createSERVERAPIIt starts with its parent and ends with its parent.anthropic.model_requestAPIIt starts with its parent and ends with its parent.

The SDK in your application emits the anthropic.messages.tool_runner span, the anthropic.custom_tool_use span, and each request's client span. To get these spans, set up SDK tracing.

Each request has its token usage on several of its spans. To count each token once, see Counting tokens.

With Full content, the anthropic.messages.create server span has the prompt and the response. The system prompt is in gen_ai.system_instructions, the request's messages in gen_ai.input.messages, and the response in gen_ai.output.messages.

For each span and its attributes, see the OpenTelemetry span reference.

A Managed Agents session

A session has a span for each Sessions API request and a turn span for each agent turn. A turn that a request starts is a child of that request's span. A turn contains a span for each model request and each tool that the API runs, except in the cases listed in the tool span reference. It also contains a span for each outcome evaluation.

This example follows one chat request, in which your application sends a message to a session and runs a custom tool. The trace has spans from both your application and the API, in the following order:

  1. Your application receives a POST /chat request from a user.
  2. Your application starts the SDK's session tool runner, which lists and streams the session's events (shown as the anthropic.sessions.events.stream and anthropic.sessions.events.list spans).
  3. Your application sends the user's message to the session by calling sessions.events.send.
  4. A turn starts and includes model requests, a bash tool use, and a turn on another thread (shown as the first anthropic.session.turn span and the spans under it).
  5. The model asks to use the custom tool list_issues, so the turn ends with the stop reason requires_action.
  6. The session tool runner runs list_issues (shown as the anthropic.custom_tool_use list_issues span) and sends its result by calling sessions.events.send.
  7. A second turn starts with the tool result (shown as the last anthropic.session.turn span).
POST /chatSERVERyour codeIt starts the trace.anthropic.sessions.events.streamCLIENTSDKIt starts with its parent and ends with its parent.anthropic.sessions.events.streamSERVERAPIIt starts with its parent and ends with its parent.anthropic.sessions.events.listCLIENTSDKIt starts while the span before it runs and runs for a short part of it.anthropic.sessions.events.listSERVERAPIIt starts early in its parent and runs for most of it.anthropic.sessions.events.sendCLIENTSDKIt starts after the span before it and runs for a short part of it.sends a user messageanthropic.sessions.events.sendSERVERAPIIt starts early in its parent and runs for most of it.anthropic.session.turnAPIIt starts late in its parent and runs past the end of its parent.stop reason requires_actionanthropic.model_requestAPIIt starts early in its parent and runs for a short part of it.anthropic.tool_use bashAPIIt starts after the span before it and runs for a short part of it.gen_ai.tool.name = bashanthropic.session.turnAPIIt starts after the span before it and runs for a short part of it.on another threadanthropic.model_requestAPIIt starts early in its parent and runs for most of it.anthropic.model_requestAPIIt starts after the span before it and ends with its parent.anthropic.custom_tool_use list_issuesSDKIt starts after the span before it and runs for a short part of it.runs your toollist_issuesyour codeIt starts early in its parent and runs for most of it.anthropic.sessions.events.sendCLIENTSDKIt starts after the span before it and runs for a short part of it.sends the tool resultanthropic.sessions.events.sendSERVERAPIIt starts early in its parent and runs for most of it.anthropic.session.turnAPIIt starts late in its parent and runs past the end of its parent.anthropic.model_requestAPIIt starts early in its parent and runs for most of it.

The SDK in your application emits the anthropic.custom_tool_use span and each request's client span. To get these spans, set up SDK tracing.

A session's spans can be in several traces, for example when you send a later request from a new root trace. With multiagent on, a session can also have several threads. To find the spans you need, group them by an ID.

  • One thread: Group spans by gen_ai.conversation.id, which holds the session thread ID. Sort them by start time to read the thread as a transcript.
  • A whole session, with all its threads: Group spans by anthropic.session.id, across traces.

With Full content, you can read a session's content from its spans.

  • To read a turn's content, use its turn span. The system prompt is in gen_ai.system_instructions on a thread's first turn span, the input in gen_ai.input.messages (your messages and tool results, system.message events, and messages from other threads), and the output in gen_ai.output.messages (the agent's messages, tool uses, and tool results).
  • To see the arguments and result of a tool use, read its tool span. The arguments are in gen_ai.tool.call.arguments, and the result is in anthropic.tool_result.content.

For each span and its attributes, see the OpenTelemetry span reference.

Counting tokens

To count each token once, sum the spans of only one source for each request. When a Messages API request has both an SDK span and an API span, sum its API spans. Both are named anthropic.messages.create, so tell them apart by kind: the SDK span is CLIENT and its child, the API span, is SERVER.

For each source, sum only the following spans, because some usage attributes repeat on more than one level of the API spans:

  • SDK spans: Sum the anthropic.messages.create spans. If a request has compactions, also add the span's anthropic.usage.compaction.input_tokens and anthropic.usage.compaction.output_tokens, because the gen_ai.usage.* attributes don't include compaction tokens. If a fallback model served a request, its span has the usage of only the model that served the response.
  • API spans for a Messages API request: Sum either the anthropic.messages.create spans or their anthropic.model_request spans, not both. If a request has compactions, also add its anthropic.compaction spans. Don't add the anthropic.usage.compaction.* attributes of the anthropic.messages.create span as well, because they hold the same tokens.
  • API spans for a Managed Agents session: Sum the anthropic.model_request and anthropic.session.outcome_evaluation spans.

Spans can arrive more than once, for example when a delivery is retried. If your observability platform doesn't remove duplicates, count each span once by its trace ID and span ID.

gen_ai.usage.input_tokens already includes the tokens read from and written to the prompt cache, so don't add the cache attributes to it. For all usage attributes, see Token usage.

Was this page helpful?