Introducing Confident Monitor

OpenTelemetry

How Confident AI's OTEL server ingests traces, and the gen_ai, confident, OpenInference, and OpenLLMetry conventions it understands

OpenTelemetry (OTEL) is the open, vendor-neutral standard for traces, metrics, and logs. Confident AI's LLM tracing is OpenTelemetry-native: every trace arrives as OTLP, whether it came from confident-trace, a third-party instrumentor, or a raw OpenTelemetry SDK.

Overview

Confident AI's OpenTelemetry server (OTEL server) is the OTLP/HTTP ingestion endpoint for all tracing data, hosted at https://(eu.)otel.confident-ai.com. All spans enter through this endpoint, whether produced by the confident-trace SDKs, a third-party integration, a cloud runtime, or an OpenTelemetry Collector.

The OTEL server accepts standard OTLP, so confident-trace is not required. However, confident-trace is still highly recommended even if you are using frameworks that are OTel native such as Google ADK, Pydantic AI, or AgentCore because of confident-trace's native integration with 25+ AI providers, frameworks, gateays, all at once.

The OTEL Server

flowchart LR
    subgraph App["Your application"]
        direction TB
        A[confident-trace<br/>25+ auto-instrumentations]
        B[OpenInference / OpenLLMetry<br/>instrumentors]
        C[Raw OpenTelemetry SDK<br/>Go, Ruby, C#, Java...]
        D[Cloud runtime<br/>AgentCore, Foundry, Gemini Enterprise]
    end
    subgraph Export["Export (OTLP/HTTP)"]
        direction TB
        X[OTLP exporter<br/>in-process]
        Y[OpenTelemetry Collector<br/>optional, fan-out to other backends]
    end
    A --> X
    B --> X
    C --> X
    D --> X
    X -.-> Y
    X --> S
    Y --> S
    S[Confident AI OTEL server<br/>otel.confident-ai.com] --> O[Confident AI]
    O --> E[Online evals]
    O --> T[Trace forwarding]

Spans reach Confident AI in one of two ways:

  • Directly from the process. The SDK's OTLP exporter (which confident-trace configures for you) batches spans and POSTs them with your project API key in the x-confident-api-key header.
  • Through an OpenTelemetry Collector. Your services export to a Collector you run, and its otlphttp exporter sends a copy to Confident AI alongside your other backends. See trace broadcasting.

On receipt, Confident AI authenticates the request, reads attributes from every namespace it understands, and reconstructs traces from the OpenTelemetry trace_id and parent span IDs. Spans from different services and languages therefore land in the same trace as long as they share W3C trace context — the basis of distributed tracing.

Regions and endpoints

RegionBase endpointTraces endpointAPI key prefix
US (default)https://otel.confident-ai.comhttps://otel.confident-ai.com/v1/tracesconfident_us_
EUhttps://eu.otel.confident-ai.comhttps://eu.otel.confident-ai.com/v1/tracesconfident_eu_
Self-hostedYour own otel. hosthttps://otel.<your-domain>/v1/tracesDeployment-issued

Use the base endpoint for OTEL_EXPORTER_OTLP_ENDPOINT (the SDK appends /v1/traces) and the traces endpoint for OTEL_EXPORTER_OTLP_TRACES_ENDPOINT or CONFIDENT_OTEL_ENDPOINT. See data residency and self-hosting.

Protocol support

CapabilitySupported
OTLP/HTTP protobufYes — recommended (Content-Type: application/x-protobuf)
OTLP/HTTP JSONYes (Content-Type: application/json)
OTLP/gRPCNo — use otlphttp in the Collector and the *-proto-http exporter in SDKs
Metrics / logs signalsNot yet — accepted and dropped so mixed pipelines don't error
Gzip request bodiesYes
Authenticationx-confident-api-key: <project api key> header
Batch sizeUp to 4 MB per request

Limits and responses

The OTEL server isn't subject to the API's rate limit, so exporters can send as fast as their batching produces spans. What it does enforce is your project's Trace Storage usage limit: the size of every request, after decompression, counts toward it. Once the project reaches the limit, every request returns 429 until the next billing cycle starts or the limit is raised. On the Free plan and during a trial, the limit is 1 GB-month.

StatusMeaningWhat the exporter does
200Spans accepted. If some were rejected, partialSuccess in the body says how many and whyMoves on
400The body couldn't be decoded as OTLPDrops the batch
401x-confident-api-key is missing or invalidDrops the batch
429The project reached its trace storage limitRetries with backoff, then drops the batch
503Ingestion is temporarily unavailable. Sent with Retry-After: 5Retries after 5 seconds

How confident-trace Works

confident-trace is the OpenTelemetry SDK pre-configured for Confident AI, not a proprietary SDK with an exporter bolted on. Every span it creates — from an automatic integration, the @span decorator or span() context manager in Python, or withSpan() in TypeScript — is a real OpenTelemetry span carrying the same gen_ai.* and confident.* attributes you would set by hand.

init() does the following once at startup:

StepWhat init() doesOpenTelemetry equivalent
ProviderCreates a global TracerProvider, or attaches to the one passed via init(tracer_provider=...)TracerProvider, trace.set_tracer_provider()
ExporterConfigures an OTLP/HTTP exporter to the OTEL server using CONFIDENT_API_KEY and, optionally, CONFIDENT_OTEL_ENDPOINTOTLPSpanExporter + BatchSpanProcessor
InstrumentationDetects and instruments installed SDKs — OpenAI, LangChain, LangGraph, LlamaIndex, Pydantic AI, Vercel AI SDK, and 20+ moreopentelemetry-instrumentation-* packages
SamplingApplies CONFIDENT_SAMPLE_RATE or init(sample_rate=...)TraceIdRatioBased sampler
EnvironmentStamps traces with CONFIDENT_ENVIRONMENT or init(environment=...)Resource attribute

Its helpers write confident.* attributes so you never touch attribute names directly:

HelperSets
@span / span() / withSpan()confident.span.type, span name, and type-specific fields such as model, provider
update_span() / updateSpan()Span input, output, metadata, and test-case fields
update_trace() / updateTrace()Trace name, tags, metadata, user, customer, thread, and trace-level input/output
trace_context() / traceContext()The same trace-level fields, scoped to a block
turn()Thread ID and per-turn input/output for multi-turn conversations

Because it is plain OpenTelemetry underneath:

  • Spans from tracer.start_as_current_span(...) and confident-trace nest in the same trace with no glue code.
  • An existing TracerProvider can be reused — init(tracer_provider=provider) in Python, createSpanProcessor() from confident-trace/otel in TypeScript. See existing OpenTelemetry provider.
  • OTEL_RESOURCE_ATTRIBUTES, OTEL_SERVICE_NAME, and W3C propagation apply unchanged.

Which Spans Are Exported

By default, confident-trace exports only AI spans, meaning spans with confident.* or gen_ai.* data, plus their parent spans. Other spans, such as HTTP requests or database queries, are exported only when they are a parent of an AI span.

To export every span:

from confident_trace import init

init(export_non_ai_spans=True)

GenAI Semantic Conventions

The OpenTelemetry GenAI semantic conventions define the gen_ai.* vocabulary for model calls, tool executions, and agent invocations. Confident AI adopts them as its baseline, so any conforming instrumentor produces typed traces without Confident-specific attributes.

Span types

When no confident.span.type is present, the span type is inferred from gen_ai.operation.name:

gen_ai.operation.nameSpan typeNotes
chat, text_completion, generate_contentllmModel, tokens, and messages read from gen_ai.*
embeddingsllmNo output messages
execute_tooltoolName from gen_ai.tool.name, arguments from gen_ai.tool.call.arguments
invoke_agent, create_agentagentName from gen_ai.agent.name
(no standard retrieval op)retrieverSet confident.span.type: retriever or use an OpenInference RETRIEVER span
(anything else)custom

Attributes

Conceptgen_ai.* attribute(s)Where it shows up
Providergen_ai.provider.name (legacy gen_ai.system)LLM span header, cost lookup
Modelgen_ai.request.model, gen_ai.response.modelLLM span header, cost
Token usagegen_ai.usage.input_tokens, gen_ai.usage.output_tokensToken usage and cost
Cached / reasoninggen_ai.usage.cache_read.input_tokens, gen_ai.usage.reasoning.output_tokensToken breakdown
Request paramsgen_ai.request.temperature, gen_ai.request.max_tokens, gen_ai.request.top_pSpan metadata
Messagesgen_ai.input.messages, gen_ai.output.messages, gen_ai.system_instructionsLLM span input/output
Toolgen_ai.tool.name, gen_ai.tool.call.arguments, gen_ai.tool.call.resultTool span name, input, output
Agentgen_ai.agent.name, gen_ai.agent.descriptionAgent span name and metadata
Conversationgen_ai.conversation.idThread ID
Finish reasongen_ai.response.finish_reasonsSpan metadata

Message content is accepted in every form the conventions have used, so older instrumentors keep working:

  • Span attributes (current) — gen_ai.input.messages / gen_ai.output.messages as JSON arrays
  • Span events (legacy) — gen_ai.content.prompt, gen_ai.content.completion, and per-message gen_ai.*.message events
  • Indexed attributes (OpenLLMetry-style) — gen_ai.prompt.{n}.* / gen_ai.completion.{n}.*

Supported Attribute Namespaces

Beyond gen_ai.*, the OTEL server recognizes the vocabularies of the most common LLM instrumentation ecosystems. Spans from any of these render as typed spans with input, output, model, and token usage populated.

NamespaceOriginTypical producersSupport
confident.*Confident AIconfident-trace, manual instrumentation, Agent SkillsFull — the only namespace that sets every field in the data model
gen_ai.*OpenTelemetry GenAI semconvconfident-trace, Google ADK, Strands, Bedrock AgentCore, Microsoft Foundry, official opentelemetry-instrumentation-* packagesFull
openinference.*, llm.*, input.*, output.*, retrieval.*, tool.*OpenInference (Arize)openinference-instrumentation-*, @arizeai/openinference-instrumentation-*, Arize Phoenix pipelinesFull — see OpenInference
traceloop.*, llm.*OpenLLMetry (Traceloop)traceloop-sdk, Traceloop's opentelemetry-instrumentation-* forksFull
ai.*Vercel AI SDK telemetryexperimental_telemetryFull — see Vercel AI SDK
mastra.*, agent.*Framework-specificMastra, Claude Agent SDKMapped onto agent and tool spans
Everything else—Any OpenTelemetry-instrumented servicePreserved as span metadata, not typed

OpenInference

OpenInferenceConfident AI
openinference.span.kind = LLMllm span
openinference.span.kind = TOOLtool span, name from tool.name
openinference.span.kind = AGENTagent span
openinference.span.kind = RETRIEVERretriever span, retrieval.documents.*.document.content → retrieval context
openinference.span.kind = CHAIN, EMBEDDING, otherscustom span
llm.model_name, llm.provider, llm.systemModel and provider
llm.token_count.prompt, llm.token_count.completionInput / output tokens
llm.input_messages.*, llm.output_messages.*LLM messages
input.value, output.valueSpan input / output
session.id, user.idThread and user
metadataSpan metadata

Setup with confident-trace as the exporter is on the OpenInference integration page.

OpenLLMetry

OpenLLMetryConfident AI
traceloop.span.kind = workflowRoot agent span; traceloop.workflow.name → trace name
traceloop.span.kind = agentagent span
traceloop.span.kind = taskcustom span
traceloop.span.kind = tooltool span
llm.request.type, gen_ai.system + gen_ai.request.modelllm span, model, and provider
gen_ai.prompt.{n}.*, gen_ai.completion.{n}.*LLM messages
gen_ai.usage.prompt_tokens, gen_ai.usage.completion_tokensInput / output tokens
traceloop.entity.input, traceloop.entity.outputSpan input / output
traceloop.association.properties.*Span metadata; session_id / user_id → thread and user

Point the Traceloop SDK at Confident AI with its standard exporter settings:

export TRACELOOP_BASE_URL="https://otel.confident-ai.com"
export TRACELOOP_HEADERS="x-confident-api-key=confident_us..."

Attribute precedence

When a span carries the same concept in several namespaces, Confident AI resolves it in this order:

  1. confident.* — always wins, so you can override anything an instrumentor set
  2. gen_ai.* — current names, then deprecated aliases
  3. OpenInference (openinference.*, llm.*)
  4. OpenLLMetry (traceloop.*, llm.*)
  5. Framework-specific namespaces (ai.*, mastra.*, …)
  6. Inference from span name and structure

Unconsumed attributes are kept verbatim as span metadata.

Choosing an Approach

If you...Use
Write Python or TypeScriptconfident-trace with automatic integrations
Use a framework with an OpenInference instrumentorOpenInference + confident-trace as exporter
Already run OpenLLMetry / TraceloopPoint TRACELOOP_BASE_URL at the OTEL server
Run agents on AWS, Azure, or Google Cloud managed runtimesCloud runtime guides
Already have an OpenTelemetry CollectorTrace broadcasting
Write Go, Ruby, C#, Java, Rust, or anything elseManual instrumentation with the OpenTelemetry SDK
Need help wiring this into your stack?Bring traces and evals into the tools your team already usesTalk to an expert

Last updated on

Built byConfident AI