Skip to main content
If your agent already emits OpenTelemetry traces with the gen_ai.* attributes, it can write to Niadra without new calls in the conversation path: point an OTLP exporter at Niadra and every model call becomes the messages of the conversation, with who spoke and when. This is the fastest way to start building memory from an agent you do not want to touch, and a common way to capture a vendor platform that exports traces but has no Niadra integration. Reading still happens through context(), the history tools or MCP. OpenTelemetry covers the write side.

The endpoint

Niadra accepts OTLP over HTTP with a JSON body (Content-Type: application/json):
Authenticate with the source key in Authorization: Bearer, the same key your agent would use for the SDK, with the track scope. The answer is the standard OTLP one: rejected spans are counted in partialSuccess.rejectedSpans, with the reasons in errorMessage. A protobuf body is refused with 422, so set your exporter to http/json.

What Niadra reads from a span

The gen_ai semantic conventions are still changing, and several generations of attributes live side by side in the libraries in use today. Niadra reads them in cascade, so you do not have to pin a library version for us: Two things OpenTelemetry has no attribute for, so you set them yourself, on the span or on the resource: Every span repeats the conversation so far, so each message gets the idempotency key of its position in the conversation: a re-exported history deduplicates instead of duplicating.
Span attributes can end up in every backend your collector exports to. Prefer an internal id (app_user_id or enduser.id) over a phone number or an e-mail, and send the Niadra attributes only on the pipeline that goes to Niadra. Personal data never travels in a URL.

Steps

1. Point an exporter at Niadra

Add an OTLP exporter next to the one you already have, with the JSON encoding. The OpenTelemetry SDK for Node.js has a JSON exporter. The Python SDK exports protobuf only, so send its spans to an OpenTelemetry Collector and let the Collector forward them to Niadra as JSON.

2. Set the channel and the customer

Set the Niadra attributes on the span that carries the messages, or once on the resource for a process that serves one channel. Keep gen_ai.conversation.id stable for the whole conversation: it becomes the conversation_id.
Attributes are read from the span itself and from its resource. When your model-client instrumentation writes the messages on a child span, set the Niadra attributes on the resource, or copy them to that span with a span processor.

3. Turn on content capture

Most gen_ai instrumentations leave message content out by default. Niadra needs it to build memory, so enable content capture in the instrumentation you use (for many Python instrumentations, OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true). If you prefer to keep content out of your other backends, run a second pipeline for Niadra only.

4. Confirm the events arrived

A span becomes messages with the same guarantees as a batch: the raw content is stored before the answer and events are ordered by the time they happened. Read the timeline of the customer to check:

When to use the SDK instead

OpenTelemetry records what the model saw and said. The SDK adds what traces do not carry: the context read before the answer and the context_stamp of each agent turn, verification with verify(), links between handles with identify(), agent actions with closes, handoffs and the end of the conversation. Those feed the context use measurement. A common path is to start with OpenTelemetry to build memory from day one, then add context() and the SDK writes to the agents that answer customers.

Next steps

Events and the batch

what an event is and how it is deduplicated.

Quickstart

reading context with the SDK.

Receive OTLP traces

the endpoint reference.

Webhooks from your systems

events from CRM, ERP and help desk.