DEV Community

Cover image for What Claude Code's telemetry sends, and how to see it for yourself
Bargan Constantin
Bargan Constantin

Posted on Originally published at ccdeck.dev AI-assisted

What Claude Code's telemetry sends, and how to see it for yourself

This article was prepared with AI assistance, using ccdeck’s source code and documentation to check the technical details.

I build ccdeck, whose Telemetry Radar is one of the ways to check, near the end; the short version of this post, with every source, is at ccdeck.dev/claude-code-telemetry. Every quote is from Anthropic's Data usage, Monitoring, Environment variables and Settings pages as I read them on 14 October 2026, and ccdeck as of 3.48.0. The docs change often.

Two things called telemetry

"Does Claude Code send my prompts somewhere?" has two answers, because Claude Code's docs use the word telemetry for two things that work in opposite directions:

  • Operational telemetry (usage metrics and error reports) goes to Anthropic and third parties. On the Claude API it is on until you turn it off, error reports only on Pro and Max sign-ins, and the metrics carry no code, prompts or file paths.
  • The OpenTelemetry export goes to a collector you choose. It is off until you turn it on, and can carry your prompts and tool input if you add the flags for them.

What Claude Code sends on its own

In the docs' words: "Claude Code sends two kinds of operational telemetry: usage metrics and error reports."

  • Metrics: "latency, reliability, and usage patterns, sent to Anthropic and to third-party logging infrastructure over TLS. Metrics never include your code, prompts, or file paths." On the Claude API they are on by default.
  • Error reports: "error messages and stack traces from Claude Code's own internals, sent to a third-party error tracking service over TLS." Claude Code redacts "known patterns of secrets, file paths, email addresses, and other personal information before anything leaves your machine."

Error reports are on only when all four hold: you sign in with Pro or Max, you run Claude Code v2.1.198 or later, you connect directly to the Claude API, and your organization has no zero data retention or HIPAA agreement. On Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry and Claude Platform on AWS, both start off.

To turn them off, set two variables in your shell or in the env block of ~/.claude/settings.json:

{
  "env": {
    "DISABLE_TELEMETRY": "1",
    "DISABLE_ERROR_REPORTING": "1"
  }
}
Enter fullscreen mode Exit fullscreen mode

Or set CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1, which turns both off at once, with auto-updates, release notes and /feedback. One cost: it and DISABLE_TELEMETRY also stop feature-flag fetching, "which can make Remote Control unavailable"; DISABLE_ERROR_REPORTING does not.

The trap: "0" still opts out

Most on/off variables in Claude Code read 0 as off. A few do not, and three of them are the switches above:

Some variables read only whether you set them at all, so any non-empty value including 0 turns the behavior on, and you turn the behavior off by unsetting the variable or setting it to an empty value.

The list under that sentence starts with CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, DISABLE_TELEMETRY and DISABLE_ERROR_REPORTING. Each of them turns something off, so "DISABLE_TELEMETRY": "0" still opts you out. To turn metrics back on, delete the key or leave it empty.

What else leaves the machine

  • The model request itself "includes all user prompts and model outputs, encrypted in transit via TLS 1.2+." No switch above changes that.
  • /feedback, /bug and /share send Anthropic "a copy of your conversation history including code" when you run them. DISABLE_FEEDBACK_COMMAND=1 turns them off.
  • The "How is Claude doing this session?" survey "records only your rating". A follow-up can offer to upload the session transcript, and "Nothing is uploaded unless you explicitly select Yes". CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY=1 turns the surveys off, and so do DISABLE_TELEMETRY, DO_NOT_TRACK and CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC.
  • Before WebFetch reads a page, it sends the hostname alone to api.anthropic.com for a safety check. CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC does not stop it; "skipWebFetchPreflight": true in your settings does.

OpenTelemetry: off until you turn it on

Claude Code can also export metrics, events and (in beta) traces through OpenTelemetry, for your own monitoring. This export "is opt-in and requires explicit configuration", starting with CLAUDE_CODE_ENABLE_TELEMETRY=1, and its data is "sent only to the OTel endpoint you configure, never to Anthropic."

