What you will be able to do
- Decide which content gates to enable, weighing diagnostic value against privacy
- Lock telemetry destinations through managed settings without leaving gaps
- Match each telemetry signal to a suitable backend type
- Choose between OpenTelemetry export, the analytics dashboard, the Claude Code Analytics API and the Usage & Cost API
1.Redacted by default: choosing which content to collect
Out of the box, Claude telemetry records the shape of activity, not its content. For prompts and assistant responses, only lengths are recorded. Raw file contents and code snippets are not included in metrics or events. MCP tool names are redacted to the literal "mcp_tool" for user-configured servers. Each extra kind of content is behind its own opt-in variable, so the strategic question is which gates your diagnosis actually needs.
| Variable | Adds |
|---|---|
| OTEL_LOG_USER_PROMPTS=1 | Prompt text on claude_code.user_prompt events and on the claude_code.interaction span |
| OTEL_LOG_ASSISTANT_RESPONSES=1 | Assistant response text on assistant_response events; requires Claude Code v2.1.193 or later |
| OTEL_LOG_TOOL_DETAILS=1 | Tool input arguments such as file paths, shell commands, and search patterns, plus real agent, skill, plugin, and MCP server names on metrics |
| OTEL_LOG_TOOL_CONTENT=1 | A tool.output span event with file contents, Bash output and tool results; requires tracing |
| OTEL_LOG_RAW_API_BODIES | Full Messages API request and response JSON, including the entire conversation history |
Three details catch people out. First, OTEL_LOG_ASSISTANT_RESPONSES falls back to OTEL_LOG_USER_PROMPTS when unset, so turning on prompts quietly turns on responses as well unless you set the response gate to 0. Second, OTEL_LOG_TOOL_CONTENT writes a span event, so without tracing it collects nothing. Third, raw API bodies imply consent to everything the other gates would reveal. Volume matters too: content attributes are truncated at 60 KB by default, and CLAUDE_CODE_OTEL_CONTENT_MAX_LENGTH can be lowered to cut telemetry volume. Under OAuth, user.email is included in attributes. It goes only to your configured endpoint, never to Anthropic.
Checkpoint 1 of 6· Check yourself
A team wants prompt text in its telemetry but must keep assistant responses out. They set OTEL_LOG_USER_PROMPTS=1 and nothing else. What happens?
When OTEL_LOG_ASSISTANT_RESPONSES is unset, it takes the value of OTEL_LOG_USER_PROMPTS. To keep responses out, set it to 0 explicitly.
“When this variable is unset, OTEL_LOG_USER_PROMPTS is used as a fallback, so set OTEL_LOG_ASSISTANT_RESPONSES=0 if you want prompt content without response content”Source: code.claude.com
2.Centralizing collection with managed settings
Across an organization, telemetry is only useful if every machine sends it to the same place. The variables can live in a settings file's env block, and when an administrator sets them in managed settings, Claude Code actively strips conflicting developer settings. Setting OTEL_EXPORTER_OTLP_ENDPOINT removes every developer-set per-signal endpoint. Setting OTEL_EXPORTER_OTLP_PROTOCOL removes developer per-signal protocols. Setting headers or client certificates removes developer endpoint variables too, so those credentials can't be sent to a collector that the administrator didn't choose.
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://collector.example.com:4317",
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer example-token"
}
}There is one gap. Exporter selectors (OTEL_METRICS_EXPORTER, OTEL_LOGS_EXPORTER and the beta OTEL_TRACES_EXPORTER) follow normal per-key precedence. A developer can still switch a signal off or send it to the console exporter, so if coverage has to be guaranteed, pin the selectors in managed settings as well. Also note that Claude Code has no default OTLP protocol. Every otlp exporter you enable needs a protocol set.
Checkpoint 2 of 6· Check yourself
Managed settings pin OTEL_EXPORTER_OTLP_ENDPOINT and headers, but some machines still send no logs. What's the most likely cause?
Managed endpoints and credentials remove developer endpoint overrides, but exporter selectors follow per-key precedence. They have to be pinned in managed settings too.
“so set the selectors in managed settings too if you need them locked”Source: code.claude.com
Checkpoint 3 of 6· Exam question
An organization is scaling its Claude Code rollout from 15 developers to roughly 300 developers and wants to set organization-level Tokens-Per-Minute and Requests-Per-Minute allocations. A junior admin proposes simply multiplying the 15-user TPM-per-user figure by 300. Why is this the wrong approach, and what should the admin do instead?
Correct answer: A — Per-user TPM/RPM shrinks as org size grows since fewer users are concurrently active at scale, so the admin should multiply by the lower per-user figure for the 300-user tier, not the 15-user figure
- A. Correct. The documented guidance shows per-user TPM and RPM recommendations decreasing as team size grows (e.g. 200k-300k TPM/user at 1-5 users down to 10k-15k TPM/user at 500+ users) because concurrent usage doesn't scale linearly with headcount, so scaling from the 15-user tier's figure would drastically over-provision.
- B. The recommendation table explicitly decreases per-user TPM and RPM as organization size increases; treating it as flat leads to requesting far more capacity than the organization will concurrently use.
- C. Rate limits apply at the organization level, not per individual user, which is precisely why naive per-user multiplication overstates the real requirement and why aggregate, tier-aware planning matters.
- D. The TPM/RPM sizing guidance applies broadly to planning Claude Code capacity for teams regardless of which provider handles the underlying API traffic, so it cannot be dismissed for Console-authenticated organizations.
3.Matching each signal to a backend
Because each signal can have its own endpoint, you don't have to send everything to one tool. The monitoring docs suggest backend types by signal. A full-featured observability platform works for all three, and its advantage is that it can correlate them.
| Signal | Backend type | Good for |
|---|---|---|
| Metrics | Time series databases | Rate calculations, aggregated metrics |
| Metrics | Columnar stores | Complex queries, unique user analysis |
| Events/logs | Log aggregation systems | Full-text search, log analysis |
| Events/logs | Columnar stores | Structured event analysis |
| Traces | Distributed tracing systems | Span visualization, request waterfalls, latency analysis |
Security auditing is one case for splitting signals. Events such as tool_decision (allowed or denied, and by what), permission_mode_changed, mcp_server_connection and auth can go to a SIEM over the logs endpoint alone. OTEL_LOG_TOOL_DETAILS then records which commands ran and which files were touched.
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_LOG_TOOL_DETAILS": "1",
"OTEL_EXPORTER_OTLP_LOGS_PROTOCOL": "http/protobuf",
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT": "https://siem.example.com:4318/v1/logs",
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer your-siem-token"
}
}Checkpoint 4 of 6· Match them up
Match each monitoring need to the backend type the docs suggest
Tap a term, then the definition that fits it.
Traces suit tracing systems, counters suit time series databases, and text-heavy events suit log aggregation.
“Distributed tracing systems: Span visualization, request waterfalls, latency analysis”Source: code.claude.com
Sources1
4.When OpenTelemetry is more than you need
OpenTelemetry gives you per-run detail, but you have to run a collector and a backend. If the question is aggregate (who is using Claude Code, what it costs, whether spend matches the bill), Anthropic's reporting surfaces may be enough. The Claude Code Analytics Admin API sits in between: it offers more detail than the dashboard "without the complexity of the OpenTelemetry integration."
| Approach | Gives you | Granularity / freshness |
|---|---|---|
| OpenTelemetry export | Per-run traces, events and metrics in your own backend | Export intervals in milliseconds, e.g. 60000 for metrics by default |
| Analytics dashboard (platform.claude.com/claude-code) | Usage metrics, spend tracking, team insights | Daily activity and spend charts |
| Claude Code Analytics API (/v1/organizations/usage_report/claude_code) | Per-user sessions, lines of code, commits, PRs, tool accept/reject rates, estimated cost | One day per request; up to 1-hour delay |
| Usage & Cost API (/v1/organizations/usage_report/messages, /v1/organizations/cost_report) | Organization token usage and USD cost for reconciliation and alerting | Usage in 1m, 1h or 1d buckets; cost daily only |
Both Admin APIs authenticate with an Admin API key. Claude Enterprise organizations are the exception: they use an Analytics API key against a different API. Usage-report numbers come from Anthropic's own accounting, which gives precise token counts instead of relying only on counting tokens in responses. That makes them the right source for cost reconciliation, even when OpenTelemetry is already running.
Checkpoint 5 of 6· Check yourself
Finance needs to reconcile internal records against Anthropic billing, broken down by workspace. Which source fits best?
The cost_report endpoint returns USD costs that can be grouped by workspace, and the Usage & Cost API is built for reconciling against Anthropic billing.
“Cost reconciliation: Match internal records with Anthropic billing for finance and accounting teams”Source: platform.claude.com
Checkpoint 6 of 6· Exam question
A company runs Claude Code through Amazon Bedrock and notices that, unlike their Claude Console workspace, no per-developer cost or token metrics appear in any Anthropic-hosted dashboard. Finance still wants per-user spend attribution and enforceable per-user caps. What should the platform team deploy to get this?
Correct answer: A — A self-hosted Claude apps gateway in front of Bedrock, which adds per-user usage attribution, OTLP token metrics, and per-user spend limits that Bedrock itself does not send to Anthropic
- A. Correct. On Bedrock, Vertex, and Foundry, Claude Code does not send metrics from the cloud provider back to Anthropic, so a self-hosted Claude apps gateway is the documented way to get per-user usage attribution, OTLP metrics with token counts, and per-user spend limits for those deployments.
- B. The analytics dashboard's contribution and spend tracking is built around Claude Console and claude.ai organizations; it is not documented to aggregate Bedrock-side spend automatically.
- C. /usage-credits governs monthly usage-credit limits on Pro/Max plans for an individual account, not organization-wide per-user attribution across a Bedrock fleet.
- D. Workspace spend limits apply to the Claude Code workspace used for Console-authenticated traffic; Bedrock-routed traffic does not flow through that workspace, so this control would not see or cap it.
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.OTEL_LOG_TOOL_CONTENT=1 puts tool output into log events.Why is that wrong?
It adds a tool.output span event and requires tracing to be enabled. With metrics and logs alone, it collects nothing.
Covered in Redacted by default: choosing which content to collect
2.Pinning the OTLP endpoint in managed settings guarantees every machine exports every signal.Why is that wrong?
The endpoint pin removes developer endpoint overrides, but exporter selectors follow per-key precedence. A developer can still disable a signal unless the selectors are pinned too.
3.The OTLP exporter defaults to grpc if no protocol is set.Why is that wrong?
Claude Code has no default protocol. You must set OTEL_EXPORTER_OTLP_PROTOCOL or a per-signal protocol for each otlp exporter.
Practise it for real
Turn on Claude Code telemetry locally, including beta traces, and confirm signals reach an OTLP collector
1.export CLAUDE_CODE_ENABLE_TELEMETRY=1
Why: Telemetry collection is off until this is set.
You should see: No output yet; nothing exports without an exporter.
2.export OTEL_METRICS_EXPORTER=otlp and OTEL_LOGS_EXPORTER=otlp
Why: Each signal has its own selector, and you enable only what you need.
You should see: Metrics and log events are selected for OTLP export.
3.export CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1 and OTEL_TRACES_EXPORTER=otlp
Why: Traces are in beta and need both the beta flag and their own exporter selector. Metrics and logs do not need the flag.
You should see: Traces are selected for OTLP export alongside metrics and logs.
4.export OTEL_EXPORTER_OTLP_PROTOCOL=grpc and OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
Why: There is no default protocol, and the endpoint tells the exporter where your collector is. The generic protocol and endpoint apply to all signals.
You should see: The exporter has a complete destination.
5.export OTEL_METRIC_EXPORT_INTERVAL=10000, then run claude and send a short prompt
Why: The default metrics interval is 60000 ms. Shortening it for debugging shows data sooner, but reset it for production.
You should see: Metrics reach the collector roughly every 10 seconds, log events every 5 seconds by default, and trace spans every 5 seconds by default.
6.Look in your collector or backend for data from service.name claude-code, including claude_code.interaction, claude_code.llm_request and claude_code.tool spans
Why: This confirms each of the three signals arrived, not just that the process started.
You should see: Metrics, log events and a claude_code.interaction span tree with child llm_request and tool spans are visible.
Stuck? Get a nudge
If nothing arrives, check the protocol first: Claude Code won't guess one. If only traces are missing, check that the beta flag is set.
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.https://code.claude.com/docs/en/monitoring-usageOfficial docs
“User prompt content is not collected by default. Only prompt length is recorded.”
↩︎ Redacted by default: choosing which content to collect“raise it only if your backend accepts larger values, or lower it to cut telemetry volume”
↩︎ Redacted by default: choosing which content to collect“When authenticated via OAuth, user.email is included in telemetry attributes, sent only to the OTel endpoint you configure, never to Anthropic.”
↩︎ Redacted by default: choosing which content to collect“Requires Claude Code v2.1.193 or later”
↩︎ Redacted by default: choosing which content to collect“when you set OTEL_EXPORTER_OTLP_ENDPOINT, Claude Code removes every developer-set per-signal endpoint.”
↩︎ Centralizing collection with managed settings“Claude Code removes the developer-set per-signal versions of that variable, plus every developer-set endpoint variable, generic or per-signal”
↩︎ Centralizing collection with managed settings“Full-featured observability platforms: Correlation between metrics and events”
↩︎ Matching each signal to a backend“Enable logging of tool content in the tool.output span event (default: disabled).”
↩︎ Exam trap 1“so set the selectors in managed settings too if you need them locked”
↩︎ Exam trap 2“Claude Code has no default protocol, so set this or the signal-specific protocol variable for each otlp exporter you enable”
↩︎ Exam trap 3“When this variable is unset, OTEL_LOG_USER_PROMPTS is used as a fallback, so set OTEL_LOG_ASSISTANT_RESPONSES=0 if you want prompt content without response content”
↩︎ Checkpoint“so set the selectors in managed settings too if you need them locked”
↩︎ Checkpoint“Distributed tracing systems: Span visualization, request waterfalls, latency analysis”
↩︎ Checkpoint - 2.
“Enabling this implies consent to everything the three variables above would reveal”
↩︎ Redacted by default: choosing which content to collect“Required for traces, which are in beta. Metrics and log events do not need this.”
↩︎ Centralizing collection with managed settings - 3.
“This API provides more detail than the basic Analytics dashboard without the complexity of the OpenTelemetry integration.”
↩︎ When OpenTelemetry is more than you need - 4.
“Accurate usage tracking: Get precise token counts and usage patterns instead of relying solely on response token counting”
↩︎ When OpenTelemetry is more than you need“Claude Enterprise organizations use an Analytics API key with a different API instead”
↩︎ When OpenTelemetry is more than you need“Grouping: Group costs by workspace or description for detailed breakdowns.”
↩︎ When OpenTelemetry is more than you need“Time buckets: Daily granularity only (1d)”
↩︎ When OpenTelemetry is more than you need“Cost reconciliation: Match internal records with Anthropic billing for finance and accounting teams”
↩︎ Checkpoint - 5.https://code.claude.com/docs/en/analyticsOfficial docs
“API (Claude Console) | platform.claude.com/claude-code | Usage metrics, spend tracking, team insights”
↩︎ When OpenTelemetry is more than you need“Spend: daily API costs in dollars alongside user count.”
↩︎ When OpenTelemetry is more than you need