
This guide covers client-side trace export from Claude Code, which works
on Claude for Teams and Claude for Enterprise. To ingest claude.ai chats and
Cowork sessions, use the Claude Compliance
integration instead. It reads transcripts from Anthropic’s Compliance API and
requires Claude Enterprise. See Which Claude surfaces are
covered.
Prerequisites
- An Openlayer API key and the ID of the inference pipeline that should receive the traces.
- A way to deliver Claude Code managed settings to your developers. Either:
- Server-managed settings, from the claude.ai admin console. Requires Claude for Teams or Claude for Enterprise and the Owner or Primary Owner role.
- Endpoint-managed settings, deployed to each device through MDM, an OS policy, or a
managed-settings.jsonfile.
- Claude Code v2.1.251 or later on developer machines. Earlier versions don’t fully lock the export destination described in What developers can and can’t change.
How Claude Code tracing works
Claude Code tracing is a beta feature and is off by default. Three settings turn it on:
Each prompt a developer sends starts a
claude_code.interaction root span. Model calls and tool
calls are recorded as its children, and each tool call has its own children for time spent
waiting on a permission decision and for execution. When Claude spawns a subagent, the
subagent’s spans nest under the tool call that started it.
1. Write the managed settings
Put the followingenv block in your managed settings, replacing the two placeholders:
OTEL_EXPORTER_OTLP_TRACES_*scopes the endpoint, protocol, and credentials to traces. If your organization already exports Claude Code metrics or logs to another collector, that export keeps working, and your Openlayer API key is never sent to it.- The endpoint is the full traces path, because a traces-specific variable doesn’t have
/v1/tracesappended to it. - The
x-bt-parentheader chooses the inference pipeline that receives the traces. - The three
OTEL_LOG_*values send the prompt, tool inputs, and tool output. Without them, each trace’s input is empty and its tool calls have no arguments or results, so Openlayer has nothing to test. Review Privacy and data handling before you deploy them, and set them to0only if your policies rule out sending content.
2. Deliver the managed settings
Deliver the block through whichever mechanism you already use to manage Claude Code. By default, Claude Code reads its policy from one managed source, the highest-ranked one present on the machine. If you already deliver a policy, add the block to that source.- Admin console
- MDM or OS policy
- managed-settings.json
Server-managed settings reach every Claude Code user who signs in to your organization,
with nothing to install on their devices.
- In claude.ai, open Admin Settings > Claude Code > Managed settings.
- Add the
envblock to the JSON and save.
CLAUDE_CODE_USE_* provider variable, such as
CLAUDE_CODE_USE_BEDROCK, or a custom ANTHROPIC_BASE_URL. Cowork sessions never fetch
them either. Use endpoint-managed settings for those machines.3. Verify the export
- On a developer’s machine, start Claude Code and run
/status. TheSetting sourcesline should listEnterprise managed settingswith the source you used:(remote)for the admin console,(plist)or(HKLM)for MDM, and(file)or(drop-ins)for a managed settings file. - If you used the admin console, run
claude doctorand check theManaged settings (remote)line. It says whether the settings loaded, the fetch failed, or Claude Code skipped it and why. - Send a prompt in Claude Code. Within a few seconds, a trace appears in your Openlayer inference
pipeline, with the
claude_code.interactionspan at its root.
[3P telemetry] First traces export line,
followed by the reason when it fails, such as FAILED (Unauthorized). Lines prefixed
[Anthropic telemetry] describe Anthropic’s own operational telemetry and don’t indicate a problem
with this setup.
What developers can and can’t change
Managed settings sit at the top of Claude Code’s settings precedence, so no user, project, or command-line setting overrides them. With the block above in place:- The destination is locked. Because managed settings set the traces endpoint and
credentials, Claude Code removes any traces endpoint a developer sets in their shell or user
settings at startup, including
BETA_TRACING_ENDPOINT, and logs a warning in the debug log. - Tracing can’t be turned off. The enable flags and
OTEL_TRACES_EXPORTERare managed, so a developer can’t set the exporter tononeorconsole, or disable telemetry. - Repositories can’t change it. Claude Code ignores OpenTelemetry variables in a repository’s
.claude/settings.jsonand.claude/settings.local.json. - Content capture is yours to set. A developer can’t change the
OTEL_LOG_*values for their own sessions, to send less content or more.
Privacy and data handling
Three variables control the content Claude Code sends. The configuration above sets all three to1, which Openlayer needs to test each trace’s input, output, and tool calls:
To keep a kind of content out of Openlayer, set its variable to
0. Openlayer can’t test content
it doesn’t receive, so a trace without a prompt has no input to evaluate.
Claude Code truncates each content attribute at 60 KB by default. These flags don’t add Claude’s
replies, which tests need to evaluate the output. Turn on detailed
tracing to add them. OTEL_LOG_ASSISTANT_RESPONSES
and OTEL_LOG_RAW_API_BODIES don’t help here: they only affect Claude Code’s log events, which
Openlayer doesn’t ingest.
Capture Claude’s replies with detailed tracing
Claude Code’s detailed beta tracing adds the text of Claude’s replies, and the messages and tool results sent in each model request. Openlayer uses them to show the prompt as each trace’s input and Claude’s final reply as its output. Turn it on wherever you can: without a reply, a trace has no output for tests to evaluate. Add these variables to theenv block from step 1, and keep
OTEL_LOG_USER_PROMPTS set to 1 there:
BETA_TRACING_ENDPOINTis a base URL. Claude Code appends/v1/tracesto it and sends traces there instead of toOTEL_EXPORTER_OTLP_TRACES_ENDPOINT. It still sends theOTEL_EXPORTER_OTLP_TRACES_HEADERScredentials.OTEL_LOG_USER_PROMPTSgates the prompt and reply text. Without it, detailed traces still arrive, but each trace’s input and output are empty.- Detailed tracing doesn’t use
otelHeadersHelper. Set the credentials inOTEL_EXPORTER_OTLP_TRACES_HEADERS. - Claude Code also sends logs to
/v1/logsunder the same base URL. Openlayer doesn’t ingest logs, so those requests fail and the debug log shows anOTEL diag errorfor each. Traces are unaffected.

