Skip to main content
Version: Latest (main)

Router Headers

The Router reads and writes the headers below: a public set on its responses, a debug trace, the request headers clients send, and internal headers no client sees. This reference is generated from the Router's header registry, src/semantic-router/pkg/headers; run make headers-generate after changing it. Header names are case-insensitive.

Who sees which headers​

SurfaceHeadersWho sees them
publicResponse headersEvery client, on each response a header applies to.
debugx-vsr-traceOnly a caller global.router.headers.debug allows, on a request that asks with x-vsr-debug: true.
controlRequest headersSent by clients to steer or identify a request.
internalInternal headersNo client: they pass between the Router, the gateway and authenticator in front of it, and providers, and no response the Router writes carries them.

Hops name where a header travels: request (client to Router), response (Router to client), provider request (Router to provider) and provider response (provider to Router). A header reaches a provider only when its hops include provider request, as Reaches providers shows for the request headers; the Router removes the others from every provider-bound request. Since is the release the header first shipped in.

Response headers​

Every response of the routing pipeline carries the headers that apply to it: answers from the upstream model, response-cache hits, and the responses the Router produces itself, such as a block, a fast response or a routing error. Responses of the Router's own handlers, such as GET /v1/models, carry x-vsr-config-version only.

HeaderSinceDescription
x-vsr-schema-versionv0.4Response-header contract revision; currently 3.
x-vsr-response-pathv0.4How the response was produced: upstream, cache, fast_response, looper, blocked, rate_limited, error or fallback.
x-vsr-config-versionv0.5Version of the configuration snapshot that served the request.
x-vsr-config-hashv0.4SHA-256 of the active runtime document, on routing previews and GET /api/v1/config.
x-vsr-warningsv0.5Warnings about the response, as an RFC 8941 list: scan_partial when a request-stage guard rule read only part of a long input, guard_overloaded on the retryable error answered instead of a refusal or a forward that rules unread on an overloaded decision runtime decide, the codes of the response_guard rules that annotated the answer, then each protocol translation loss with its action, reason and field.
x-vsr-selected-recipev0.4Recipe the effective entrypoint selected; omitted for concrete backend models.
x-vsr-selected-decisionv0.1Decision the decision engine selected; omitted when no decision matched.
x-vsr-selected-modelv0.1Model alias the Router selected.
x-vsr-replay-idv0.2Router Replay record id, when the record was persisted.
x-vsr-costv0.4Usage priced with the served model's configured pricing; buffered responses only.
x-vsr-cost-currencyv0.4Currency of x-vsr-cost, from pricing.currency.
x-ratelimit-limitv0.2Limit of the rate-limit window that rejected the request.
x-ratelimit-remainingv0.2Requests left in that window.
x-ratelimit-resetv0.2Unix time the window resets at.
x-request-idv0.1Request correlation id, forwarded to providers; the native gateway adds one when absent, and the management API echoes it.
x-content-type-optionsv0.4nosniff on Router Replay management responses.
x-envoy-upstream-service-timev0.5Envoy's upstream time on responses in Envoy mode; gateway-parity checks ignore its value.
x-envoy-overloadedv0.5true on the 503 a full circuit breaker returns, as Envoy sets it.

A response that answered from the upstream model:

HTTP/1.1 200 OK
content-type: application/json
x-vsr-schema-version: 3
x-vsr-config-version: 7
x-vsr-response-path: upstream
x-vsr-selected-recipe: default
x-vsr-selected-decision: complex-request
x-vsr-selected-model: reasoning-model
x-vsr-replay-id: replay_01J...
  • Read x-vsr-schema-version before parsing the other headers; the current value is 3. Responses of the Router's own handlers never carry it, so its absence there is expected.
  • A request keeps the configuration version it started on, even when a hot reload activates another one while it runs. x-vsr-config-version counts the activations of one Router, which keeps its own configuration history; to check that replicas serve the same configuration, compare the active_runtime_hash that GET /api/v1/config/hash reports.
  • Recipe names scope local signal, projection, decision, cache, replay, metric, and learning or session identities. Use x-vsr-selected-recipe together with the local decision and signal names when correlating a response with Insights or metrics.

The trace​

HeaderSinceDescription
x-vsr-tracev0.5Routing details as an RFC 8941 dictionary of at most 4 KB, for a caller global.router.headers.debug allows.

