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-IDdel gateway, mai su un valore sotto il tuo controllo.
Quando qualcosa va storto
- Indica l'
X-Trace-Idinviato oppure l'X-Request-IDdella 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-Ide 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