moda.conversation_id attribute (the trace ID); it can span many OpenTelemetry traces, and the OTLP traceId is only a fallback for grouping. The Moda SDKs use this same endpoint; you only need this page when integrating an existing OpenTelemetry pipeline directly.
Endpoint and authentication
Point an exporter at Moda
- Exporter environment variables
- OpenTelemetry Collector
Standard OTLP exporters read these variables:Use the
_TRACES_-scoped variables (rather than OTEL_EXPORTER_OTLP_ENDPOINT) so the exporter posts to the exact /v1/traces path and other signals in your pipeline are unaffected.Already running OpenTelemetry inside a Node.js app? The Moda SDK for Node.js attaches its span processor to your existing TracerProvider instead of replacing it — see Node.js SDK.
Supported attribute conventions
Moda recognizes GenAI spans in each of these conventions automatically, per span — mixed batches are fine:
When a span carries both
llm.* and numbered gen_ai.* message attributes, the llm.* set is used — messages are never extracted twice from one span.
Model, provider, usage, and finish reason
For each field, the first attribute found wins:Moda attribution attributes
Set these span attributes to control how spans map onto Moda traces, users, environments, and prompts. All are optional.
The trace ID, user, and prompt keys are also read from the Vercel AI SDK metadata form
ai.telemetry.metadata.moda.*, which is how getVercelAITelemetry() sets them.
On the resource, user.id / enduser.id and deployment.environment are read as defaults for every span under that resource.
Trace ID precedence
For each span, the trace ID (conversation_id) is resolved in this order:
moda.conversation_id(including theai.telemetry.metadata.moda.conversation_idform)gen_ai.conversation.id— the legacy underscore formgen_ai.conversation_idand the Traceloop keytraceloop.association.properties.session_idare also honored- The span’s OpenTelemetry
traceId
session_id attribute is deliberately ignored: it is too generic and could merge unrelated traces. Without an explicit conversation_id, spans group by OpenTelemetry trace — each OTLP trace becomes its own Moda trace — so set moda.conversation_id for anything multi-step.
Environment normalization
Environments are normalized todevelopment, staging, or production. Common aliases map to their canonical forms (dev / develop → development, stg / stage → staging, prod → production); unrecognized values fall back to production. A span-level moda.environment overrides the resource-level deployment.environment.
Example request
A minimal OTLP/JSON request with one GenAI chat span:count is the number of trace messages extracted (the example yields two — one user message and one assistant message):
ExportTraceServiceResponse (Content-Type: application/x-protobuf), so unmodified OTLP exporters work without changes.
After sending, open Traces in the dashboard — trace conv-123 appears with the extracted user and assistant messages within minutes.
Limits and errors
- Request bodies are limited to 5 MB (
413Request too large). There is no per-request span-count limit below that. - An optional
X-Request-IDheader (UUID) is echoed back asrequestIdfor correlating requests with responses.
Next steps
- Ingestion overview — all ingestion endpoints, authentication, and shared limits.
- Vercel AI SDK — the AI SDK integration that emits
ai.*telemetry to this endpoint. - HTTP API — the simple JSON alternative when you don’t run OpenTelemetry.
- Reliability — retries, limits, and error envelopes.