# What Information Is Available in the X-Routed-Via Header?

> Understand the X-Routed-Via header. Discover which platform and model processed your request or if it was served from cache. Learn more about your API traffic.

- Repository: [Tashfeen/freellmapi](https://github.com/tashfeenahmed/freellmapi)
- Tags: api-reference
- Published: 2026-08-28

---

**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`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/routes/responses.ts) at line 28, the header is attached once the first meaningful output is ready to stream:

```typescript
// From responses.ts - header set before streaming begins
res.setHeader('X-Routed-Via', routedViaValue(provider, model));

```

Similarly, [`server/src/routes/proxy.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/header-value.ts) (line 52) processes the string through `safeHeaderValue`:

```typescript
// 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`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/routes/proxy.ts) at line 75, cache hits trigger:

```typescript
// 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

```bash
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)

```javascript
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:

```javascript
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.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/responses.ts) before the SSE stream begins
- For **proxy endpoints**: Set in [`proxy.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/proxy.ts) before 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`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/header-value.ts) | Defines `safeHeaderValue()` and `routedViaValue()` for header sanitization |
| [`server/src/routes/responses.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/routes/responses.ts) | Attaches header for OpenAI-compatible chat completion streams |
| [`server/src/routes/proxy.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/routes/proxy.ts) | Attaches header for generic proxy requests and cache hits |
| [`docs/api.md`](https://github.com/tashfeenahmed/freellmapi/blob/main/docs/api.md) | Documents header behavior for API consumers (line 60) |

## Summary

- **The `X-Routed-Via` header** 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 `cache` instead of provider details
- **Sanitization** occurs in [`header-value.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/header-value.ts) via the `routedViaValue` function
- **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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/routes/proxy.ts) and allows immediate distinction between cached and live responses.