x-vsr-trace carries what else the Router knows about a request, such as the matched signals, the decision's confidence and the algorithm. It is an RFC 8941 dictionary of at most 4096 bytes, whose members are omitted when they don't apply. A string percent-encodes % and every byte outside printable ASCII, so decode it after unquoting. When the encoded trace would exceed 4096 bytes, the Router leaves out members from the lowest priority up and ends the dictionary with truncated.

x-vsr-trace: confidence=0.91, algorithm=static, routing_latency_ms=3.2, signals=("context:long-context" "projection:use-reasoning-model"), session_phase=tool_loop

Who may turn on the trace​

The trace names the signal and guard rules a request matched, the decision ranking and the Router Learning reasons, so a client can't turn it on by itself. A client asks for it with x-vsr-debug: true, and global.router.headers.debug decides who may; the Router ignores x-vsr-debug from everyone else.

debugWho gets the trace
none (default)Nobody.
anyEvery client that sends x-vsr-debug: true. Use it for development and tests, or behind a gateway that removes the header from untrusted clients.
authenticatedOnly the users and groups in debug_principals, as the identity headers your authenticator sets assert them (global.services.authz.identity).
global:
router:
headers:
debug: authenticated
debug_principals:
users: [oncall-bot]
groups: [platform-sre]

authenticated trusts the identity headers. A standalone Router keeps them only on a listener with identity.trust_headers, and refuses authenticated when no listener trusts them. Behind an Envoy-based gateway, the gateway must remove the identity headers that clients send. The Dashboard Playground, vllm-sr route probe and sr-bench ask for the trace; when the caller isn't allowed, they show the public set only.

Members​

Highest priority first:

MemberOwnerDescription
config_hashbenchmarkSHA-256 of the runtime document that served a config-bound evaluation request.
inference_callsbenchmarkProvider calls a config-bound evaluation request made.
model_usagebenchmarkPer-model usage receipt of a config-bound evaluation request, as JSON.
confidenceroutingModel-derived score of the selected decision, such as 0.91.
algorithmroutingSelector or executor that chose the model after the decision matched, such as static.
routing_latency_msroutingTime spent choosing the model, in milliseconds.
fallback_attemptsfallbackAttempts cross-model fallback made, the primary included, when a fallback candidate served the response.
on_unknownroutingDecisions whose unknown result rules.on_unknown resolved, each with its policy.
client_protocolprotocolClient wire protocol, such as anthropic.
upstream_protocolprotocolProvider wire protocol, such as openai.
effective_input_tokensautomatic_outputRendered input tokens of the final automatic-output dispatch, chat template included.
effective_max_output_tokensautomatic_outputOutput token limit of the final automatic-output dispatch, reasoning included.
signalssignalsMatched signal rules as type:name, and type:rule:option for a choice rule without labels; projections are projection:name.
scan_coveragesignalsGuard rules that read their input in windows, as type:name with coverage (full, partial or none) and, for partial, the read and windows counts.
context_tokenssignalsToken count the context signal measured.
categoryclassificationDomain category the classifier chose, such as math.
reasoningclassificationReasoning mode chosen for the request: on or off.
modalityroutingOutput kinds of the selected decision's output contract, such as (image) or (text image); omitted for a decision that declares none.
system_promptsystem_promptPresent when a system_prompt plugin injected text into the request.
cache_similarityresponse_cacheSimilarity score of the response-cache lookup.
retentionretentionThe matched decision's retention directive: the drop, ttl_turns, keep_current_model and prefer_prefix it sets.
prompt_cacheprompt_cacheOutcome of the prompt_cache plugin, with its reason and the inserted and preserved marker counts.
toolstoolsOutcome of the tools plugin's selection, with its candidates, kept and latency_ms.
response_guardresponse_guardOutcome of the selected decision's response_guard, such as blocked, with buffered when the Router held a streamed answer until the guard read it.
session_phaserouter_learningProtection phase: user_turn, tool_loop or provider_state.
learningrouter_learningRouter Learning methods, each with its action, scope and reason.
looperlooperModels the Looper called, with its algorithm, final model, iterations, latency_ms and token counts.
rankingroutingThe matched decision the selected one beat, with the reason that settled it.
truncatedresponse_contractPresent when members were left out to keep the trace within 4 KB.
  • confidence is absent when the decision rests on policy leaves, aggregates several evidence leaves, resolves through an error policy, or is a catch-all.
  • fallback_attempts counts the same way in both gateway modes and is omitted when the primary answered.
  • ranking is omitted when only one decision matched; parse decision_ranking in Router Replay for the full ranking.
  • learning lists the Router Learning methods with their action. Show the actions as user-facing phrases such as tool/protocol pinned, model switched, or learning bypassed; fresh conversation or session-start diagnostics are usually useful only in debug views, as neutral status text.
  • effective_input_tokens and effective_max_output_tokens appear together on a successful upstream response when automatic output was resolved, in the initial headers of streaming and buffered responses alike. Explicit output limits, cache hits, skipped processing, and Looper responses omit them. Their values come from the final dispatch after request changes and backend rendering; they are not estimates or the model's configured maximum context length.
  • config_hash, inference_calls and model_usage are the receipts of a config-bound evaluation request, one sent with x-vsr-bench-expected-config-hash.
  • retention shows the fields a matched decision's retention directive set, so operators can verify policy wiring; clients should not use them as commands.
  • prompt_cache is content-free: it reports counts and outcomes, never the cached text itself, and it never claims a cache hit or provider-side savings.