"Claude Code has no default protocol", so set one for each otlp exporter. By default an event records how long a prompt or a response was, not its text: "User prompt content is not collected by default. Only prompt length is recorded." Each kind of content has its own flag, and each is off by default:

Flag What it adds to the export
OTEL_LOG_USER_PROMPTS your prompts
OTEL_LOG_ASSISTANT_RESPONSES Claude's responses; when unset, it follows OTEL_LOG_USER_PROMPTS
OTEL_LOG_TOOL_DETAILS tool input: Bash commands, file paths, URLs, MCP server and tool names
OTEL_LOG_TOOL_CONTENT what tools return, in trace spans (needs tracing)
OTEL_LOG_RAW_API_BODIES the full API requests and responses: "Bodies include the entire conversation history"

Signed in with OAuth, the exports also carry your e-mail address as user.email. And since v2.1.282, Claude Code ignores these variables in a repository's .claude/settings.json, "so a repository can't use them to turn telemetry on, choose where it goes, or capture content." A repository can still switch a signal off.


Check what your machine is set to send

The flags can sit in more than one place, and a line added months ago stays there, out of sight. Three places to look:

  1. Your shell. Anything exported in your profile.
  2. ~/.claude/settings.json, under env. A value there "overwrites the same variable exported in your shell", so this file wins over step 1 (the Claude Desktop app's launch environment is the exception).
  3. Managed settings, if your organization deploys them. You cannot override those.
env | grep -E '^(CLAUDE_CODE_ENABLE_TELEMETRY|OTEL_|DISABLE_TELEMETRY|DISABLE_ERROR_REPORTING|CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC)='

jq '.env // {} | with_entries(select(.key | test("^(CLAUDE_CODE_ENABLE_TELEMETRY|OTEL_|DISABLE_TELEMETRY|DISABLE_ERROR_REPORTING|CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC)")))' \
  ~/.claude/settings.json
Enter fullscreen mode Exit fullscreen mode

If CLAUDE_CODE_ENABLE_TELEMETRY shows up in either, look next for OTEL_EXPORTER_OTLP_ENDPOINT (where it goes) and any OTEL_LOG_* flag (what content it carries).

Watch an export arrive

Reading flags tells you what Claude Code is set to send. To see what an export actually contains, point it at a collector on your own machine that prints everything it receives. The OpenTelemetry Collector's debug exporter does that; this configuration, assembled from the Collector's configuration docs, passes otelcol validate on version 0.162.0:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 127.0.0.1:4317
exporters:
  debug:
    verbosity: detailed
service:
  pipelines:
    logs:
      receivers: [otlp]
      exporters: [debug]
    metrics:
      receivers: [otlp]
      exporters: [debug]
Enter fullscreen mode Exit fullscreen mode

Run it with the release binary (otelcol --config=config.yaml) or the Docker image, which reads its configuration from /etc/otelcol/config.yaml (inside a container, listen on 0.0.0.0:4317 and publish the port to 127.0.0.1). If something already holds port 4317 (ccdeck's own default port is 4317, for one), use another port in both places. Then start one session pointed at it:

CLAUDE_CODE_ENABLE_TELEMETRY=1 \
OTEL_METRICS_EXPORTER=otlp OTEL_LOGS_EXPORTER=otlp \
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4317 \
OTEL_LOGS_EXPORT_INTERVAL=1000 \
claude
Enter fullscreen mode Exit fullscreen mode

Submit a prompt. The docs say to look for the claude_code.user_prompt event, and without OTEL_LOG_USER_PROMPTS it carries prompt_length, not the text. Two caveats: an env block in your settings that sets these variables wins over the ones on this command line, and if nothing arrives, claude --debug-file <path> logs exporter failures as [3P telemetry] errors (lines marked [Anthropic telemetry] are the operational telemetry above, not your export).


Doing the same from a dashboard: Telemetry Radar

The two checks above are what ccdeck's Telemetry Radar (marked Beta) does in one panel. Its Configuration view lists each telemetry flag and where it was set (your user settings, the cached organization settings or the managed settings file, and on Linux the environment a running session was launched with), with the destinations; credentials and endpoint paths stay hidden. Those cached organization settings are how a Team or Enterprise organization turns the export on for its members, and ccdeck's accounts panel marks each account of such an organization with a small shield that says, on hover or focus, what it sends and where.

Telemetry Radar's Configuration view: the destination http://192.0.2.16:4317 from User settings, then Telemetry and Your prompts enabled with their switches on, and a flag no settings file names marked Not set, its switch off
Demo data. Telemetry and prompts on in your own settings; a flag no file sets says Not set. 192.0.2.16 is an address reserved for examples.

Its Monitor view does the second check without a collector of yours, and without a Start button: whenever ccdeck runs, it finds Claude Code's collector by itself, captures in the background (tcpdump on macOS and Linux, Wireshark's dumpcap on Windows) and decodes the exports it sees on their way to your collector. AGENTS_DECK_NO_RADAR=1 keeps a deck started with it from looking or capturing. Its limits are the honest part:

  • Settings files, and on Linux running sessions. Elsewhere a variable exported only in your shell does not show, and on Linux it shows only while a session started with it runs, so "No destination found" does not mean telemetry is off.
  • Its switches write to your user settings. Every telemetry and content flag has one, a flag no file sets shows Not set with its switch off, and each switch writes "1" or "0" under env in ~/.claude/settings.json, for new sessions; a flag from organization or managed settings shows Managed, and one from a launch environment is read-only. It neither shows nor switches DISABLE_TELEMETRY or DISABLE_ERROR_REPORTING.
  • Only plaintext OTLP over gRPC, on IPv4. An HTTPS export shows as a connection it cannot read; http/protobuf and http/json are not decoded. It cannot see Anthropic's own metrics and error reports, or model requests, which travel over TLS.
  • Not which program sent it. It filters by address, so another app sending to the same collector shows too, and an empty list does not mean nothing was sent.
  • Capture needs an administrator once. Allow capture… asks for your password through the system's own prompt and changes the system: on macOS, a LaunchDaemon of ccdeck's own (dev.ccdeck.chmodbpf) that does what Wireshark's ChmodBPF does, with you in the access_bpf group; on Linux, tcpdump, installed if missing and allowed to capture (setcap) for your own group only. Over SSH it shows a sudo command instead; on Windows you install Wireshark with Npcap yourself. What it decodes stays in memory, for 24 hours at most, and is never written to a file or sent anywhere.
  • Both outlast ccdeck. Switching a flag off writes "0" rather than removing the key, npx ccdeck --uninstall takes only ccdeck's hooks out of ~/.claude/settings.json, and the capture setup stays until an administrator undoes it. For the OpenTelemetry flags "0" does mean off; the "0 still opts out" rule is about the three DISABLE variables, which Radar does not touch.

And since this post is about what tools send: ccdeck sends usage reports of its own, on by default. They carry its version, your system, your IP address and (on all but the error reports) a device fingerprint, rough counts such as how many sessions ran in a day, and the errors it hits; your prompts, files and project names are not in them. AGENTS_DECK_NO_REPORTS=1 from the first start sends none. Since 3.42.0 the feedback you send from its Feedback button carries the same fingerprint, unless that variable is set.


The short version

  • Operational telemetry goes to Anthropic and third parties, on by default on the Claude API; DISABLE_TELEMETRY and DISABLE_ERROR_REPORTING turn it off, and "0" counts as set.
  • The OpenTelemetry export goes only where you point it, off until CLAUDE_CODE_ENABLE_TELEMETRY=1, and carries content only with an OTEL_LOG_* flag.
  • Check your shell, then ~/.claude/settings.json (which wins over the shell), then managed settings (which win over both).
  • To see what an export really holds, send it to a collector on 127.0.0.1 with the debug exporter.

Top comments (0)