Skip to main content
Every gateway call the SDK helps you make carries grouping headers so related calls line up in your traces. Three objects nest, and each level defaults from the one above, so you only reach for the level your app needs. A turn’s headers(prompt?) returns the full bag: the tenant auth (x-to11-authorization, x-to11-project-id, and x-to11-env when the client has an env — otherwise the gateway routes on the project’s fallback env), the traceparent, the session and conversation ids, and — when you pass a rendered prompt — its provenance. It is a pure read of the turn’s fixed ids, so reuse it across a tool loop or call it per request; the result is the same. Apply it only to gateway requests; it carries the to11 key and must not go to a provider endpoint directly. Ids are generated and stable per object; pass your own to group by a business id (a user session, a chat thread). You view the grouped traces in the dashboard under Projects → Traces. The examples below assume:

One call

For a single call, create the turn inline. It uses the client’s default session and conversation.
Here to11.turn() mints a fresh traceparent — a brand-new trace for this one call — and borrows the client’s default session and conversation ids. headers(prompt) then stamps the request with the whole bag at once: the auth headers (x-to11-authorization, x-to11-project-id, and x-to11-env when set), the three grouping ids (x-to11-session-id, x-to11-conversation-id, traceparent), and the prompt’s provenance (x-to11-prompt-id, x-to11-prompt-version, plus release, variant, label, and slug when present). That provenance is what lets the trace in your dashboard show which prompt version produced the call.

A tool-use loop

When one turn makes several model calls (a tool loop), hoist the turn so every call reuses its headers — and therefore its traceparent — so the whole loop is one trace.
The turn is created once, so its traceparent is fixed for the whole loop. Reusing the same headers on every call keeps the first model call, each tool-result round-trip, and the final answer under one traceparent — they line up as a single turn in your traces. Create a turn inside the loop instead and every call would get its own traceparent, scattering one logical turn across unrelated traces.

A multi-turn chat

Call session.turn() once per user input. Every turn shares the session’s implicit conversation id, so the whole chat groups under one conversation, each turn its own trace.
Each session.turn() mints a fresh traceparent — one trace per user input — but hands back the session’s single implicit conversation id every time. So x-to11-conversation-id stays constant across the whole chat while traceparent changes each turn: the dashboard shows one conversation containing a trace per turn.

Multiple agents

Run several agents under one session by creating a conversation per agent. Each conversation has its own id and message thread; all share the session.
Each session.conversation() generates its own x-to11-conversation-id, and both carry the same x-to11-session-id. Every turn beneath them still gets its own traceparent. The result is one session holding two parallel conversations, each with its own traces — so you can tell the main agent’s work from the research agent’s while still seeing they belong to the same unit of work.

Without a managed prompt

You do not need a rendered prompt to use the gateway. Call turn.headers() with no argument to get auth, session, conversation, and trace headers, and supply your own model and messages.
Calling headers() with no argument injects the same auth headers and the same three grouping ids — just without the x-to11-prompt-* provenance, since there is no rendered prompt to attribute. You supply model and messages yourself, and the call is still authenticated, grouped, and traced exactly like the others.