Projection scores and full projection traces stay in the Router Replay record rather than the trace. Use x-vsr-replay-id to inspect them in the Dashboard or through the authenticated Router management API; public inference listeners do not serve replay records.

Warnings​

x-vsr-warnings is an RFC 8941 list of warning codes, omitted when none applies. The codes of the response_guard rules that annotated the answer come first, in rule order, then the protocol translation losses. Per-warning detail, such as hallucination spans or jailbreak confidence, stays in the replay record.

CodeMeaning
scan_partialA request-stage guard rule (jailbreak, safety or pii) read only some of a long input's windows, or none, and the request was routed on what it read.
hallucinationA response_guard rule over a hallucination signal flagged the answer.
unverified_factualThe answer was factual, but a hallucination rule had no context to check it against.
response_jailbreakA response_guard rule over a response-stage jailbreak signal flagged the answer.
response_guardA response_guard rule over any other signal flagged the answer.
protocolProtocol translation changed or dropped part of the request, with its action, reason and field.
truncatedProtocol warnings left out to keep the header within 4 KB, with their count.

Request headers​

Clients send these to steer or identify a request. See Session identification for how the Router picks the session a request belongs to.

HeaderReaches providersSinceDescription
x-vsr-session-idnov0.5Session id the client pins; without it the Router reads the headers global.router.headers.session_id_headers names, in order.
x-session-idyesv0.3Client session id session_id_headers accepts by default; providers receive it.
x-claude-code-session-idyesv0.3Conversation id Claude Code sends, which session_id_headers accepts by default after x-session-id; providers receive it.
x-conversation-idyesv0.4Client conversation id; Router Learning scope: conversation protects it, and providers receive it.
x-vsr-memorynov0.5off keeps Router-managed memory out of the request.
x-vsr-skip-processingnov0.3true opts the request out of Router processing when global.router.skip_processing.enabled is set.
x-vsr-debugnov0.4true asks for x-vsr-trace on the response; honored only for a caller global.router.headers.debug allows.
x-vsr-cache-controlnov0.4Response-cache directives for the request, when the plugin's request_controls allow them.
x-vsr-compression-controlnov0.4Context-compression directives for the request, when the plugin's request_controls allow them.
x-vsr-protection-releasenov0.5Any non-empty value asks router-learning protection for a fresh decision on the request's protection key; global.router.learning.protection.release.header can rename it.
x-vsr-bench-expected-config-hashnov0.5Configuration hash an evaluation request requires; another active configuration fails it with 412.
x-vsr-bench-max-inference-callsnov0.5Provider-call limit of an evaluation request; only 1 is supported.

Internal headers​

These pass between the Router, the gateway and authenticator in front of it, and providers. They are not part of the client contract, and no response the Router writes carries them. The Router drops a client's value of every x-vsr- header except the request headers above and x-vsr-delegated-credential, which the gateway in front must strip from clients, and drops every x-vsr- header a provider returns.

Identity​

