> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sazabi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Claude Agent SDK

> Pass OTEL environment variables through the Claude Agent SDK's env option to ship telemetry from your agents — prompts, tool calls, and model API requests with token counts and cost — to Sazabi.

[All Claude Agent SDK integration capabilities](https://docs.sazabi.com/catalogs/integrations/claude-agent-sdk)

## About

Ship telemetry from agents you build on the [Claude Agent SDK](https://code.claude.com/docs/en/agent-sdk/overview) to Sazabi. The SDK runs Claude Code under the hood, so every agent run emits the same structured events as a Claude Code session — user prompts, tool calls, tool results, and model API requests with token counts and cost — with no extra instrumentation library.

Events carry `app.entrypoint` set to `sdk-py` or `sdk-ts`, so you can tell production agents apart from interactive Claude Code sessions. `claude_code.api_request` events carry `model`, `input_tokens`, `output_tokens`, `cache_read_tokens`, `cost_usd`, and `duration_ms`; every event carries `session.id`.

> [!WARNING]
>
> Setting `OTEL_LOG_USER_PROMPTS=1` exports the raw prompt text your agent sends, which in production often includes your end users' input. The snippets below keep it off; token counts, cost, and tool calls are exported either way.

## Prerequisites

* An agent built on the Claude Agent SDK for Python or TypeScript
* Your Sazabi intake URL, shown above — open the log source and copy the **Intake URL** from its setup screen (the public key is embedded in the URL)

## Set up in the dashboard

**Step 1**

### Store the intake URL with your agent's configuration

Make the intake URL available to your agent as an environment variable named `SAZABI_INTAKE_URL` — in your deployment's secret store, or your shell for a local run. Keep it out of committed source.

**Step 2**

### Pass the telemetry variables in your agent options

Add the following variables to the `env` option of every `query()` call or `ClaudeSDKClient` your agent creates.

> [tab] Python
>
> ```python title="agent.py" theme={"system"}
> import os
> from claude_agent_sdk import ClaudeAgentOptions, query
>
> options = ClaudeAgentOptions(
>     env={
>         "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
>         "OTEL_LOGS_EXPORTER": "otlp",
>         "OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
>         "OTEL_EXPORTER_OTLP_ENDPOINT": os.environ["SAZABI_INTAKE_URL"],
>         "OTEL_METRICS_INCLUDE_ENTRYPOINT": "true",
>         "OTEL_LOG_USER_PROMPTS": "0",
>         "OTEL_LOG_ASSISTANT_RESPONSES": "0",
>     },
> )
>
> async for message in query(prompt=prompt, options=options):
>     ...
> ```
>
> In Python, `env` is merged over your process environment.

> [tab] TypeScript
>
> ```ts title="agent.ts" theme={"system"}
> import { query } from "@anthropic-ai/claude-agent-sdk";
>
> const telemetryEnv = {
>   ...process.env,
>   CLAUDE_CODE_ENABLE_TELEMETRY: "1",
>   OTEL_LOGS_EXPORTER: "otlp",
>   OTEL_EXPORTER_OTLP_PROTOCOL: "http/protobuf",
>   OTEL_EXPORTER_OTLP_ENDPOINT: process.env.SAZABI_INTAKE_URL,
>   OTEL_METRICS_INCLUDE_ENTRYPOINT: "true",
>   OTEL_LOG_USER_PROMPTS: "0",
>   OTEL_LOG_ASSISTANT_RESPONSES: "0",
> };
>
> for await (const message of query({ prompt, options: { env: telemetryEnv } })) {
>   // handle messages
> }
> ```
>
> In TypeScript, `env` replaces the environment the SDK passes to Claude Code. Keep the `...process.env` spread so your agent still sees `ANTHROPIC_API_KEY` and `PATH`.

Keep `OTEL_METRICS_INCLUDE_ENTRYPOINT` at `true` — without it, events carry no `app.entrypoint`. Leave the metrics exporter off to keep volume down; if you enable it, Sazabi stores each metric data point as a log record.

**Step 3**

### Redeploy your agent

The SDK reads the variables each time it starts Claude Code. Deploy the change (or restart your agent locally), then run one query.

## Set up with the CLI

You can also register the Claude Agent SDK log source with the [Sazabi CLI](https://docs.sazabi.com/reference/cli.md) (installed and authenticated — see [CLI reference](https://docs.sazabi.com/reference/cli/log-sources.md)).

Registering the source mints the same intake URL the dashboard shows above (the public key is embedded in its hostname):

```bash theme={"system"}
sazabi log-sources create claude_agent_sdk --mode manual
```

The command prints the intake URL for the new source — copy the whole URL and point your agent at it using the configuration shown above. Run `sazabi log-sources get <log-source-id>` at any time to reprint the endpoint, or `sazabi log-sources list` to see every log source in the project.

## Verify

Run one query through your agent. Open the [Intake page](https://docs.sazabi.com/guides/instrument/intake.md) in the Sazabi dashboard and confirm events from the **Claude Agent SDK** source appear within a minute or two.

From the CLI, `sazabi logs ask "How many claude-code log lines with app.entrypoint sdk-py or sdk-ts arrived in the last 15 minutes, by event name?"` confirms events are arriving. Start a thread and search for `claude_code.api_request` to see each model request with its token counts and cost, or for `claude_code.api_error` to find failed requests.

## Troubleshooting

**No events after a run** — Confirm `SAZABI_INTAKE_URL` is set in the process that runs your agent and that the `env` option reaches the `query()` call or client that ran. Claude Code sends its batch when the run ends; a process killed mid-run may not send it.

**TypeScript agent can no longer reach Anthropic** — The `env` object replaced the whole environment. Restore the `...process.env` spread.

**Events appear without `app.entrypoint`** — `OTEL_METRICS_INCLUDE_ENTRYPOINT` is missing or not `true`. Set it and redeploy.

**Events appear under service `claude-code`** — That is expected: the SDK runs Claude Code, which names its own service. Filter on `app.entrypoint` to separate agents from interactive sessions, or add `OTEL_RESOURCE_ATTRIBUTES` with a `deployment.environment=` entry to tell environments apart.

**Metric data points appear as log records** — Expected when `OTEL_METRICS_EXPORTER` is set: Sazabi stores each metric data point as a log record, not in a metrics store. Unset it to keep volume down; `api_request` events already carry token counts and cost.

## Further reading

> [card] [Claude Code](https://docs.sazabi.com/catalogs/log-sources/coding-agents/claude-code.md)
>
> Ship interactive Claude Code session telemetry.

> [card] [Intake](https://docs.sazabi.com/guides/instrument/intake.md)
>
> See per-source ingestion volume and health.

> [card] [Log sources](https://docs.sazabi.com/catalogs/log-sources.md)
>
> Browse the full log source catalog.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.