import SelfHostedOtelEndpoint from "../../../partials/ingest/self-hosted-otel-endpoint.mdx"; # Claude Code ## Overview The Anthropic Claude Code input receives OTel telemetry data emitted by [Claude Code](https://claude.ai/code), Anthropic's agentic coding tool. Claude Code natively supports OpenTelemetry for monitoring usage, performance, and operational metrics. ## Requirements There is no configuration needed at the input level in Monad. Simply create a Claude Code input and attach it to a pipeline. All configuration is done on the Claude Code side, where you point its OTel exporter to the Monad endpoint with the appropriate authentication headers. ## Claude Code Configuration To send telemetry from Claude Code to Monad, configure the OpenTelemetry exporter in your Claude Code settings. You will need: 1. A Monad **organization API key** with the `pipeline:data:write` permission 2. The **pipeline ID** of the pipeline with your Claude Code input ### Required Headers | Header | Value | Description | |--------|-------|-------------| | `Authorization` | `ApiKey ` | Monad organization API key | Your pipeline's ingest hostname, `.data.monad.com`, tells Monad which pipeline the telemetry belongs to. ### Example Configuration #### Local Setup For individual users, set the following environment variables before launching Claude Code: ```bash export CLAUDE_CODE_ENABLE_TELEMETRY=1 export OTEL_EXPORTER_OTLP_ENDPOINT=https://.data.monad.com:4317 export OTEL_EXPORTER_OTLP_PROTOCOL=grpc export OTEL_EXPORTER_OTLP_HEADERS="Authorization=ApiKey " ``` These can also be set directly in your local Claude Code configuration file rather than exporting them in your shell. See the [Claude Code Monitoring Usage guide](https://code.claude.com/docs/en/monitoring-usage) for details. #### Organization-Wide Setup To enforce telemetry across your entire organization, administrators can configure these settings centrally so individual users don't need to set anything locally. See the [Administrator Configuration guide](https://code.claude.com/docs/en/monitoring-usage#administrator-configuration) for how to roll this out org-wide. :::tip[Blog Walkthrough] For a full walkthrough of setting up Claude Code with Monad and using the community transform, see our blog post: [Detection Engineering For Claude Code, Part 2](https://www.monad.com/blog/detection-engineering-for-claude-code-part-2). ::: ## Community Transform A community transform called [**"Flatten Claude OTLP Logs and Metrics"**](https://app.monad.com/transforms/repository/utility:v1.0.0:anthropic:claude-otlp-flatten) is available in the [Monad Transforms Repository](https://app.monad.com/transforms/repository). This transform separates and flattens OTel records for easier readability, classification, and querying. For example, the raw OTel record: ```json { "resourceLogs": [ { "resource": { "attributes": [ { "key": "host.arch", "value": { "stringValue": "amd64" } }, { "key": "os.type", "value": { "stringValue": "linux" } }, { "key": "os.version", "value": { "stringValue": "6.6.87.2-microsoft-standard-WSL2" } }, { "key": "service.name", "value": { "stringValue": "claude-code" } }, { "key": "service.version", "value": { "stringValue": "2.1.87" } }, { "key": "wsl.version", "value": { "stringValue": "2" } } ] }, "scopeLogs": [ { "logRecords": [ { "attributes": [ { "key": "user.id", "value": { "stringValue": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } }, { "key": "session.id", "value": { "stringValue": "ffffffff-ffff-ffff-ffff-ffffffffffff" } }, { "key": "organization.id", "value": { "stringValue": "ffffffff-ffff-ffff-ffff-ffffffffffff" } }, { "key": "user.email", "value": { "stringValue": "user@example.com" } }, { "key": "user.account_uuid", "value": { "stringValue": "ffffffff-ffff-ffff-ffff-ffffffffffff" } }, { "key": "user.account_id", "value": { "stringValue": "user_0fffffffffffff" } }, { "key": "terminal.type", "value": { "stringValue": "windows-terminal" } }, { "key": "event.name", "value": { "stringValue": "user_prompt" } }, { "key": "event.timestamp", "value": { "stringValue": "2026-03-31T18:58:48.275Z" } }, { "key": "event.sequence", "value": { "intValue": "76" } }, { "key": "prompt.id", "value": { "stringValue": "ffffffff-ffff-ffff-ffff-ffffffffffff" } }, { "key": "prompt_length", "value": { "stringValue": "21" } }, { "key": "prompt", "value": { "stringValue": "test prompt from user" } } ], "body": { "stringValue": "claude_code.user_prompt" }, "observedTimeUnixNano": "1774983528275000000", "timeUnixNano": "1774983528275000000" }, { "attributes": [ { "key": "user.id", "value": { "stringValue": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } }, { "key": "session.id", "value": { "stringValue": "ffffffff-ffff-ffff-ffff-ffffffffffff" } }, { "key": "organization.id", "value": { "stringValue": "ffffffff-ffff-ffff-ffff-ffffffffffff" } }, { "key": "user.email", "value": { "stringValue": "user@example.com" } }, { "key": "user.account_uuid", "value": { "stringValue": "ffffffff-ffff-ffff-ffff-ffffffffffff" } }, { "key": "user.account_id", "value": { "stringValue": "user_0fffffffffffff" } }, { "key": "terminal.type", "value": { "stringValue": "windows-terminal" } }, { "key": "event.name", "value": { "stringValue": "api_request" } }, { "key": "event.timestamp", "value": { "stringValue": "2026-03-31T18:58:50.911Z" } }, { "key": "event.sequence", "value": { "intValue": "77" } }, { "key": "prompt.id", "value": { "stringValue": "ffffffff-ffff-ffff-ffff-ffffffffffff" } }, { "key": "model", "value": { "stringValue": "claude-sonnet-4-6" } }, { "key": "input_tokens", "value": { "stringValue": "3" } }, { "key": "output_tokens", "value": { "stringValue": "15" } }, { "key": "cache_read_tokens", "value": { "stringValue": "19749" } }, { "key": "cache_creation_tokens", "value": { "stringValue": "13" } }, { "key": "cost_usd", "value": { "stringValue": "0.00620745" } }, { "key": "duration_ms", "value": { "stringValue": "2630" } }, { "key": "speed", "value": { "stringValue": "normal" } } ], "body": { "stringValue": "claude_code.api_request" }, "observedTimeUnixNano": "1774983530911000000", "timeUnixNano": "1774983530911000000" } ], "scope": { "name": "com.anthropic.claude_code.events", "version": "2.1.87" } } ] } ] } ``` Becomes these two flattened records: ```json { "body": "claude_code.user_prompt", "event.name": "user_prompt", "event.sequence": "76", "event.timestamp": "2026-03-31T18:58:48.275Z", "host.arch": "amd64", "observedTimeUnixNano": "1774983528275000000", "organization.id": "ffffffff-ffff-ffff-ffff-ffffffffffff", "os.type": "linux", "os.version": "6.6.87.2-microsoft-standard-WSL2", "prompt": "test prompt from user", "prompt.id": "ffffffff-ffff-ffff-ffff-ffffffffffff", "prompt_length": "21", "service.name": "claude-code", "service.version": "2.1.87", "session.id": "ffffffff-ffff-ffff-ffff-ffffffffffff", "terminal.type": "windows-terminal", "timeUnixNano": "1774983528275000000", "user.account_id": "user_0fffffffffffff", "user.account_uuid": "ffffffff-ffff-ffff-ffff-ffffffffffff", "user.email": "user@example.com", "user.id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "wsl.version": "2" } ``` ```json { "body": "claude_code.api_request", "cache_creation_tokens": "13", "cache_read_tokens": "19749", "cost_usd": "0.00620745", "duration_ms": "2630", "event.name": "api_request", "event.sequence": "77", "event.timestamp": "2026-03-31T18:58:50.911Z", "host.arch": "amd64", "input_tokens": "3", "model": "claude-sonnet-4-6", "observedTimeUnixNano": "1774983530911000000", "organization.id": "ffffffff-ffff-ffff-ffff-ffffffffffff", "os.type": "linux", "os.version": "6.6.87.2-microsoft-standard-WSL2", "output_tokens": "15", "prompt.id": "ffffffff-ffff-ffff-ffff-ffffffffffff", "service.name": "claude-code", "service.version": "2.1.87", "session.id": "ffffffff-ffff-ffff-ffff-ffffffffffff", "speed": "normal", "terminal.type": "windows-terminal", "timeUnixNano": "1774983530911000000", "user.account_id": "user_0fffffffffffff", "user.account_uuid": "ffffffff-ffff-ffff-ffff-ffffffffffff", "user.email": "user@example.com", "user.id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "wsl.version": "2" } ``` In splitting this way, the "body" key can be used to classify, sort, drop, or route each record by type. ## Related Articles - [Claude Code - Monitoring Usage](https://code.claude.com/docs/en/monitoring-usage) - [Monad OpenTelemetry Input](../monad/monad-otel.mdx) - [OpenTelemetry OTLP Exporter Configuration](https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/) - [Detection Engineering For Claude Code, Part 1](https://www.monad.com/blog/detection-engineering-for-claude-code-part-1) - [Detection Engineering For Claude Code, Part 2](https://www.monad.com/blog/detection-engineering-for-claude-code-part-2) ## Sync frequency This is a push (receiver) input: Monad ingests records as the source sends them, so there is no polling interval. See [Input Sync Frequency](../../guides/sync-frequency) for details.