These name an authenticated caller. A listener that doesn't trust identity headers drops the ones a client sends (see Gateway modes), and no identity header reaches a model provider.

HeaderSinceDescription
x-authz-user-idv0.2Authenticated user id; identity.user_id_header names another header.
x-authz-user-groupsv0.2Authenticated user's groups, comma-separated; identity.user_groups_header names another header.
x-authz-team-idv0.4Authenticated team id; partitions the response cache.
x-authz-tenant-idv0.4Authenticated tenant id; partitions the response cache.
x-vsr-outcome-principalv0.4Opaque attested identity that isolates outcome-ingest rate limits; never persisted.

Credentials​

Credentials, by name only. None reaches a client, and a provider receives only the credential its auth sets: a per-user key only as that credential, and never a client's own credential header.

HeaderHops
x-user-openai-keyrequest
x-user-anthropic-keyrequest
x-user-azure-openai-keyrequest
x-user-bedrock-keyrequest
x-user-gemini-keyrequest
x-user-vertex-ai-keyrequest
x-user-minimax-keyrequest
x-user-cloudflare-workers-ai-keyrequest
x-vsr-delegated-credentialrequest
x-vsr-internal-authrequest
authorizationrequest, provider request
api-keyrequest, provider request
x-api-keyprovider request
x-goog-api-keyprovider request
api-subscription-keyprovider request
ocp-apim-subscription-keyprovider request

Routing and transport​

HeaderHopsSinceDescription
x-vsr-route-modelrequest, provider requestv0.5Route key: the model whose route the gateway sends the provider request on; the Router drops a client's value and sets its own.
x-vsr-upstream-hostprovider responsev0.5Endpoint Envoy reports on the provider response for KV registry writes; removed before the client.
x-vsr-kv-source-podprovider requestv0.4Address of the pod that holds the source model's KV cache.
x-vsr-kv-cache-idprovider requestv0.4Opaque id of the source KV block.
x-vsr-kv-mapper-idprovider requestv0.4Mapper artifact for the source and target model pair.
x-vsr-systemone-backendrequest, provider requestv0.5Marks a System One request one Router forwards to another, which refuses to forward it again.
x-vsr-outcome-sourcerequestv0.4Outcome provenance a trusted control plane attests to the management API.
x-forwarded-forrequest, provider requestv0.5Client address chain; the native gateway's access log records it, and providers receive it.
x-forwarded-protorequest, provider requestv0.5Scheme of the client connection; the native gateway sets it when absent, as Envoy does.
x-envoy-upstream-rq-timeout-msrequest, provider requestv0.5Route timeout the Router sets from the decision's reliability block.
x-envoy-upstream-rq-per-try-timeout-msrequest, provider requestv0.5Per-try timeout the Router sets from the decision's reliability block.
x-envoy-max-retriesrequest, provider requestv0.4Retry count the Router sets from the decision's reliability block, and 0 on evaluation requests.
x-envoy-retry-onrequest, provider requestv0.5Retry conditions the Router sets from the decision's reliability block.
x-envoy-retriable-status-codesrequest, provider requestv0.5Retriable status codes the Router sets from the decision's reliability block.
x-envoy-hedge-on-per-try-timeoutrequest, provider requestv0.4false on evaluation requests, so a per-try timeout never hedges.
x-envoy-internalrequestv0.5Envoy's internal-request marker; the edge drops it from client requests.
x-envoy-retriable-header-namesrequestv0.5Envoy retry control; the edge drops it from client requests.
x-envoy-retry-grpc-onrequestv0.5Envoy retry control; the edge drops it from client requests.
x-envoy-upstream-alt-stat-namerequestv0.5Envoy stats control; the edge drops it from client requests.
x-envoy-upstream-rq-timeout-alt-responserequestv0.5Envoy timeout control; the edge drops it from client requests.
x-envoy-expected-rq-timeout-msrequestv0.5Envoy timeout control; the edge drops it from client requests.
x-envoy-force-tracerequestv0.5Envoy tracing control; the edge drops it from client requests.
x-envoy-ip-tagsrequestv0.5Envoy IP tagging control; the edge drops it from client requests.
x-envoy-original-urlrequestv0.5Envoy redirect control; the edge drops it from client requests.
x-envoy-ratelimitedprovider responsev0.5Marks a provider response an Envoy rate limit rejected; the native upstream can retry it.