There are three ways to get traces into Galtea. They use two endpoints: the REST Trace API and the public OTel endpoint (the OTLP collector).
- Galtea SDK — decorate your code with
@trace. The SDK posts to the REST Trace API. See Tracing Agent Operations. - OpenTelemetry export — send OTLP traces to the public OTel endpoint. This is what this page covers.
- REST API — create traces directly through the REST Trace API with your API key. Same endpoint the SDK uses.
What “OTel Compatible” Means
Galtea accepts standard OTLP traces (OTLP is the OpenTelemetry export protocol) at its collector endpoint. To configure your exporter or your own OTel Collector, follow Point your OTel exporter to the Galtea collector — the endpoint, authentication, and configuration are the same for everything on this page. Once spans arrive, each one takes exactly one of three paths:- Enrich an existing inference result. Spans correlated to an existing Inference Result become Trace records attached to it. Correlation happens through a shared W3C trace ID (when Galtea propagated a
traceparentheader during Direct Inference) or through an explicitgaltea.inference_result.idspan attribute. - Create a production conversation. Uncorrelated spans that carry both a conversation key and a product-version route are assembled into production Sessions with conversation turns. See Create Production Conversations from OTel Traces.
- Rejected. Uncorrelated spans missing a conversation key, a version route, or both are rejected. A span that names an inference result which does not exist (or is not visible to your API key) is also rejected; it does not fall back to conversation assembly. Galtea never guesses where your data belongs.
Before You Start: A One-Minute Eligibility Check
You can use this path if you can do at least one of the following:- Add
galtea.*attributes to your spans. You control the instrumentation code. - Set resource attributes on your own OTel Collector. This works even when the spans are emitted by a managed platform you cannot edit.
- Propagate a
traceparentheader Galtea mints. Available only with Direct Inference, where Galtea calls your endpoint. - Your platform already emits a recognized span shape. Either the OpenTelemetry GenAI semantic conventions or a supported managed-platform shape (see How Span Content Maps to Trace Records).
| Your situation | What works |
|---|---|
| You control the instrumentation and can add span attributes | Full control. Set the galtea.session.custom_id span attribute and the galtea.version.id resource attribute to create production conversations, and galtea.trace.* span attributes to fill each trace’s input and output. |
| A managed platform emits your spans and you cannot edit them, but you run your own OTel Collector | Set galtea.version.id once on the Collector as a resource attribute. If the platform is built on Temporal, the conversation key is derived automatically, and each turn’s input and output are read automatically from the platform’s span shapes (see How Span Content Maps to Trace Records). |
| Your service is OTel-instrumented and Galtea calls it via Direct Inference | Enable traceparent propagation on the endpoint connection. Your spans enrich the inference results Galtea creates. No Galtea attributes needed. |
| Your platform emits the OpenTelemetry GenAI semantic conventions | Input and output map automatically from the gen_ai.* spans, with zero Galtea-specific attributes — whether the spans enrich an existing inference result or are assembled into a new production conversation. To create new sessions you still need a conversation key and a version route. |
| None of the above | This path does not work for you yet. Use the Galtea SDK or the REST API instead. |
Create Production Conversations from OTel Traces
Galtea can assemble uncorrelated spans into full multi-turn production conversations. It needs two pieces of information: a conversation key (which spans belong to the same conversation) and a version route (which product version the conversation belongs to).Set a Conversation Key
The conversation key decides which spans belong to the same Galtea session. Provide it in whichever way fits your setup.- Your own session ID
- Managed platform (vendor-derived)
Set the
galtea.session.custom_id span attribute to your own conversation identifier, for example your chat session ID. Spans carrying it are grouped into one Galtea session per distinct ID. Within a session, one OTel trace (all spans sharing a W3C trace ID) becomes one conversation turn.Route to a Product Version
Assembly requires thegaltea.version.id resource attribute. It routes the spans to a Version of your product and is validated against the organization of the API key you authenticate with. Without it, uncorrelated spans are rejected.
A resource attribute describes the whole telemetry source, not a single span. So you can set it once on your own OTel Collector, even when a managed platform emits the spans and you cannot edit them:
What You Get
- Production sessions. Sessions created this way are production sessions, so Monitors evaluate them automatically.
- Automatic input and output. Each turn’s input and output are read from the turn’s own spans using the same per-field precedence as the enrichment path (
galtea.trace.*>gen_ai.*> managed-platform span shapes). A managed platform whose LLM text lives only ingen_ai.*attributes or vendor span events — with nogaltea.trace.*attributes — still produces turns with non-empty input and output. When a turn contains several LLM calls, the first prompt becomes the turn input and the last completion becomes the turn output. See How Span Content Maps to Trace Records. For turns answered without any LLM call (a templated or guardrail reply), see Recover replies that do not come from the LLM. - Idempotent ingestion. Re-sent or late span batches do not create duplicate sessions, turns, or traces. Later turns append to the same session.
- Works together with the SDK. If a session with the same custom ID already exists (for example, created by the SDK), ingestion attaches to it instead of creating a new one.
Two limits to plan for:
- Finished sessions reject new turns. A finished session still accepts late traces for its existing turns, but does not open new ones. To start new turns, begin a new conversation with a fresh
galtea.session.custom_id(or a new Temporal workflow). - One payload can open at most 100 new conversations. New sessions beyond that in the same OTLP payload are rejected (they appear in the export response’s rejected-span count). Continuations of conversations that already exist do not count toward the limit. If you send a large backfill or a high-volume export, split it across smaller export batches. Self-hosted deployments can raise the limit with the
OTEL_MAX_NEW_CONVERSATIONS_PER_PAYLOADsetting.
How Span Content Maps to Trace Records
When a span becomes a Trace record — whether it enriches an existing inference result or is assembled into a production conversation — its input and output are filled per field, using the first source that provides a value:galtea.trace.*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.
gen_ai.* forms:
gen_ai.input.messages/gen_ai.output.messages(the current semantic conventions)- the legacy
gen_ai.prompt/gen_ai.completionattributes - the GenAI content span events
galtea.trace.* attribute table and the automatically mapped OTel fields, see Controlling how spans map to Trace records.
Recover Replies That Do Not Come from the LLM
Some turns are answered without an LLM completion. A guardrail can replace the answer, a template can redirect the user, or a tool can return the final reply on its own. For these turns the user-visible answer lives on a non-LLM span. So by default the assembled turn output is empty, or it shows an internal label such as an intent-classifier tag, instead of the real reply. TheotelOutputSourceRule config field fixes this. It names the exact span and field that carry the real reply, so the turn shows the true answer. Set it on a Product or a Version. The Version value overrides the Product value. Leave it null (the default) to keep the rule off.
The rule has four parts:
spanName— the exact OTLP span name to match. For a Temporal (managed-platform) activity, this is the activity span name.attribute— the span attribute that holds the reply, stored as a JSON string.path— a JSONPath into that parsed JSON that points at the output text. JSONPath is a small query syntax for JSON, for example$[0].message.content.predicate(optional) — an object{ path, equals }. The rule applies only when the node atpredicate.pathequalsequals. Use it when the user message and the assistant message share the same span and attribute, so you do not pick the user’s own message as the reply.
ExecuteActivity:save_reply span, inside the app.arguments attribute, which holds a JSON array. $[0].message.content is the reply text inside that array. The predicate keeps user messages out: the same span also carries the user’s message with role "user", so the predicate makes the rule fire only for role "assistant".
This rule is a last resort. It fills only the turn output, and only when the turn has no LLM output. Galtea first tries the normal per-field sources (
galtea.trace.*, then gen_ai.*, then recognized managed-platform span shapes). The rule applies only if none of those produced an output. Within one turn, the latest span with output by start time wins. So the rule recovers the reply when the reply-bearing span is emitted after the LLM or classifier span. This is the common classify-then-reply order.otelOutputSourceRule on a product or a version. In the Python SDK you can set it when you create a version. The field is otel_output_source_rule, and you pass the same four-part object shown above. The SDK does not set it on products or on version updates. To set it on a product, or to change it on an existing version, use the API or the dashboard. The version value wins over the product value.
Learn More
Exporter and Collector setup
Configure your OTel exporter or Collector to send traces to Galtea.
Monitor
The always-on rule that evaluates your production sessions automatically.
Tracing Agent Operations
Collect traces with the Galtea SDK’s
@trace decorator.Trace
What a Trace record is and which properties it holds.