langwatch claudestarts Claude Code and sets up the connection on the first run. Use it on a machine you work on.langwatch instrument claudewrites the same setup and exits. Use it on a server, or when the telemetry must go to a team project.
Before you start
- Install Claude Code.
- Install the LangWatch command line tool:
npm install -g langwatch - Create an account at app.langwatch.ai, or run your own instance with
npx @langwatch/server.
Run Claude Code through the wrapper
LangWatch remembers the answer, so later runs do not ask again. Everything else is unchanged:
langwatch claude accepts the same flags, the same subcommands and the same keyboard shortcuts as claude, and it returns the same exit code.
A virtual key is created the first time you choose the gateway, not at login. If you always keep your own subscription, LangWatch never creates one for you.
Set up a machine without starting Claude Code
langwatch instrument claude writes the connection into ~/.claude/settings.json and exits. A plain claude run on that machine then sends its telemetry to LangWatch. This is the setup for a server that holds many agents, for a machine image, or for a configuration management run.
Choose where the telemetry goes
Pass one scope flag, and one only.Send the telemetry to a team project
traces:create permission on the project. See Roles and permissions.
The wrapper accepts the same flags. This pins the project and then starts Claude Code:
--project and --personal are LangWatch flags. LangWatch removes them from the command line before Claude Code reads it, so they never reach the agent.
Set up a machine that never logs in
--key takes an ingest key (ik-lw-…). It needs no login and contacts no server, which makes it the option for a shared machine, a build agent, or a base image.
LANGWATCH_INGEST_KEY environment variable:
Move a tool back to your personal workspace
Remove the setup
What you get in LangWatch
Open your personal page at/me, or open the project you pinned Claude Code to.
- Sessions: one row per Claude Code session, with the context it carried, how often it compacted, how long it worked, and the pull requests it drove.
- Traces: one trace per turn, with the tool call tree, the latency of each step, and each subagent on its own branch.
- Cost: the amount per session and per turn, the model of each turn, and the split between tokens written to the prompt cache and tokens read back from it.
- Content: the prompt of each turn, the input and the output of each tool call, and the response of the model.
Attribute sessions to pull requests
LangWatch joins a session to a pull request through the repository and branch the session reports. The session reports the directory it is working in, read at the start of the session and again after every turn. Two rules follow from how Claude Code tracks that directory:- A
cdinside the Bash tool does not move the session. The session still reports the directory it was launched in. - A native switch with the EnterWorktree tool does move the session. From then on it reports the repository and branch of the worktree it entered.
- Create a worktree for the branch:
git -C <repo> fetch origin <branch> && git -C <repo> worktree add .claude/worktrees/<name> <branch> - Ask the session to call the EnterWorktree tool with that worktree’s path.
gh commands from a home directory, attaches to no repository and no pull request, and its token cost cannot be attributed. The per pull request rollup is available over the API as Get pull request coding agent usage.
Content and privacy
The setup thatlangwatch claude and langwatch instrument claude write turns on the four Claude Code content flags, because the content is what makes a trace worth reading:
Remove the flags from
~/.claude/settings.json to keep only the usage numbers: tokens, cost, model, latency, the tool call tree and the subagent tree stay, and the content stops.
langwatch claude and langwatch instrument claude set OTEL_LOG_RAW_API_BODIES, which already carries the assistant’s response text along with the rest of the request and response body. If you want the response text on its own, without the full body, add OTEL_LOG_ASSISTANT_RESPONSES yourself: the wrapper does not set it for you.
Claude Code shortens each inline body at 60 kilobytes. CLAUDE_CODE_OTEL_CONTENT_MAX_LENGTH raises that limit. Claude Code always removes extended thinking from the bodies, so LangWatch never receives it.
Troubleshooting
Nothing arrives in LangWatch
Nothing arrives in LangWatch
Restart Claude Code. It reads
~/.claude/settings.json at start, so a session that was already open when you ran langwatch instrument claude keeps its old configuration.Then run langwatch instrument claude again and read what it prints. It names the file it wrote and the destination the telemetry goes to.The trace has no tool call tree, no latencies and no subagents
The trace has no tool call tree, no latencies and no subagents
CLAUDE_CODE_ENHANCED_TELEMETRY_BETA is missing. It is the flag that turns spans on, and OTEL_TRACES_EXPORTER does nothing without it. Cost and tokens still arrive, so the session appears, but LangWatch has no structure to attach them to and every subagent folds into the main session.The trace has no prompt
The trace has no prompt
OTEL_LOG_USER_PROMPTS is missing. Claude Code removes the prompt text from its user_prompt event by default.The trace has no response
The trace has no response
Both
OTEL_LOG_RAW_API_BODIES and OTEL_LOG_ASSISTANT_RESPONSES are missing. Claude Code reports the response text of the assistant on its api_response_body event (needs OTEL_LOG_RAW_API_BODIES=1, and carries the full request and response JSON) or on its lighter assistant_response event (needs OTEL_LOG_ASSISTANT_RESPONSES=1, and carries only the response text). Both are off by default. Set OTEL_LOG_ASSISTANT_RESPONSES=1 if you want the response without the rest of the body.Claude Code docs describe OTEL_LOG_ASSISTANT_RESPONSES as falling back to the value of OTEL_LOG_USER_PROMPTS. Don’t rely on that fallback: set it explicitly.Claude Code also reports api_response_body and assistant_response for work that is not a conversation, such as an autosuggestion or a session title. LangWatch filters those out, so a title never becomes the output of a trace.The telemetry goes to the wrong workspace
The telemetry goes to the wrong workspace
Run
langwatch instrument claude --project <id-or-slug> to move it to a team project, or langwatch instrument claude --personal to move it back to your own.Authentication errors
Authentication errors
Check that the key is live and that the header reads
Authorization=Bearer <key>. An ingest key can write traces and nothing else, so a key that works for ingestion still fails on other endpoints.On a machine with a login, run langwatch login --device again to refresh the session.The cost is zero although the traces arrive
The cost is zero although the traces arrive
The model name on the span does not match an entry in the LangWatch cost catalog. Read
gen_ai.request.model on the span. Current names such as claude-sonnet-4-6, claude-opus-4-7 and claude-haiku-4-5 match; older aliases return no cost.Manual OpenTelemetry setup
Use this when you cannot install the LangWatch command line tool. The block below mirrors the variableslangwatch instrument claude writes for you, plus the optional OTEL_LOG_ASSISTANT_RESPONSES flag, which the wrapper does not set. Drop that line if you only want what the wrapper gives you.
Environment variables
ik-lw-…), which can create traces and nothing else. Keep a full project API key (sk-lw-…) out of the configuration of a coding agent: it can read and change your project data, and a coding agent has no use for that.
For a self-hosted instance, replace the endpoint with the address of your instance followed by /api/otel. Claude Code appends /v1/traces, /v1/logs and /v1/metrics on its own. Never write the per-signal path yourself.
Settings file
Claude Code reads the same variables from theenv block of ~/.claude/settings.json, which survives a new terminal:
.claude/settings.json in the repository and keep the key and the content flags in a gitignored .claude/settings.local.json. See Per-repository telemetry.
Managed settings for a fleet
An administrator can apply the same block to every machine through the managed settings file:- macOS:
/Library/Application Support/ClaudeCode/managed-settings.json - Linux and Windows Subsystem for Linux:
/etc/claude-code/managed-settings.json - Windows:
C:\ProgramData\ClaudeCode\managed-settings.json
Team attribution
Add your own labels to every trace withOTEL_RESOURCE_ATTRIBUTES:
Headers from a script
An enterprise that issues short-lived tokens can produce the headers at start time. Add this to.claude/settings.json: