Skip to main content

Send traces with OpenTelemetry

If your agent framework already exports OpenTelemetry spans, you can send them to Caliper by changing configuration. Each OpenTelemetry trace becomes one conversation in a Caliper source.

1. Make a key

Create a workspace API key with the Send agent traces scope (caliper:traces:write). The scope can send and nothing else.

2. Point the exporter at Caliper

Set these where your agent runs:

OTEL_EXPORTER_OTLP_ENDPOINT=https://api.zerowidth.ai/1.0/caliper/otel
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer zw_..."
OTEL_SERVICE_NAME=support-bot
  • The exporter posts to /v1/traces under the endpoint, so the full address is https://api.zerowidth.ai/1.0/caliper/otel/v1/traces.
  • Both OTLP/HTTP encodings work: protobuf (the usual default) and JSON (http/json). Compressed bodies (gzip) work too.
  • The service name becomes the source's name.

3. Check it arrived

Run your agent, then open Sources in Caliper. The source appears with its first conversations, and each span shows up as a step.

What Caliper reads

Caliper reads spans that follow the OpenTelemetry GenAI conventions, along with the attribute names several common instrumentation libraries use.

SpanBecomes
An agent run (gen_ai.operation.name = invoke_agent)The conversation's input and output
A model call (chat, or any span with gen_ai.request.model)A model step with its model, tokens, and cost
A tool call (execute_tool, or gen_ai.tool.name)A tool step with its arguments and result
A retrievalA lookup with its query and the documents it returned
Anything elseA step with its name, timing, and attributes

The conversation id comes from gen_ai.conversation.id or session.id, and the person from enduser.id or user.id.

Spans of one trace often arrive across several exports, because the outermost span finishes last. Caliper adds them to the same conversation as they come in, and a span sent twice counts once.

Leaving things out

Caliper keeps what arrives. To keep prompts, replies, or tool results out of Caliper, turn off content capture in your instrumentation library, or drop those attributes in your OpenTelemetry pipeline before they're exported.

Limits

The same plan limits apply as for POST /1.0/caliper/traces. Over the per-minute limit, your exporter gets a 429 and retries on its own.

2 min read