RawFrame

Fallback routing

Try other models automatically when the one you asked for is down.

Add routing.fallbacks to a generation request, and if the requested model can't take the job, it runs on the next model in the list instead. You pay the price of the model that actually ran.

{
  "model": "openai/gpt-image-2",
  "prompt": "A lighthouse on a cliff at dusk",
  "params": { "aspect_ratio": "1:1" },
  "routing": { "fallbacks": ["google/gemini-2.5-flash-image", "bfl/flux-3-image"] }
}

When it falls back

A fallback runs only when the model refused the job before accepting it, with an error that's safe to retry and wasn't billed:

ReasonError code on the attempt
The provider is down or overloadedprovider_unavailable
The provider rate-limited usprovider_rate_limited
Our quota with the provider is used upquota_exhausted
The model has been failing, so its circuit is open (see below)provider_unavailable
The model's provider isn't configured right nowprovider_unavailable

Anything else ends the generation as usual. A content refusal or invalid parameters won't be retried on another model, and once a provider has accepted the job we never resubmit it elsewhere, so you're never billed twice for one generation. If the last model in the list also fails, it is retried up to three times before the generation fails.

What each fallback must support

Every fallback is checked when you submit, and the request is rejected with 400 and param: "routing.fallbacks[i]" if one:

  • doesn't exist, or isn't available to your account;
  • makes a different media type (an image model can't stand in for a video model);
  • doesn't accept the request as sent, such as a duration, aspect ratio or number of outputs it doesn't support;
  • repeats a model already in the chain.

Defaults for parameters you leave out are filled in for each model separately. Up to three fallbacks are allowed. provider_options are passed only to the model you asked for, since they're specific to its provider; fallbacks run without them.

What you're charged

  • Hold: when you submit, we hold the highest estimate across the whole chain, shown as price_estimate_micros. Your balance must cover it, or the request fails with 402.
  • Charge: when the generation finishes, you're charged for what the model that ran produced, at that model's price, and the rest of the hold is released.
  • served_by on the generation shows which model ran. model keeps the one you asked for.

Model availability

Each model has a circuit breaker. If more than half of its last 50 submits (with at least 10 in the window) failed with retryable errors, the circuit opens for 30 seconds and requests skip that model. After that, one request is let through as a test: if it works the model is back, and if not the circuit opens again.

GET /v1/models shows the result in availability:

availabilityMeaning
operationalTaking requests normally.
degradedRecovering: a test request is being let through.
unavailableThe circuit is open, or the provider isn't configured. Requests fall back, or fail with provider_unavailable.

On this page