Request-Header
Drei optionale Header, die das Gateway versteht: zwei tragen Ihren eigenen Trace-Kontext bis in unsere Logs, einer hält ein Gespräch auf demselben Upstream, damit Prompt Caching weiter greift. Ohne sie ändert sich nichts.
| Header | Was das Gateway tut | Wofür |
|---|---|---|
X-Trace-Id | Wird in der Antwort zurückgegeben und am Aufruf gespeichert, der so mit den anderen Aufrufen der Trace gruppiert wird. | Einen Aufruf Ihrem eigenen Tracing-System zuordnen. |
X-Span-Id | Wird in der Antwort zurückgegeben und am Aufruf gespeichert; er benennt den Aufruf im Wasserfalldiagramm der Trace. | Einen einzelnen Span innerhalb dieses Traces kennzeichnen. |
X-Session-Id | Wird zurückgegeben und am Aufruf gespeichert. Aufeinanderfolgende Requests mit demselben Wert werden an denselben Kanal und denselben Upstream-Key gebunden. | Prompt Caching über ein ganzes Gespräch hinweg warm halten. |
X-Request-ID | Wird nicht von Ihnen übernommen. Ihr Wert kommt als X-Client-Request-ID zurück; die X-Request-ID der Antwort ist immer die vom Gateway erzeugte UUIDv7. | Die Gateway-seitige Identität des Aufrufs - im Support-Ticket angeben. |
So senden Sie sie
curl https://synthorai.io/v1/chat/completions \
-H "Authorization: Bearer $SYNTHORAI_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Session-Id: conv-8f3a2b" \
-H "X-Trace-Id: 7c1d9e40f2b84a17" \
-H "X-Span-Id: 2f9b41c8" \
-d '{
"model": "claude-sonnet-5",
"messages": [{"role": "user", "content": "Hello"}]
}' Header, die andere Tools schon senden
Trägt ein Aufruf keinen unserer drei Header, liest das Gateway den entsprechenden Header, den ein Coding-Agent, ein SDK oder ein Tracing-Standard ohnehin sendet. So werden diese Läufe in Traces gruppiert, ohne dass Sie etwas ändern.
| Header | Gelesen als | Gesendet von |
|---|---|---|
X-Claude-Code-Session-Id | Session | Claude Code |
X-Litellm-Session-Id | Session | LiteLLM SDK, OpenHands |
Session-Id | Session | OpenAI Codex CLI |
Helicone-Session-Id | Session | Helicone |
X-OpenWebUI-Chat-Id | Session | Open WebUI |
X-Opencode-Session-Id | Session | OpenCode |
baggage: session.id=… | Session | W3C Baggage (OpenTelemetry) |
baggage: gen_ai.conversation.id=… | Session | W3C Baggage (OpenTelemetry) |
baggage: langfuse_session_id=… | Session | Langfuse SDK |
X-Session-Affinity | Session | OpenClaw, OpenCode, Kilo Code |
X-Litellm-Trace-Id | Trace | LiteLLM SDK |
X-Portkey-Trace-Id | Trace | Portkey |
traceparent | Trace; die Parent-ID gilt als Span | W3C Trace Context (OpenTelemetry) |
X-Claude-Code-Prompt-Id | Trace | Claude Code |
X-Interaction-Id | Trace | GitHub Copilot |
X-Codex-Turn-Metadata | Trace | OpenAI Codex CLI |
baggage: langfuse_trace_id=… | Trace | Langfuse SDK |
X-Portkey-Span-Id | Span | Portkey |
X-OpenWebUI-User-Id | Endnutzer (Label _user) | Open WebUI |
baggage: user.id=… | Endnutzer (Label _user) | W3C Baggage (OpenTelemetry) |
baggage: langfuse_user_id=… | Endnutzer (Label _user) | Langfuse SDK |
Sind beide vorhanden, gilt immer unser eigener Header. Session-Id und X-Codex-Turn-Metadata werden nur von der Codex CLI gelesen, X-Interaction-Id nur von GitHub Copilot, erkannt am User-Agent. Ein Aufruf ganz ohne Trace-ID bekommt die Request-ID des Gateways als X-Trace-Id zurück.
Bei /v1/chat/completions und /v1/responses kann die Sitzungs-ID auch im Body stehen, als session_id (mit dem OpenAI SDK in extra_body). Ein Header hat Vorrang, und das Feld wird entfernt, bevor die Anfrage an den Anbieter geht.
OpenClaw sendet traceparent bei jedem Modellaufruf, seine Läufe werden also ohne Einstellung zu Traces gruppiert; für Sitzungen aktivieren Sie compat.sendSessionAffinityHeaders am Modell. Open WebUI sendet Chat-ID und Nutzer-ID, sobald ENABLE_FORWARD_USER_INFO_HEADERS gesetzt ist; die mitgesendeten Header für Name und E-Mail werden nicht gelesen. Ein Agent, der nichts davon sendet (Cursor, Aider, Cline, Continue und die meisten Agenten-Frameworks), braucht X-Session-Id in seinen eigenen Headern.
W3C Trace Context und Baggage
traceparent liefert den Trace und mit seiner Parent-ID den Span; eine OpenTelemetry-HTTP-Instrumentierung setzt ihn von selbst. Alles Weitere steht in baggage, unter den Namen von OpenTelemetry: session.id oder gen_ai.conversation.id für die Sitzung, gen_ai.agent.id und gen_ai.agent.name für den Agenten, user.id für den Endnutzer. Ihr Code muss sie dort eintragen: Ein OpenTelemetry-SDK kopiert Span-Attribute nicht ins Baggage. Der Name eines Agenten wird als dessen Typ gespeichert und darf Buchstaben, Ziffern, ., _ und - enthalten. tracestate wird nicht gelesen.
Agents innerhalb einer Sitzung
Ein Coding-Agent, der Sub-Agents startet, gibt bei jedem Aufruf an, welcher Agent ihn gemacht hat. Das Gateway speichert das zusammen mit dem Aufruf: Eine Sitzung zeigt so ihre Kosten je Agent, und ein Trace zeigt, welche Aufrufe Komprimierungen oder Nebenaufrufe waren und welche Tools zwischen zwei Aufrufen liefen. Keiner dieser Header ändert das Routing: Ein Sub-Agent bleibt auf dem Upstream seiner Sitzung.
| Header | Gelesen als | Gesendet von |
|---|---|---|
X-Agent-Id | Agent | Synthorai |
X-Parent-Agent-Id | Der Agent oder die Sitzung, die ihn gestartet hat | Synthorai |
X-Claude-Code-Agent-Id | Agent | Claude Code |
X-Claude-Code-Parent-Agent-Id | Der Agent oder die Sitzung, die ihn gestartet hat | Claude Code |
Thread-Id | Agent | OpenAI Codex CLI |
X-Codex-Parent-Thread-Id | Der Agent oder die Sitzung, die ihn gestartet hat | OpenAI Codex CLI |
baggage: gen_ai.agent.id=… | Agent | W3C Baggage (OpenTelemetry) |
X-Parent-Session-Id | Der Agent oder die Sitzung, die ihn gestartet hat | OpenCode, Kilo Code |
X-Opencode-Parent-Session-Id | Der Agent oder die Sitzung, die ihn gestartet hat | OpenCode |
X-Claude-Code-Request-Class | Art des Aufrufs | Claude Code |
X-Claude-Code-Agent-Type | Art des Aufrufs | Claude Code |
X-Claude-Code-Compaction | Art des Aufrufs | Claude Code |
X-Claude-Code-Context-Compacted | Art des Aufrufs | Claude Code |
X-Openai-Subagent | Art des Aufrufs | OpenAI Codex CLI |
baggage: gen_ai.agent.name=… | Art des Aufrufs | W3C Baggage (OpenTelemetry) |
X-Claude-Code-Prev-Tool-Durations | Laufzeiten der Tools | Claude Code |
Claude Code sendet die Agent-IDs standardmäßig. Die Art des Aufrufs und die Laufzeiten der Tools sendet es nur, wenn dort, wo es läuft, CLAUDE_CODE_GATEWAY_HINT_HEADERS=1 gesetzt ist.
Gespeichert: die IDs, der Typ eines Agents, die Art des Aufrufs sowie Tool-Namen mit ihren Laufzeiten in Millisekunden. Nicht gespeichert: der Name, den Sie einem Agent gegeben haben, und alles, was ein Tool gelesen oder geschrieben hat.
Eine Anfrage mit Labels versehen
Senden Sie X-Synthorai-Metadata mit einem JSON-Objekt aus Strings, um anzugeben, wofür eine Anfrage gedacht war: ein Feature, eine Umgebung, einer Ihrer Nutzer. Die Labels stehen bei der Anfrage in den Logs, filtern Logs, Traces und Sessions (metadata.feature = checkout), werden unter Analytics, Breakdown summiert und gehen mit Ihren Exporten hinaus.
curl https://synthorai.io/v1/chat/completions \
-H "Authorization: Bearer $SYNTHORAI_API_KEY" \
-H 'X-Synthorai-Metadata: {"feature":"checkout","env":"prod","_user":"u_123"}' \
-d '{"model":"claude-sonnet-5","messages":[{"role":"user","content":"Hi"}]}' Bis zu 10 Labels. Ein Schlüssel besteht aus 1 bis 32 Zeichen aus a-z 0-9 _ . -; ein Wert ist ein String von höchstens 128 Bytes. _user benennt den Endnutzer, für den die Anfrage gestellt wurde; jeder andere Schlüssel, der mit einem Unterstrich beginnt, ist reserviert. Ein Label, das eine Regel verletzt, wird verworfen, die Anfrage läuft trotzdem: Die Antwort nennt die verworfenen Schlüssel in X-Synthorai-Metadata-Dropped.
Labels werden mit der Anfrage so lange aufbewahrt wie das Anfrageprotokoll; das Filtern nach Labels umfasst die letzten 90 Tage. Schreiben Sie keine Prompt-Texte, personenbezogenen Daten oder Geheimnisse hinein; ein Wert, der wie ein Zugangsdatum aussieht, wird als [redacted] gespeichert. An den Anbieter werden sie nie gesendet.
Session-Affinität
Ein Cache-Eintrag liegt auf genau einem API-Key beim Anbieter. Ein Kanal kann mehrere Keys halten, und ohne Hinweis verteilt das Gateway die Aufrufe darauf - der zweite Zug eines Gesprächs landet dann womöglich auf einem Key, der Ihr Präfix nie gesehen hat, und zahlt die Schreibkosten erneut.
Senden Sie bei jedem Aufruf eines Gesprächs denselben Wert und für ein anderes Gespräch einen anderen. Serverseitig wird nichts gespeichert und nichts läuft ab: Der Wert wird gehasht, um Kanal und Key zu wählen - derselbe Wert führt also immer zum selben Ziel.
An den beiden OpenAI-kompatiblen Endpunkten - /v1/chat/completions und /v1/responses - können Sie den Header ganz weglassen: Enthält der Request-Body prompt_cache_key, nutzt das Gateway diesen als Affinitäts-Key. An /v1/messages und den Gemini-Endpunkten senden Sie den Header.
Affinität ist Best Effort: Sie entscheidet nur, welcher Kanal unter gleichrangigen Kandidaten gewählt wird. Failover, Rate-Limit-Cooldown, Retries und eine explizite Routing-Vorgabe gehen ihr immer vor. Der Listenpreis eines Modells ist auf jedem Kanal gleich, den wir wählen können.
Grenzen
- Je 128 Byte. Längere Werte werden abgeschnitten. Ein Wert mit Steuerzeichen oder Zeichen außerhalb des druckbaren ASCII wird komplett verworfen - weder zurückgegeben noch geloggt. Diese Werte landen in einem Response-Header und einer Logzeile; das hält Header- und Log-Injection draußen.
- Sie enden am Gateway. Keiner der drei wird an den Modellanbieter weitergereicht - der ausgehende Request trägt nur Authentifizierung, Content-Type und anbieterspezifische Header.
- Keiner davon identifiziert einen Aufruf für die Abrechnung. Abrechnung, Deduplizierung und Abgleich hängen alle an der gateway-eigenen
X-Request-ID, nie an einem Wert, den Sie kontrollieren.
Wenn etwas schiefgeht
- Nennen Sie die gesendete
X-Trace-Idoder dieX-Request-IDaus der Antwort - mit beidem finden wir genau diesen Aufruf. - Ihre Trace-ID steht am Aufruf in den Protokollen und unter Traces, so finden Sie ihn selbst, bevor Sie ein Ticket eröffnen.
- Um die Affinität zu prüfen, senden Sie denselben langen Präfix mehrfach mit einer
X-Session-Idund sehen Sie sich die Cache-Spalten in den Protokollen an: Der erste Aufruf schreibt in den Cache, die folgenden sollten daraus lesen. Ändern Sie den Wert, sollte der Schreibvorgang wieder auftauchen.
Siehe auch: Prompt Caching · Traces und Sessions