Header di richiesta

Tre header opzionali riconosciuti dal gateway: due portano il tuo contesto di tracing fino ai nostri log, uno mantiene una conversazione sullo stesso upstream perché il caching dei prompt continui a fare centro. Ometterli non cambia nulla.

Header Cosa fa il gateway A cosa serve
X-Trace-Id Restituito nella risposta e salvato sulla chiamata, che così viene raggruppata con le altre chiamate della trace. Collegare una chiamata al tuo sistema di tracing.
X-Span-Id Restituito nella risposta e salvato sulla chiamata; dà il nome alla chiamata nella cascata della trace. Identificare un singolo span in quella traccia.
X-Session-Id Restituito e salvato sulla chiamata. Richieste consecutive con lo stesso valore vengono fissate allo stesso canale e alla stessa chiave upstream. Mantenere caldo il caching dei prompt lungo una conversazione.
X-Request-ID Il tuo valore non viene adottato. Torna come X-Client-Request-ID; l'X-Request-ID della risposta è sempre lo UUIDv7 generato dal gateway. L'identità della chiamata lato gateway: citala in un ticket di supporto.

Come inviarli

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 che altri strumenti inviano già

Quando una chiamata non porta nessuno dei nostri tre header, il gateway legge l’header equivalente che un agente di coding, un SDK o uno standard di tracing invia già, quindi quelle esecuzioni vengono raggruppate in Trace senza modifiche da parte tua.

Header Letto come Inviato da
X-Claude-Code-Session-Id Sessione Claude Code
X-Litellm-Session-Id Sessione LiteLLM SDK, OpenHands
Session-Id Sessione OpenAI Codex CLI
Helicone-Session-Id Sessione Helicone
X-OpenWebUI-Chat-Id Sessione Open WebUI
X-Opencode-Session-Id Sessione OpenCode
baggage: session.id=… Sessione W3C Baggage (OpenTelemetry)
baggage: gen_ai.conversation.id=… Sessione W3C Baggage (OpenTelemetry)
baggage: langfuse_session_id=… Sessione Langfuse SDK
X-Session-Affinity Sessione OpenClaw, OpenCode, Kilo Code
X-Litellm-Trace-Id Trace LiteLLM SDK
X-Portkey-Trace-Id Trace Portkey
traceparent Trace; il suo parent id fa da 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 Utente finale (etichetta _user) Open WebUI
baggage: user.id=… Utente finale (etichetta _user) W3C Baggage (OpenTelemetry)
baggage: langfuse_user_id=… Utente finale (etichetta _user) Langfuse SDK

Se ci sono entrambi, vince sempre il nostro header. Session-Id e X-Codex-Turn-Metadata vengono letti solo dalla CLI di Codex e X-Interaction-Id solo da GitHub Copilot, riconosciuti dallo User-Agent. Una chiamata senza alcun ID di trace riceve l’ID di richiesta del gateway come X-Trace-Id.

Su /v1/chat/completions e /v1/responses, l’id di sessione può stare anche nel corpo, come session_id (con l’SDK OpenAI, in extra_body). Un header ha la precedenza, e il campo viene rimosso prima che la richiesta vada al provider.

OpenClaw invia traceparent a ogni chiamata al modello, quindi le sue esecuzioni vengono raggruppate in trace senza configurazione; per le sessioni, attiva compat.sendSessionAffinityHeaders sul modello. Open WebUI invia l’id della chat e quello dell’utente quando ENABLE_FORWARD_USER_INFO_HEADERS è attivo; le intestazioni con nome ed e-mail che li accompagnano non vengono lette. Un agente che non invia nulla di tutto questo (Cursor, Aider, Cline, Continue e la maggior parte dei framework per agenti) ha bisogno di X-Session-Id tra le intestazioni personalizzate.

W3C Trace Context e Baggage

traceparent fornisce la trace e, con il parent id, lo span; una strumentazione HTTP di OpenTelemetry lo aggiunge da sola. Il resto viaggia in baggage, con i nomi di OpenTelemetry: session.id o gen_ai.conversation.id per la sessione, gen_ai.agent.id e gen_ai.agent.name per l’agente, user.id per l’utente finale. Deve inserirli il tuo codice: un SDK OpenTelemetry non copia gli attributi degli span nel baggage. Il nome di un agente viene conservato come suo tipo e accetta lettere, cifre, ., _ e -. tracestate non viene letto.

Agenti all’interno di una sessione

Un agente di coding che avvia sub-agenti indica quale agente ha fatto ogni chiamata. Il gateway lo conserva insieme alla chiamata: così una sessione mostra il costo per agente, e una traccia mostra quali chiamate erano compattazioni o chiamate secondarie e quali strumenti sono stati eseguiti tra due chiamate. Nessuno di questi header cambia il routing: un sub-agente resta sull’upstream della sua sessione.