claude -p sessions and the Agent SDK don’t need
the allowlist. For every attribute it adds, see Traces
(beta) in Anthropic’s monitoring
guide.
Add team and repository context
Each trace carries the developer’s session ID, which Openlayer uses to group the traces of one conversation into a session. When the developer is signed in with a Claude account, Openlayer uses their email address as the trace’s user. Sessions that authenticate with an API key or a cloud provider, such as Amazon Bedrock, carry an anonymous per-installation ID instead. Claude Code always sends the email when it’s available, whatever theOTEL_LOG_* values are.
To tag traces with your own context, such as a team or cost center, and with the repository the
developer is working in, add these variables to the env block from step
1:
Despite their names, the
OTEL_METRICS_INCLUDE_* variables add their attributes to trace spans
too.
Openlayer turns each custom key without a dot, such as department, into a column you can filter
and group traces by. Keys with a dot, such as team.id, and Claude Code’s own attributes, such as
vcs.repository.name and app.version, are stored as nested metadata. You see them on each step
of the trace, but you can’t filter by them. So:
- Name custom keys without dots:
team, notteam.id. - Don’t reuse the first segment of a dotted attribute. If you set both
teamandteam.id, the nestedteam.idreplaces yourteamvalue. The same applies to Claude Code’s own prefixes, such asapp,user,vcs, andorganization.
Which Claude surfaces are covered
The OTLP configuration on this page applies wherever Claude Code reads managed settings:
The two integrations differ in plan, direction, and data:
- Claude Code OTLP export (this page) works on Claude for Teams and Claude for Enterprise. Claude Code pushes traces to Openlayer as each developer works.
- Claude Compliance requires Claude for Enterprise. Openlayer pulls transcripts of claude.ai chats, Cowork sessions, and Claude Code sessions from Anthropic’s Compliance API on a schedule.
Rotate the API key with a headers helper
To avoid distributing a long-lived API key, point Claude Code at a script that prints the headers instead. Deploy the script to each machine, then replaceOTEL_EXPORTER_OTLP_TRACES_HEADERS in
your managed settings with the top-level otelHeadersHelper key:
otelHeadersHelper failed in the session and in /status.
The helper doesn’t apply to detailed tracing,
which only sends the credentials in OTEL_EXPORTER_OTLP_TRACES_HEADERS.
Troubleshooting
For every Claude Code telemetry setting, see Anthropic’s monitoring
guide.