Step 1: Get your OTLP endpoint and credentials
Set up your OpenTelemetry-compatible backend and obtain the OTLP traces endpoint URL along with any required authentication headers. For Axiom:- Create an Axiom account and dataset
- Go to Settings > API Tokens and create a new token
- Your endpoint is
https://api.axiom.co/v1/traces - You’ll need headers:
Authorization: Bearer xaat-xxxandX-Axiom-Dataset: your-dataset
- Deploy an OpenTelemetry Collector with an OTLP receiver
- Configure the receiver to listen on a publicly accessible endpoint
- Note the endpoint URL (typically ending in
/v1/traces)
Step 2: Enable Broadcast in OpenRouter
Go to Settings > Observability and toggle Enable Broadcast.
Step 3: Configure OpenTelemetry Collector
Click the edit icon next to OpenTelemetry Collector and enter:- Endpoint: Your OTLP traces endpoint URL (e.g.,
https://api.axiom.co/v1/tracesorhttps://your-collector.example.com:4318/v1/traces) - Headers (optional): Custom HTTP headers as a JSON object for authentication
Step 4: Test and save
Click Test Connection to verify the setup. The configuration only saves if the test passes.Step 5: Send a test trace
Make an API request through OpenRouter and view the trace in your OpenTelemetry backend.Compatible backends
The OpenTelemetry Collector destination works with any backend that supports OTLP over HTTP, including:- Axiom - Cloud-native log and trace management
- Jaeger - Distributed tracing platform
- Grafana Tempo - High-scale distributed tracing backend
- Honeycomb - Observability for distributed systems
- Lightstep - Cloud-native observability platform
- Self-hosted OpenTelemetry Collector - Route traces to multiple backends
Custom Metadata
Custom metadata from thetrace field is sent as span attributes in the OTLP payload. How this metadata appears depends on your downstream backend.
Supported Metadata Keys
Example
Span Attributes
Custom metadata keys are included as span attributes under thetrace.metadata.* namespace. For example, environment from the trace field becomes trace.metadata.environment in the OTLP payload.
Standard GenAI semantic conventions (gen_ai.*) are used for model, token usage, and cost attributes.
Additional Context
- The
userfield maps touser.idin span attributes - The
session_idfield maps tosession.idin span attributes - Your downstream backend determines how these attributes are indexed, queried, and displayed
- Using
parent_span_idlets you link OpenRouter traces to your application’s existing distributed traces
Billing quantities
Cache-write details are exported as numeric attributes on the generation span:
With Cost enabled under Additional generation metadata, the same quantities and native-tool counters are also queryable under
span.metadata.openrouter_generation.*. For example:
intValue and the estimate flag as boolValue. Root spans also carry generation metadata under trace.metadata.openrouter_generation.*. Read each generation once. These representations repeat the same generation quantities; do not add them together. Unavailable quantities are omitted from OTEL attributes, while zero and false are preserved. See Token and cost fields for interpretation and billing caveats.
Raw provider usage
Unlike the quantities above,upstream_raw_response_usage is not flattened into one attribute per provider field. It is sent as a single stringValue attribute holding JSON, because its keys are provider-controlled and can change without notice:
null — which is sent as the four-character string null, distinct from the attribute being absent. When it decodes to null, upstream_raw_response_usage_suppression_reason says whether the value was suppressed or simply unavailable.
This attribute keeps its path even when a generation carries more ordinary metadata than fits in the attribute budget. Because collectors and backends impose their own attribute value length limits, verify that your pipeline stores the complete JSON string before relying on it.
Privacy Mode
When Privacy Mode is enabled for this destination, prompt and completion content is excluded from traces. All other trace data — token usage, costs, timing, model information, and custom metadata — is still sent normally. Raw provider usage is replaced withnull and reported as privacy_mode, because a provider’s usage object can contain arbitrary future fields. See Privacy Mode for details.