Header Letto come Inviato da
X-Agent-Id Agente Synthorai
X-Parent-Agent-Id L’agente o la sessione che lo ha avviato Synthorai
X-Claude-Code-Agent-Id Agente Claude Code
X-Claude-Code-Parent-Agent-Id L’agente o la sessione che lo ha avviato Claude Code
Thread-Id Agente OpenAI Codex CLI
X-Codex-Parent-Thread-Id L’agente o la sessione che lo ha avviato OpenAI Codex CLI
baggage: gen_ai.agent.id=… Agente W3C Baggage (OpenTelemetry)
X-Parent-Session-Id L’agente o la sessione che lo ha avviato OpenCode, Kilo Code
X-Opencode-Parent-Session-Id L’agente o la sessione che lo ha avviato OpenCode
X-Claude-Code-Request-Class Tipo di chiamata Claude Code
X-Claude-Code-Agent-Type Tipo di chiamata Claude Code
X-Claude-Code-Compaction Tipo di chiamata Claude Code
X-Claude-Code-Context-Compacted Tipo di chiamata Claude Code
X-Openai-Subagent Tipo di chiamata OpenAI Codex CLI
baggage: gen_ai.agent.name=… Tipo di chiamata W3C Baggage (OpenTelemetry)
X-Claude-Code-Prev-Tool-Durations Tempi di esecuzione degli strumenti Claude Code

Claude Code invia gli id di agente per impostazione predefinita. Il tipo di chiamata e i tempi di esecuzione degli strumenti vengono inviati solo se CLAUDE_CODE_GATEWAY_HINT_HEADERS=1 è impostato dove viene eseguito.

Conservato: gli id, il tipo di un agente, il tipo di chiamata e i nomi degli strumenti con i tempi di esecuzione in millisecondi. Non conservato: il nome che hai dato a un agente e tutto ciò che uno strumento ha letto o scritto.

Etichettare una richiesta

Invia X-Synthorai-Metadata con un oggetto JSON di stringhe per dire a cosa serviva una richiesta: una funzionalità, un ambiente, uno dei tuoi utenti. Le etichette compaiono sulla richiesta nei log, filtrano log, trace e sessioni (metadata.feature = checkout), vengono sommate in Analytics, Breakdown, ed escono con le tue esportazioni.

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"}]}'

Fino a 10 etichette. Una chiave ha da 1 a 32 caratteri tra a-z 0-9 _ . -; un valore è una stringa di al massimo 128 byte. _user indica l’utente finale per cui è stata fatta la richiesta; ogni altra chiave che inizia con un trattino basso è riservata. Un’etichetta che viola una regola viene scartata e la richiesta viene eseguita comunque: la risposta indica le chiavi scartate in X-Synthorai-Metadata-Dropped.

Le etichette vengono conservate con la richiesta per lo stesso tempo del log delle richieste, e il filtro per etichetta copre gli ultimi 90 giorni. Non inserirvi testo dei prompt, dati personali o segreti; un valore che sembra una credenziale viene salvato come [redacted]. Non vengono mai inviate al provider.

Affinità di sessione

Una voce di cache vive su una sola chiave API presso il provider. Un canale può avere più chiavi e, senza un indizio, il gateway distribuisce le chiamate tra queste: il secondo turno di una conversazione può finire su una chiave che non ha mai visto il tuo prefisso e ripagare il costo di scrittura.

Invia lo stesso valore a ogni chiamata di una conversazione e un valore diverso per un'altra conversazione. Nulla viene memorizzato lato server e nulla scade: il valore viene sottoposto ad hash per scegliere canale e chiave, quindi lo stesso valore risolve sempre allo stesso modo.

Sui due endpoint compatibili OpenAI - /v1/chat/completions e /v1/responses - puoi omettere l'header: se il corpo della richiesta contiene prompt_cache_key, il gateway lo usa come chiave di affinità. Su /v1/messages e sugli endpoint Gemini invia l'header.

L'affinità è best effort: decide solo quale canale scegliere tra candidati di pari rango. Failover, cooldown per rate limit, retry e una preferenza di routing esplicita hanno sempre la precedenza. Il prezzo di listino di un modello è lo stesso su ogni canale che possiamo scegliere.

Limiti

  • 128 byte ciascuno. I valori più lunghi vengono troncati. Un valore con caratteri di controllo o fuori dall'ASCII stampabile viene scartato del tutto: non restituito, non registrato. Questi valori finiscono in un header di risposta e in una riga di log, il che tiene fuori header e log injection.
  • Si fermano al gateway. Nessuno dei tre viene inoltrato al provider del modello: la richiesta in uscita porta solo autenticazione, content type e header specifici del provider.
  • Nessuno identifica una chiamata ai fini della fatturazione. Fatturazione, deduplicazione e riconciliazione si basano sull'X-Request-ID del gateway, mai su un valore sotto il tuo controllo.

Quando qualcosa va storto

  • Indica l'X-Trace-Id inviato oppure l'X-Request-ID della risposta: con uno dei due troviamo la chiamata esatta.
  • Il tuo trace ID compare sulla chiamata nei Log e in Trace, così puoi trovarla da solo prima di aprire un ticket.
  • Per verificare che l’affinità funzioni, invia più volte lo stesso prefisso lungo con un unico X-Session-Id e guarda le colonne della cache nei Log: la prima chiamata scrive nella cache, le successive dovrebbero leggerla. Cambia il valore e la scrittura dovrebbe ricomparire.

Vedi anche: Prompt Caching · Trace e sessioni