What Information Is Available in the X-Routed-Via Header?
The X-Routed-Via response header reveals which provider platform and model actually processed a request, formatted as <platform>/<model> (e.g., groq/llama-3.3-70b-versatile), or returns cache when served from cache.
The X-Routed-Via header is a custom HTTP response header exposed by the FreeLLMAPI open-source project (tashfeenahmed/freellmapi) that provides transparency into request routing. When you send a request through this unified API gateway—especially with model auto-selection enabled—this header tells you exactly where your inference workload landed.
Header Format and Value Construction
The X-Routed-Via value follows a strict platform/model pattern constructed from the actual provider that served the request.
Platform and Model Identification
The value is assembled as:
<provider-platform>/<model-identifier>
For example: groq/llama-3.3-70b-versatile or openai/gpt-4o-mini.
This formatting is implemented in the response handlers across the codebase. In server/src/routes/responses.ts at line 28, the header is attached once the first meaningful output is ready to stream:
// From responses.ts - header set before streaming begins
res.setHeader('X-Routed-Via', routedViaValue(provider, model));
Similarly, server/src/routes/proxy.ts at line 23 handles this for generic proxy endpoints.
ASCII Sanitization and Percent-Encoding
Before placement in the HTTP header, the platform/model string undergoes mandatory sanitization to ensure HTTP header safety.
The routedViaValue function in server/src/lib/header-value.ts (line 52) processes the string through safeHeaderValue:
// header-value.ts - sanitization implementation
export function routedViaValue(platform: string, model: string): string {
const raw = `${platform}/${model}`;
return safeHeaderValue(raw); // Percent-encodes non-ASCII characters
}
Any non-ASCII characters in the platform or model name are percent-encoded to maintain header validity. For example, a model name containing Chinese characters would be encoded as %E6%88%91%E7%9A%84%E6%A8%A1%E5%9E%8B.
Cache Responses: A Special Case
When a request is served from the internal cache, the X-Routed-Via header returns a literal string rather than a provider identifier.
In server/src/routes/proxy.ts at line 75, cache hits trigger:
// proxy.ts - cache hit handling
res.setHeader('X-Routed-Via', 'cache');
This distinguishes cached responses from live inference calls, helping with debugging and cost attribution.
Reading the Header: Practical Examples
cURL Command
curl http://localhost:3001/v1/chat/completions \
-H "Authorization: Bearer <your-unified-key>" \
-H "Content-Type: application/json" \
-d '{"model":"auto","messages":[{"role":"user","content":"Hello"}]}' \
-i | grep X-Routed-Via
Sample output:
X-Routed-Via: groq/llama-3.3-70b-versatile
Fetch API (JavaScript/TypeScript)
fetch('http://localhost:3001/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${UNIFIED_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'auto',
messages: [{ role: 'user', content: 'Hello' }]
})
})
.then(res => {
const routedVia = res.headers.get('X-Routed-Via');
console.log('Routed via:', routedVia); // "groq/llama-3.3-70b-versatile"
return res.json();
});
Decoding Percent-Encoded Values
If your provider or model names contain unicode characters, decode them with:
const routedVia = 'groq/%E6%88%91%E7%9A%84%E6%A8%A1%E5%9E%8B';
const decoded = decodeURIComponent(routedVia);
console.log(decoded); // "groq/我的模型"
Timing: When the Header Appears
The X-Routed-Via header is added once the first meaningful output is about to be streamed. This timing is deliberate—it ensures the actual serving provider is known before any response body reaches the client.
- For streaming chat completions: Set in
responses.tsbefore the SSE stream begins - For proxy endpoints: Set in
proxy.tsbefore response forwarding
This prevents misleading header values during model selection or provider fallback scenarios.
Source Files and Implementation Details
| File | Purpose |
|---|---|
server/src/lib/header-value.ts |
Defines safeHeaderValue() and routedViaValue() for header sanitization |
server/src/routes/responses.ts |
Attaches header for OpenAI-compatible chat completion streams |
server/src/routes/proxy.ts |
Attaches header for generic proxy requests and cache hits |
docs/api.md |
Documents header behavior for API consumers (line 60) |
Summary
- The
X-Routed-Viaheader identifies the actual provider platform and model serving each request - Format:
<platform>/<model>with ASCII-only values (percent-encoded when needed) - Cache hits return the literal value
cacheinstead of provider details - Sanitization occurs in
header-value.tsvia theroutedViaValuefunction - Timing: Header is set immediately before streaming begins, ensuring accurate routing information
Frequently Asked Questions
What does the X-Routed-Via header value look like for a standard request?
The value follows the pattern platform/model, such as groq/llama-3.3-70b-versatile or anthropic/claude-3-sonnet-20240229. This tells you both which provider's infrastructure handled the request and which specific model variant was invoked.
Why does the X-Routed-Via header sometimes contain percent-encoded characters?
Non-ASCII characters in provider or model names are automatically percent-encoded by the safeHeaderValue sanitizer in server/src/lib/header-value.ts. This ensures HTTP header compliance while preserving the full identity information—use decodeURIComponent() to recover the original string.
How can I tell if my response came from cache instead of live inference?
When FreeLLMAPI serves a request from its internal cache, the X-Routed-Via header is set to the literal string cache rather than a platform/model value. This behavior is implemented in server/src/routes/proxy.ts and allows immediate distinction between cached and live responses.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →