- Create production sessions from real traffic. Uncorrelated spans become production Sessions that Monitors evaluate automatically. Spans that name a test case become a non-production session instead, which no Monitor scores. See Monitor Real User Traffic via OpenTelemetry.
- Enrich existing Galtea Traces. Spans correlated to a Trace become Span records on it. Correlation uses the shared trace ID from the
traceparentheader Galtea propagates during Direct Inference, or the explicitgaltea.trace.idspan attribute. Galtea also sends that attribute’s value in thebaggageheader of each conversation turn call, so your agent can copy it onto its spans. See W3C Trace Context Propagation.
Endpoint and authentication
Configure your OTel exporter to send traces to the Galtea collector. Every request must carry anAuthorization: Bearer <Galtea-API-key> header — without it, the gateway returns 401 Unauthorized before the request reaches the collector.
All examples below use the Galtea platform hostname: otel.platform.prod-main.galtea.ai.
Using a dedicated tenant deployment?
Using a dedicated tenant deployment?
If your organization has a private Galtea deployment, replace the hostname with your tenant-specific endpoint:Your Galtea account team will provide the exact hostname during onboarding.
Configure your exporter
- Environment variables
- Python code
- OTel Collector
The OpenTelemetry SDK reads endpoint and headers from environment variables. Use shell substitution to expand The same
${GALTEA_API_KEY} before the value is stored in OTEL_EXPORTER_OTLP_TRACES_HEADERS:- HTTP (port 4318)
- gRPC (port 4317)
${GALTEA_API_KEY} syntax works in a docker-compose.yml environment: block, but only when GALTEA_API_KEY is set in the shell that runs Compose or in a .env file Compose loads. Docker Compose substitutes ${...} from those sources when it renders the config. It does not read another entry in the same environment: block. If the variable is unset there, the exporter receives the literal string ${GALTEA_API_KEY} and the gateway returns 401 Unauthorized.Use
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT (the per-signal variant), not OTEL_EXPORTER_OTLP_ENDPOINT. The base variable auto-appends /v1/traces to the URL, but the Galtea collector expects the /otel/traces path.Verify your key and endpoint
A quick way to confirm the header is being applied correctly is to POST an empty payload and inspect the status code:How span content maps to Span records
When a span becomes a Span record — whether it enriches an existing trace or is assembled into a production conversation — its input and output are filled per field, using the first source that provides a value:galtea.span.*explicit attributes — full control, always wins.gen_ai.*GenAI semantic conventions — the OpenTelemetry standard for LLM telemetry.- Recognized managed-platform span shapes — platform-specific formats Galtea knows.
- A configured span-source rule —
otelInputSourceRuleorotelOutputSourceRuleon the Version, the Product, or the organization, which reads the field out of a named non-LLM span. See Recover the turn input from a non-LLM span.
metadata, under the key galtea.span.original_type.
The span type follows its own order, because only galtea.span.type is a Galtea attribute:
galtea.span.type— always wins.- The span kind your platform already declares — MLflow’s
mlflow.spanType, or a span shape that names the kind by itself. gen_ai.operation.name— the OpenTelemetry GenAI operation, such aschatorembeddings.SPAN— when nothing above names a kind.
RETRIEVER span becomes a RETRIEVER span, which is what Galtea reads retrieval context from. A vendor word Galtea spells differently still maps, so MLflow’s LLM becomes GENERATION.
These keys had different names before version 5.0.0, and Galtea still reads the old ones. See
Dataset, Trace, and Span Renames if your collector already
sends them.
- Galtea span attributes
- OTel GenAI conventions
- Managed platforms
span.name→namestartTimeUnixNano/endTimeUnixNano→startTime/endTime+latencyMs(computed)span.status→error(fallback whengaltea.span.erroris not set; only forSTATUS_CODE_ERROR)parentSpanId→parentTraceId(parent-child hierarchy)
metadata field, so no data is lost.
Token usage and cost
Galtea reads the token counts your spans report and adds them up per turn. Send them with the OpenTelemetry GenAI keys:
A turn’s
inputTokens, outputTokens and tokens are the sum over every span of that turn, so a turn that makes three LLM calls reports the three calls added together. A span that reports no usage adds nothing. Send no usage at all and the turn keeps what Galtea already had: nothing when no Model is linked to the Version, or the estimate Galtea derived from the turn text when one is.
Galtea also recognizes the usage a managed platform reports in its own format. MLflow Tracing’s mlflow.chat.tokenUsage works with no Galtea attribute. When a span carries both, the gen_ai.usage.* keys win, field by field.
Cost is derived from those counts and the per-token price of the Model linked to the Version. Link a Model with a known price and the turn’s cost is filled. With no Model, or with no price for it, cost stays empty rather than zero.
A reported count replaces one Galtea estimated earlier: your own figure is the accurate one. A cost you reported yourself is kept, and the new counts do not replace it: Galtea recomputes only a cost it derived from the counts and the Model price, never a different figure you set. Spans of a turn may arrive in several export batches, and each batch raises the turn’s total instead of replacing it. Re-sending the same spans changes nothing.
Retrieval context (RAG): to record what your system retrieved, type a span as
RETRIEVER and put the retrieved data in its output (for example via galtea.span.output). This is how Galtea reads retrieval context: it is derived from your RETRIEVER spans, and the output has no required shape.Attributes that route a conversation
The keys above fill a Span record. The keys below decide which session Galtea assembles the spans into. They apply to uncorrelated spans only, so a span already linked to a Trace ignores them.
Name the version in one of three ways.
galtea.version.id points at a Version you already created. galtea.product.id plus the galtea.version.fact.<key> attributes describe the agent state instead. The third way sends no galtea.version.fact.* attributes. It sends the standard attributes that your organization or product lists as version attributes, and Galtea builds the facts from them. Either of the last two ways can drop galtea.product.id and send the product key attributes instead. In the last two ways Galtea finds or creates the matching Version with the rules of Get or Create Version: the same facts reuse one Version, and one changed value creates a new one. The route follows the first present of galtea.version.id, galtea.version.fact.*, and the version attributes, so a resource that sets more than one is read by the first. Its later attributes are ignored. When a resource has galtea.product.id and the key attributes, galtea.product.id wins. Monitor Real User Traffic via OpenTelemetry shows each setup.
Galtea rejects the uncorrelated spans of a resource, while the rest of the payload still ingests, when it sends fact attributes, or attributes your organization lists as version attributes, with no usable galtea.product.id and its resource attributes route to no single product of your organization (no product has those key values, or two products with keys of the same size do), when the facts are not valid, whether sent as fact attributes or built from the version attributes (a value that is not text or an integer, more than 32 keys, or more than 2000 bytes in all), or when the product does not exist in your organization. The last case also covers an API key whose role cannot create a Version when no Version holds the facts yet.
Galtea rejects one conversation, while the rest of the payload still ingests, when the test case does not exist, when it belongs to another product than the version, when two spans of one conversation name different test case IDs or two resources do, or when the conversation key already holds another session on that version. Galtea also rejects a span whose trace ID matches a Direct Inference turn that was removed. It does not assemble that span into a new session. Those spans are counted in the export response’s partialSuccess.rejectedSpans. The response’s partialSuccess.errorMessage names the reason that applied, so your collector log says what to change.
Monitor Real User Traffic via OpenTelemetry walks through the full setup.
Learn More
Monitor Real User Traffic via OpenTelemetry
Turn your live traffic’s traces into production sessions that Monitors evaluate.
W3C Trace Context Propagation
Attach OTel spans to the test runs Galtea triggers via Direct Inference.