Skip to main content

OpenTelemetry

The OpenTelemetry integration is the import-free path. If your team already runs an OTel collector for distributed tracing, point its OTLP/HTTP exporter at Adjudon and every span carrying the gen_ai.* semantic-convention attributes flows into the Decision Trace pipeline as if you had called the SDK directly. No import adjudon, no constructor, no per-call wrapper. The collector you already operate becomes the integration.

Endpoint

POST https://api.adjudon.com/otel/v1/traces

OTLP/HTTP JSON only today. The endpoint accepts payloads up to 5 MB — OTLP batches commonly carry 1,000+ spans, and the ceiling exists to absorb the largest production batches without splitting them. Authentication is the same adj_agent_* API key the Traces API accepts; the same per-agent and per-org rate limits apply.

Configure your OTel SDK

Python — opentelemetry-sdk
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter

provider = TracerProvider(resource=Resource.create({
"service.name": "customer-support-bot", # → DecisionTrace.agentId
}))

exporter = OTLPSpanExporter(
endpoint="https://api.adjudon.com/otel/v1/traces",
headers={"Authorization": "Bearer adj_agent_..."},
)
provider.add_span_processor(BatchSpanProcessor(exporter))
OTel Collector — exporter config
exporters:
otlphttp/adjudon:
endpoint: https://api.adjudon.com/otel
traces_endpoint: https://api.adjudon.com/otel/v1/traces
headers:
authorization: Bearer adj_agent_...
encoding: json

service:
pipelines:
traces:
exporters: [otlphttp/adjudon]

The collector route is the production deployment pattern: route every gen-AI service through one collector, attach Adjudon as one of several exporters (alongside Tempo / Jaeger / your incumbent APM), and let the collector handle batching and retry.

Attribute mapping

The Adjudon mapper consumes the OTel GenAI semantic conventions and maps them onto the DecisionTrace schema:

OTel attributeDecisionTrace field
service.name (resource)agentId
gen_ai.systemmetadata.llm_provider
gen_ai.request.modelmetadata.request_model
gen_ai.response.modelmetadata.response_model
gen_ai.request.temperatureinputContext.temperature
gen_ai.request.max_tokensinputContext.max_tokens
gen_ai.request.top_pinputContext.top_p
gen_ai.response.finish_reasonsoutputDecision.finish_reasons
gen_ai.usage.input_tokensmetadata.tokens_input
gen_ai.usage.output_tokensmetadata.tokens_output
event gen_ai.content.promptinputContext.prompt
event gen_ai.content.completionoutputDecision.completion
span name · gen_ai.operation.nametriggeringCondition

A span without any gen_ai.* attribute is silently dropped — OTel collectors mix gen-AI traffic with HTTP, DB, and queue spans, and Adjudon only ingests the gen-AI subset. The endpoint returns 200 OK even when every span in the batch was dropped, per the OTLP spec.

Deduplication on retry

The mapper computes a deterministic traceId from the OTel trace ID + span ID:

traceId = otel-<otel_trace_id>-<otel_span_id>

A retry that re-sends the same span produces the same traceId; MongoDB's unique index on traceId accepts the duplicate as a no-op (E11000 caught and treated as success). This is what allows the OTel pipeline to skip the standard Idempotency-Key middleware — the dedup is intrinsic to the OTel identifiers.

Errors

The endpoint returns standard HTTP responses with the same error shape as POST /traces. The most common failure modes:

HTTPCause
400Malformed OTLP JSON; collector should not retry
401Missing or invalid adj_agent_* API key
429Per-agent or per-org rate limit hit; collector should back off
5xxAdjudon transient; collector retries with exponential backoff

Per OTLP, the server SHOULD return 200 OK for partial-success batches; Adjudon does so and surfaces rejected counts in the response body so the collector can log them.

Resources

  • Quickstart — first trace in 60 seconds via the SDK path
  • Traces API — the underlying resource OTel spans materialise as
  • Authenticationadj_agent_* key format and rotation
  • Python SDK — the adjudon-otel adapter package for teams that want the import-driven path
  • OpenTelemetry GenAI conventions: opentelemetry.io/docs/specs/semconv/gen-ai/
  • Error Codes — the broader error taxonomy