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):
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
Thegen_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.
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. Keepgen_ai.conversation.id stable for the whole conversation: it becomes the conversation_id.
3. Turn on content capture
Mostgen_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 thecontext_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.

