> This page is for Gateway.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.merge.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.merge.dev/_mcp/server.

# Using routing policies

> How Gateway resolves the routing policy for a request, which errors fail over to the next model or vendor, how to send priority_order inline, and how default_routing works.

Gateway resolves a routing policy for each request from the request and your organization's configuration. The recommended way to pick one is its [model alias](/merge-gateway/routing/model-aliases): send `@alias/<slug>` as `model`.

## How routing policies are applied

The first match wins.

1. **A concrete `model`.** A `provider/model` ID or bare model name routes directly, ignoring `routing_policy_id` and key bindings.
2. **[`priority_order`](#sending-a-priority-list-with-the-request)**, an inline priority list.
3. **A model alias.** `@alias/<slug>` routes through the policy it names.
4. **`routing_policy_id`**, in the body or the `X-Merge-Routing-Policy-Id` header.
5. **A policy [bound to the API key](/merge-gateway/automation/api-keys#bind-a-routing-policy-to-a-key).** `POST /v1/embeddings` ignores key bindings.
6. **The [customer's](/merge-gateway/embedded-routing-stack/overview) default policy**, when the request names a customer.
7. **The project's default policy**, when a project API key, `project_id`, or the `X-Project-Id` header sets a [project](/merge-gateway/cost/projects#scoping-requests-to-a-project).
8. **The organization default policy.**

If nothing resolves, Gateway rejects the request because no model or policy applies. Key bindings to deleted, inactive, or differently scoped policies are skipped. When a project policy resolves, its [tag rules](/merge-gateway/routing/overview#tag-based-routing) can select another strategy.

### `model` values

| `model`                                        | Behavior                                                                                            |
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Omitted, `null`, or `"default_routing"`        | Use the resolved policy. `default_routing` (case-insensitive) is for clients that must send a model |
| `"@alias/<slug>"`                              | Route through that alias's policy                                                                   |
| `"provider/model"`, such as `"openai/gpt-5.5"` | Route to that model, skipping every policy                                                          |
| Bare name, such as `"gpt-5.5"`                 | Resolved to a full ID, rejected if ambiguous, then routed like `provider/model`                     |

## Failover

The same rules cover vendor fallback within a model and model fallback in Priority policies and `priority_order`: Gateway tries eligible vendors, then the next model. It retries vendor throttles, outages, timeouts, connection failures, and billing errors. Invalid requests stop routing; credential rejections usually do. Some successful-looking `200` responses, such as an empty completion, can fail over too. The collapsed tables below summarize status-code behavior; [Errors](/merge-gateway/errors#what-fails-over) covers other cases.

Streams fail over only before the first chunk reaches you. If every candidate fails, Gateway returns the last error.

A model that fails 3 times in 60 seconds on one vendor is skipped there until a health probe (every 30 seconds) succeeds. That vendor's other models keep routing.

## Sending a priority list with the request

Send `priority_order` to set the order per request instead of storing a policy. Entries follow the [failover rules](#failover). Stored policies are bypassed, but each entry still honors the key's allowed models, vendor and region restrictions, zero data retention, and provider access; disallowed entries are skipped.

**`cURL`**

```bash title="cURL"
curl https://api-gateway.merge.dev/v1/responses \
  -H "Authorization: Bearer $MERGE_GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": [{"type": "message", "role": "user", "content": "Summarize this ticket."}],
    "priority_order": [
      "openai/gpt-5.5",
      {"model": "anthropic/claude-sonnet-5", "vendors": ["bedrock"]},
      "zai/glm-5.3"
    ]
  }'
```

**`OpenAI SDK`**

```python title="OpenAI SDK"
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["MERGE_GATEWAY_API_KEY"],
    base_url="https://api-gateway.merge.dev/v1/openai",
)

completion = client.chat.completions.create(
    model="openai/gpt-5.5",  # the SDK requires a model, so restate the first entry
    messages=[{"role": "user", "content": "Summarize this ticket."}],
    extra_body={
        "priority_order": [
            "openai/gpt-5.5",
            {"model": "anthropic/claude-sonnet-5", "vendors": ["bedrock"]},
        ]
    },
)
print(completion.choices[0].message.content)
```

A successful list is saved as a policy scoped to the request's customer, project, or organization. The same list and scope always get the same ID, returned in `routing.policy_id` and `x-merge-routing-policy-id` and reusable as `routing_policy_id`. Inline policies never become defaults and are listed only with `include_inline=true`.

## Reference

### `priority_order` entries

| Field               | Rules                                                                                                                                   |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Entry               | A model ID string, or an object with `model` and optional `priority` and `vendors`. Up to 10 entries                                    |
| `priority`          | Integer, `0` or higher. Lower runs first. An entry without one uses its 0-based list position as its priority, and ties keep list order |
| `vendors`           | Non-empty list of vendors to try for that entry, in order                                                                               |
| `model` (top level) | Omit it, or set it to the first entry or `"default_routing"`                                                                            |

`priority_order` can't be combined with `routing_policy_id`, a model alias, or top-level `vendor` or `vendors`. It works on `/v1/responses` and every compatible endpoint.

The organization and each project and customer have at most one default policy. Select others by alias or `routing_policy_id`.

#### Failover response codes

| Fails over to the next candidate                                                         | Stops and returns the error                                                             |
| ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `429` and every `5xx`                                                                    | `400` request errors, such as invalid parameters                                        |
| Timeouts and connection errors                                                           | `401` and `403` credential rejections, except between two of your self-hosted endpoints |
| `402` and billing errors returned as `400`, such as insufficient vendor balance          |                                                                                         |
| A vendor `404`, or a `400` saying the vendor doesn't have the model                      |                                                                                         |
| `400 output_budget_exhausted` (the model spent the whole output budget on reasoning)     |                                                                                         |
| A vendor content-policy refusal, which moves to a model from a different direct provider |                                                                                         |
| Any other status, such as `408`, `409`, or `422`                                         |                                                                                         |

#### Policy resolution error codes

| Status and code                              | Cause                                                                                  |
| -------------------------------------------- | -------------------------------------------------------------------------------------- |
| `400 model_required`                         | No `model` and no policy resolves, or an Intelligent policy has no models              |
| `400 routing_policy_requires_project`        | `routing_policy_id` names a project-scoped policy and the request has no project       |
| `400 routing_policy_requires_customer`       | `routing_policy_id` names a customer-scoped policy and the request has no customer     |
| `404`                                        | `routing_policy_id` is unknown, inactive, or scoped to a different project or customer |
| `400 routing_policy_mismatch`                | Body `routing_policy_id` and the `X-Merge-Routing-Policy-Id` header differ             |
| `400 alias_routing_policy_conflict`          | A model alias and `routing_policy_id` on the same request                              |
| `422`                                        | Invalid `priority_order` on `/v1/responses`, including a conflicting `model`           |
| `400 priority_order_model_conflict`          | `model` differs from the first `priority_order` entry on a compatible endpoint         |
| `400 invalid_priority_order`                 | Any other invalid `priority_order` on a compatible endpoint                            |
| `400 priority_order_routing_policy_conflict` | `priority_order` with the `X-Merge-Routing-Policy-Id` header                           |

## Next steps

#### [Model aliases](/merge-gateway/routing/model-aliases)

Select a policy by name in the model field

#### [Routing policies](/merge-gateway/routing/overview)

Compare strategies and see how Gateway picks a vendor

#### [Management API](/merge-gateway/management-api)

Create and update policies programmatically