# Choosing a model

Name one model, or a tier, a provider, or nothing at all. Everything that matches is tried in order until one answers, and the reply names the one that did.

## How a call is routed

Three steps, each with its own distinct failure. A name nobody serves, a capability nobody has, and an upstream that
broke are different answers, and you can tell them apart without parsing prose.

| Step | What happens |
|---|---|
| 1. Expand | The selection becomes every configured offering it could mean that runs on a key: yours, or Momor's where the offering's catalog row says [`resale: true`](/docs/gateway/models/#reading-the-catalog). Nothing matches, or nothing it matches runs on a key: `404`. |
| 2. Filter | Each candidate's client is asked whether it can carry this call: tools, schema, streaming and file types. A [parameter](/docs/gateway/reference/chat/#how-parameters-reach-providers) a candidate does not take is no reason to skip it. This filters capabilities; it does not validate your parameter values. All refuse: `422`. |
| 3. Try | Survivors are tried in order and the first to reply wins. All fail upstream: the last provider's own status, with its own message. See [provider failover](/docs/gateway/failover/). |

Capability refusals are deliberately aggregate. Even a one-rung ladder returns the same generic `422` when its
client refuses the requested shape. Once a provider is actually called, its real failure remains distinct and can
become the terminal answer if the ladder is exhausted.

## Naming what you want

The shortest selector is a canonical model name. Qualifiers narrow the same model catalog by tier, publisher, or
serving provider; they do not expose or accept the identifier a provider uses on its own API.

```json
"model": "kimi-k3"                                      // this canonical model, through any provider
"model": "moonshotai/kimi-k3"                           // this publisher and model, through any provider
"model": "togetherai/moonshotai/kimi-k3"                // this provider, publisher and model
"model": "tier/high"                                    // any high-tier model
"model": "togetherai/tier/high"                         // any high-tier model on this provider
"model": { "name": "kimi-k3", "publisher": "MoonshotAi", "provider": "TogetherAi" }
"model": { "tier": "medium", "except": ["gpt-oss-120b", { "publisher": "Meta" }] }
"model": "auto"                                         // your organization's models for auto, or any model
```

The full shorthand grammar is:

| Form | Meaning |
|---|---|
| `*` | Any public model of the type the route names. |
| `auto` | The models your organization lists for `auto` that are of the type the route names, tried in its order; any public model of that type where it lists none. |
| `{model}` | The canonical model name, regardless of provider. |
| `tier/{tier}` | Any model in that tier: `free`, `low`, `medium`, `high`, `xhigh` or `tierless`. |
| `{publisher}/{model}` | A canonical model from that publisher, regardless of provider. |
| `{provider}/tier/{tier}` | Any model in that tier served by that provider. |
| `{provider}/{publisher}/{model}` | One publisher-qualified model served by one provider. |

The model and publisher positions also accept `*`; the provider position does not. Provider is always the first
segment of a three-segment selector; it has no two-segment shorthand because two segments always mean
`publisher/model`. A string with more than three segments, an empty segment, or a value after `tier/` that is not a
tier is invalid. Use the object form, with `name`, `tier`, `publisher`, `provider` and `except`, when the shorthand is
less clear. Matching is case-insensitive.

`except` leaves models out of any selection: a model one of its entries answers to is never tried, whatever else the
selection matches. Each entry is a selector in either form, so it can leave out a model, a publisher, a provider or a
tier.

A tier is held on public benchmark intelligence and output speed against its Claude anchor, both: `medium` Claude Haiku,
`high` Claude Sonnet, `xhigh` Claude Opus. A model holds it where it clears the anchor's intelligence on most of the
public comparison sites that list both, each on its own measure, and the anchor's output speed. `tierless` is a
transcription, OCR or decision model, with no peers to rank it against. A model no comparison site lists beside the
anchors carries `unknown` and is never served.

A tier, `auto` or `*` leaves out deprecated models, and, where `prioritization.maxAge` or your organization's default
sets one, models older than it. A selector naming one exact model is
served by it whether it is deprecated or not, and whatever its release date.

A model's catalog `id` is its publisher and name as `publisher/name`, in lowercase with spaces as hyphens, so the `id`
itself is a selector: `"model": "moonshotai/kimi-k3"`. The provider's own model identifier is deliberately private,
and is neither returned nor accepted.

## Change the model, change nothing else

The same request shape reaches every offering, even though the provider SDKs, reasoning formats and tool-call id rules
differ underneath. Read `model` back from the reply rather than assuming it echoes your request: it reports what
actually served the call, after tier and wildcard resolution and after failover.

```json
"model": "claude-sonnet-5"            // Anthropic
"model": "gpt-5.6-terra"              // OpenAI
"model": "gemini-3.6-flash"           // Google
```

## The order candidates are tried in

Two providers serving the same canonical model give a request a real ladder: the second is the next rung, not a retry
you have to ask for. Candidates are ordered by price, what an offering lists for a million tokens in and a million out,
cheapest first, and where price ties, by provider name, then publisher, then model name. An offering running on a key
the request carries leads, then those on your organization's
[prioritized keys](/docs/gateway/bring-your-own-keys/#which-key-a-call-runs-on); those on its fallback keys come after
Momor's. [`prioritization`](#choosing-providers) puts the providers you order ahead of price, and within each provider
your key goes before Momor's.

## Ranking your own candidates

Send `models` instead of `model` to rank several selectors yourself. Every model the first entry answers to is tried
before any the second answers to, and so on; within one entry the order above applies. A model two entries both answer
to is tried once, in its first place. On `POST /models`, sending both `model` and `models` is a `400`.

```json
"models": ["claude-sonnet-5", "anthropic/*", "tier/high"]
```

On [`/v1/chat/completions`](/docs/gateway/reference/chat-completions/), `model` and `models` may both be sent, each as a
string or an array of strings: every selector in `model` is tried first, then each in `models`.

## Choosing providers

`prioritization` decides which providers serve a call first and which never do.

| Field | Notes |
|---|---|
| `order` | Providers that lead, in this order, ahead of price. |
| `ignore` | Providers that serve nothing on this call. |
| `sort` | `"price"`, the default: after `order`, the cheapest offering first. |
| `zdr` | `true` runs the call under [zero data retention](/docs/gateway/bring-your-own-keys/#zero-data-retention). `false` by default. |
| `deprecated` | `true` lets deprecated models serve a tier, `auto` or `*`. Left out, the organization's default, else `false`. |
| `maxAge` | How old a model may be, as ISO 8601 such as `P6M`, `P1Y` or `P2Y`, or a TimeSpan such as `180.00:00:00`: a tier, `auto` or `*` is served only by models released no longer ago than this. A month counts thirty days and a year 365. Left out, the organization's default, else no model is left out for its age. |

```json
"prioritization": { "order": ["Groq"], "ignore": ["TogetherAi"] }
```

`order` and `ignore` name a provider's root, such as `azure`, or one of its regions as `name@region`, such as
`azure@eu`. A root in `ignore` leaves out the root alone, and its regions still serve; `azure@eu` leaves out that
region alone.

A provider or region this deployment does not serve, or one both ordered and ignored, is refused with `400`. The Chat
Completions route takes `order`, `ignore`, `zdr`, `deprecated` and `maxAge` as `provider`.

## Organization defaults

The organization's owner, signed in, sets the models tried when a call asks for `auto`, and a default
`prioritization`. It is the same setting in Settings › Models & routing, and in a Workflow organization's Settings ›
Models, where AI steps that name no model ask for `auto` too:

```http
PATCH /organization/preferences
{ "modelRouting": { "models": ["anthropic/claude-sonnet-5", "moonshotai/kimi-k3", "tier/high"], "prioritization": { "order": ["Groq"], "ignore": ["TogetherAi"] } } }
```

| Field | Notes |
|---|---|
| `modelRouting.models` | Model selections tried in order when a call asks for `auto`, as a call's own [`models`](#ranking-your-own-candidates) would be: a name, `publisher/name`, `provider/publisher/name`, a tier, or the object form. Empty means any model. A call that names its own `model` or `models` is routed by those. |
| `modelRouting.prioritization.order` | Providers that lead, in this order, ahead of price. Roots or `name@region`. |
| `modelRouting.prioritization.ignore` | Providers that serve nothing. Roots or `name@region`. |
| `modelRouting.prioritization.sort` | `"price"`, the default: after `order`, the cheapest offering first. |
| `modelRouting.prioritization.zdr` | `true` holds every call the organization makes to [zero data retention](/docs/gateway/bring-your-own-keys/#zero-data-retention). |
| `modelRouting.prioritization.deprecated` | `true` lets deprecated models serve a tier, `auto` or `*` for a call that does not say. |
| `modelRouting.prioritization.maxAge` | How old a model may be for a call that sets none; left out, no model is left out for its age. |

`order` and `sort` apply only to a call that sends no `order` of its own, as `prioritization` or, on Chat
Completions, as `provider`; a call that sends its own is routed by that. `ignore` applies to every call: a provider the
organization ignores serves no call, whatever the call orders, and a call's own `ignore` leaves out more. `zdr` applies
to every call: set to `true`, it holds every call to zero data retention, whatever the call sends, and a call's own
`false` does not turn it off. `deprecated` and `maxAge` apply to a call that sets neither of its own; a call's
own value stands over the organization's. A selection or provider this deployment does not know is refused with `400`. `GET /organization/preferences`
returns the defaults under `modelRouting`.
