> For the complete documentation index, see [llms.txt](https://docs.kontinent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kontinent.ai/models-and-routing/routing-policies.md).

# Routing policies

A **routing policy** is a named list of models that you address like a single model. Instead of hard-coding `anthropic/claude-opus-4.8` in your app, you send `policy/eu-prod` and Kontinent works down the models you configured — in order, by weight, whatever the policy says.

The policy lives in your organization, not in your code. Swap the models behind it in the console and every request follows the change within seconds, no deploy.

{% hint style="success" %}
**Use the full id, including the `policy/` prefix.** The console shows it as a copyable chip: `policy/eu-prod`. That exact string goes into the `model` field.
{% endhint %}

## What a policy gives you

<table data-view="cards"><thead><tr><th></th><th></th><th></th></tr></thead><tbody><tr><td><h4><i class="fa-list-ol" style="color:$primary;">:list-ol:</i></h4></td><td><strong>Your own chain</strong></td><td>Cross-vendor fallback you define, not just the built-in per-model routes.</td></tr><tr><td><h4><i class="fa-code" style="color:$primary;">:code:</i></h4></td><td><strong>One id in your code</strong></td><td>Change models in the console; the request body never changes.</td></tr><tr><td><h4><i class="fa-scale-balanced" style="color:$primary;">:scale-balanced:</i></h4></td><td><strong>Traffic splitting</strong></td><td>Send 90% to a cheap model and 10% to a strong one, by weight.</td></tr></tbody></table>

This is the layer *above* [maximum availability](/models-and-routing/availability.md). Built-in failover moves one logical model between providers. A policy moves between **different models** — including different vendors — because you said so.

## Create one

{% stepper %}
{% step %}

### Open Routing policies

In the console, go to **Routing** → **Create policy**.
{% endstep %}

{% step %}

### Name it

The name becomes the policy id: `EU Prod` → `policy/eu-prod`. The id is generated once and **never changes**, even if you rename the policy later. Names must be unique within your organization.
{% endstep %}

{% step %}

### Pick a strategy

**Fallback**, **Load balance**, or **Latency** — see [below](#strategies).
{% endstep %}

{% step %}

### Add models

Add models from the catalog panel and order them with the arrows. For fallback, set **attempts** per model (1–5). For load balance, set a **weight** (1–100).
{% endstep %}

{% step %}

### Use the id

Copy the `policy/<slug>` chip and send it as `model`. Live within \~30 seconds of saving.
{% endstep %}
{% endstepper %}

## Strategies

| Strategy         | Order of models                                                                                                                | Per-model setting |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------ | ----------------- |
| **Fallback**     | Top to bottom, exactly as listed. Each model is retried `attempts` times before moving on.                                     | `attempts` (1–5)  |
| **Load balance** | Weighted random. A 90/10 pair sends roughly 9 in 10 requests to the first model — the other entries stay in line as fallbacks. | `weight` (1–100)  |
| **Latency**      | Fastest-first. Currently ordered as listed while live latency data is being collected.                                         | —                 |

A model that fails is never a dead end: whatever the strategy picked first, the remaining entries are still tried in order. Failover rules are the same as for regular models — `429`, `5xx`, and connection errors retry the next candidate, always **before the first byte** reaches you. See [Retries & backoff](/best-practices/retries-and-backoff.md).

## Use it

{% tabs %}
{% tab title="curl" %}

```bash
curl https://api.kontinent.ai/v1/chat/completions \
  -H "Authorization: Bearer $KONTINENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "policy/eu-prod",
    "messages": [{"role": "user", "content": "Hallo"}]
  }'
```

{% endtab %}

{% tab title="Python" %}

```python
from openai import OpenAI

client = OpenAI(base_url="https://api.kontinent.ai/v1", api_key=KONTINENT_API_KEY)

client.chat.completions.create(
    model="policy/eu-prod",
    messages=[{"role": "user", "content": "Hallo"}],
)
```

{% endtab %}
{% endtabs %}

Policies work on `/v1/chat/completions` and `/v1/embeddings`, and with streaming.

## Rules worth knowing

* **Real model ids always win.** If a policy slug collides with a catalog model id, the catalog model is served. A policy can never shadow a real model.
* **Policies are private to your organization.** Another org's slug simply doesn't exist for your key.
* **Wrong-kind entries are skipped.** An embedding model in a policy used for chat is ignored, not an error.
* **Unavailable models drop out.** If a model leaves the catalog, it is skipped and the rest of the chain still serves. The console marks it as *no longer available* so you can fix the policy.
* **Guardrails still apply.** Key guardrails, allowlists, zero-retention requirements, and sovereignty segments are enforced *after* the policy expands. A policy cannot route around them — if every entry is blocked, the request is refused.
* **A policy is an explicit override.** Only the models you listed are used; the built-in provider fallbacks of those models are not silently appended.
* **Usage is billed to the model that served.** The usage record keeps both: `model` is `policy/eu-prod`, `served_model` is the model that actually ran, and spend is attributed to the latter.

## Troubleshooting

| Symptom                              | Cause                                                                                                     |
| ------------------------------------ | --------------------------------------------------------------------------------------------------------- |
| `404 model_not_found`                | Wrong id or wrong org. Copy the chip from the console — the id is `policy/<slug>`, e.g. `policy/eu-prod`. |
| Change had no effect                 | The catalog snapshot refreshes about every 30 seconds. Retry shortly after saving.                        |
| A model in the policy never runs     | It is a different kind (embedding vs. chat), disabled in the catalog, or blocked by the key's guardrail.  |
| `502` / `429` although models remain | Every entry in the chain failed. See [Handling errors](/features/errors.md).                              |

{% hint style="info" %}
Deleting a policy stops resolving its id immediately. Requests still sending `policy/<slug>` will get `404 model_not_found`.
{% endhint %}

A policy is an explicit chain you address as `policy/<slug>`. For a router that classifies each request and picks among a pool you configured, see [Price & performance](/models-and-routing/price-performance.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.kontinent.ai/models-and-routing/routing-policies.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
