OpenTelemetry
If your app already emits OpenTelemetry traces, Metrx can read its LLM spans directly: point an OTLP/HTTP exporter at the Metrx receiver.
| Value | |
|---|---|
| Endpoint | https://gateway.metrxbot.com/v1/traces |
| Protocol | OTLP/HTTP, JSON encoding only |
| Auth header | Authorization: Bearer <METRX_API_KEY> (keys start with sk_live_) |
| Spans per request | At most 100 LLM spans; extra spans are reported back as rejectedSpans, so set the batch size to 100 |
| Body size | At most 1MB per request |
Direct protobuf is not supported yet. A request with a protobuf body is refused with 415 OTLP_PROTOBUF_UNSUPPORTED, and gRPC is not accepted. Exporters that can only send protobuf (Python’s, among others) go through an OpenTelemetry Collector, below.
Node.js: environment variables only
Node’s OTLP/HTTP exporter can send JSON, so environment variables are enough. In an OTel header value the space after Bearer is percent-encoded as %20:
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="https://gateway.metrxbot.com/v1/traces"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/json"
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer%20${METRX_API_KEY}"
export OTEL_RESOURCE_ATTRIBUTES="service.name=refund-triage"
export OTEL_BSP_MAX_EXPORT_BATCH_SIZE="100"Then install the auto-instrumentations and load them when the app starts:
npm install @opentelemetry/api@1.9.1 @opentelemetry/auto-instrumentations-node@0.81.2 openai@6.49.0
node --require @opentelemetry/auto-instrumentations-node/register app.jsThe OpenAI instrumentation records spans for openai 4.19 to 6.x only. With openai 7 it records nothing and reports no error, so the install pins openai@6.49.0.
Calls are recorded under the agent key in the span or resource attribute metrx.agent_key when present, else under service.name. Each trace is one task unless a span carries metrxbot.task_id.
Python and other protobuf exporters: through a Collector
Python’s OTLP/HTTP exporter has no JSON encoding: asking it for http/json fails with Unsupported OTLP protocol 'http/json'. Run an OpenTelemetry Collector next to the app. It receives protobuf or gRPC from the app and re-encodes the traces to JSON for Metrx:
# otel-collector.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
send_batch_size: 100
send_batch_max_size: 100
exporters:
otlphttp/metrx:
traces_endpoint: https://gateway.metrxbot.com/v1/traces
encoding: json
compression: none
headers:
Authorization: "Bearer ${env:METRX_API_KEY}"
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp/metrx]Start the Collector with METRX_API_KEY in its environment, then point the app at it:
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_SERVICE_NAME="refund-triage"The batch processor keeps each request to Metrx at or under the 100-span cap. The same Collector works for any SDK that only speaks protobuf or gRPC.
Errors
The receiver answers with the gateway’s error body, { error, code, hint, docs }. The codes you will see here are MISSING_API_KEY, UNAUTHORIZED, OTLP_PROTOBUF_UNSUPPORTED, PAYLOAD_TOO_LARGE and INVALID_JSON; Errors says what to do about each.