> ## Documentation Index
> Fetch the complete documentation index at: https://docs.routor.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Response Metadata

> How to read routing decisions from the response body and headers.

# Response Metadata

Every response from Routor includes routing metadata so you can see which model handled your request, what tier it was classified into, and how much you saved. There are two ways to access it.

***

## The `routor` Response Object (Always Available)

Every non-streaming response includes a `routor` object in the JSON body. This is the primary way to read routing metadata. It works on every deployment, with no configuration needed.

```json theme={null}
{
  "id": "chatcmpl-abc123",
  "model": "moonshot/kimi-k2.6",
  "choices": [...],
  "usage": { ... },
  "routor": {
    "model":       "moonshot/kimi-k2.6",
    "tier":        "LIGHT",
    "profile":     "auto",
    "confidence":  0.82,
    "savingsPct":  87.4,
    "method":      "rules"
  }
}
```

| Field        | Description                                                                                  |
| ------------ | -------------------------------------------------------------------------------------------- |
| `model`      | The model that handled the request (may differ from the routed model if a fallback was used) |
| `tier`       | The complexity tier assigned: NANO, SIMPLE, LIGHT, STANDARD, or COMPLEX                      |
| `profile`    | The routing profile used: `auto`, `tier`, or `direct`                                        |
| `confidence` | Classification confidence from 0 to 1                                                        |
| `savingsPct` | Savings vs the baseline model (Claude Opus 4.8) as a percentage                              |
| `method`     | How the tier was decided: `rules`                                                            |

### Reading it in code

**Node.js / TypeScript:**

```typescript theme={null}
const res = await fetch("https://api.routor.ai/v1/chat/completions", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.ROUTOR_API_KEY}`,
    "Content-Type":  "application/json",
  },
  body: JSON.stringify({ model: "auto", messages: [...] }),
});

const data = await res.json();
console.log("Model:",     data.routor.model);
console.log("Tier:",      data.routor.tier);
console.log("Savings:",   data.routor.savingsPct + "%");
console.log("Confidence:", data.routor.confidence);
```

**Python:**

```python theme={null}
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ROUTOR_API_KEY"],
    base_url="https://api.routor.ai/v1",
)

response = client.chat.completions.create(
    model="auto",
    messages=[{"role": "user", "content": prompt}],
)

# The routor object is in response.model_extra or the raw response
# depending on your SDK version. Use the raw HTTP response for direct access:
import httpx
r = httpx.post(
    "https://api.routor.ai/v1/chat/completions",
    headers={"Authorization": f"Bearer {os.environ['ROUTOR_API_KEY']}", "Content-Type": "application/json"},
    json={"model": "auto", "messages": [{"role": "user", "content": prompt}]},
)
data = r.json()
print("Model:",    data["routor"]["model"])
print("Tier:",     data["routor"]["tier"])
print("Savings:",  data["routor"]["savingsPct"], "%")
```

***

## Response Headers (Debug Mode Only)

Every response includes `X-Request-Id`, a unique ID for that request, useful for support queries.

The `X-Routor-*` headers are only emitted when the server has `DEBUG_ROUTING=1` set. On a default production deployment, these headers are **not** present. Use the `routor` response object above instead, which is always available.

| Header                   | Type    | Always sent?                                   | Description                                  |
| ------------------------ | ------- | ---------------------------------------------- | -------------------------------------------- |
| `X-Request-Id`           | string  | Yes                                            | Unique ID for this request                   |
| `X-Routor-Model`         | string  | Only with `DEBUG_ROUTING=1`                    | The model that handled the request           |
| `X-Routor-Tier`          | string  | Only with `DEBUG_ROUTING=1`                    | The complexity tier assigned                 |
| `X-Routor-Confidence`    | float   | Only with `DEBUG_ROUTING=1`                    | Classification confidence from 0 to 1        |
| `X-Routor-Profile`       | string  | Only with `DEBUG_ROUTING=1`                    | The routing profile used                     |
| `X-Routor-Savings`       | string  | Only with `DEBUG_ROUTING=1`                    | Savings vs baseline as a percentage          |
| `X-Routor-Fallback`      | boolean | Only with `DEBUG_ROUTING=1`                    | `true` if a fallback model was used          |
| `X-Routor-History-Floor` | string  | Only with `DEBUG_ROUTING=1`, and only when set | Tier floor applied from conversation history |

***

## Streaming Responses

Streaming responses do not include the `routor` object in the stream. To get routing metadata for a streamed request:

1. Check the dashboard, which records every request regardless of streaming
2. Use the [Debug Endpoint](api/debug.md) with the same prompt to see the decision without spending credits
3. If your deployment has `DEBUG_ROUTING=1` set, the `X-Routor-*` headers are sent before the stream begins

***

## Fallback Indicator

When the primary model fails and Routor tries the next one in the chain, the `routor` object in the response body shows the fallback model (not the original routed model). If `DEBUG_ROUTING=1` is set, the `X-Routor-Fallback: true` header is also added.

A high rate of fallbacks from one provider is a sign that provider is having issues. Check the [Provider Health](dashboard/providers.md) page in the dashboard.
