---
title: "Model fallbacks"
description: "When no provider of the requested model can serve, pirouter moves the request to the next fallback model named on the request or the workspace, and bills only the attempt that returned the response."
canonical: "https://pirouter.ai/docs/guides/fallbacks"
last-updated: "2026-10-17"
lang: "en"
source: "content/docs/en/guides/fallbacks.mdx"
---

# Model fallbacks

When no provider of the requested model can serve, pirouter moves the request to the next fallback model named on the request or the workspace, and bills only the attempt that returned the response.

[Provider routing](https://pirouter.ai/docs/guides/routing.md) changes providers within one model; model fallbacks change the model when none of its providers can serve. Name fallback models in the request's `models` array, or set them for the workspace in the console.

## Name fallback models on a request

Add a `models` array to the request body. pirouter tries `model` first, then the array in order.

```bash
curl https://api.pirouter.ai/v1/chat/completions \
  -H "Authorization: Bearer $PIROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-opus-5.5",
    "models": ["openai/gpt-6.1-sol", "google/gemini-4-argon"],
    "messages": [{ "role": "user", "content": "Hello!" }]
  }'
```

- `models` holds at most 3 entries; more returns `422`.
- An entry equal to `model`, or repeated, is dropped.
- Without `model`, the first entry of `models` is the primary model.
- Requests on all three protocols accept `models`. On the Gemini protocol the primary model is in the path and `models` is only the fallback list.

Every fallback model is checked when the request arrives. If any of them does not exist, the whole request returns `404 model_not_found`, the `message` names it, and nothing has been forwarded. A fallback model that has been retired returns `404 model_not_found` as well, and the `message` gives its retirement date.

You can leave the `route` field out: it accepts only `"fallback"`, which behaves the same as no `route` at all.

## Set fallback models for the workspace

Add them under **Fallback models** on the **Routing** page of the console: at most 3, and only chat text models. Only workspace owners can change them.

The workspace list applies only when the request has no `models` of its own. A request that sends `models` uses exactly that list; the workspace list is not appended.

A model on the workspace list that has gone offline is skipped without an error.

![Fallback models on the Routing page: Claude Sonnet 5.5, GPT-5.5 and Gemini 3.5 Flash in order, up to 3](/docs/shots/fallbacks-models.en.webp)

## When it switches

The request moves to the next model in two cases:

1. The current model has no provider that can serve: the [routing settings](https://pirouter.ai/docs/guides/routing.md#when-no-provider-is-left) excluded them all, or they are all unavailable (for example, a deployment is turned off or past its retirement date).
2. A provider of the current model failed before the first byte, and failover has tried every provider of that model. For the failures that trigger failover, see [Provider routing](https://pirouter.ai/docs/guides/routing.md#failover).

pirouter switches to the next model only before the response starts. Once the response has started, no later error changes the model.

In these cases the request ends without moving to another model:

- The model is not served on the endpoint you called: `422 validation_failed`.
- The input is over the model's context limit: `400 context_length_exceeded`.
- pirouter's rate limit refused the request: `429 rate_limited`. The same holds partway through a switch: the whole request returns `429` with a `Retry-After` header.

A request is tried at most 5 times in total, across all its models.

`"allow_fallbacks": false` in `provider` limits providers, not `models`: on the next model the choice among its providers starts afresh.

## Billing

You pay only for the attempt that returned the response, at the price of its own model and provider. An attempt that failed before the next one took over is not billed.

Search **Logs** in the console by `X-Pi-Trace-Id` to see every attempt of the request: an attempt that the next one replaced is a failed row costing $0.00, and only the attempt that returned the response is billed. See [Request logs](https://pirouter.ai/docs/guides/logs.md#find-a-request-by-trace-id).

![Logs searched by one trace ID: a failed openai/gpt-6-sol attempt costing $0.00, then a successful openai/gpt-5.5 request](/docs/shots/fallbacks-trace.en.webp)

## Which model answered

The `model` in the response body is the ID of the model that answered. When it differs from the `model` you sent, a fallback happened. The `X-Pi-Model` response header holds the same value, and `X-Pi-Provider` names the provider that served it. A request that waited more than 90 seconds for the provider has neither header, so read `model` in the body or in the stream's events; no fallback happens after that point. See [Long requests](https://pirouter.ai/docs/guides/timeouts.md#long-requests).

## Not available today

- **Presets.** A request that sends `preset` returns `422`.
- **A dedicated field saying a fallback happened.** Compare the response's `model` with the one you sent.

## Next steps

- [Provider routing](https://pirouter.ai/docs/guides/routing.md): How a provider is chosen among those serving one model.
- [Models and protocols](https://pirouter.ai/docs/models.md): How model IDs are written and which protocols each model accepts.
