Eazler AI Lab AI Engineering Journal
Skip to article
Guides◷ 11 min read

OpenRouter provider routing guide — provider selection, fallbacks and response validation

In OpenRouter, provider.order is a priority list, not an allowlist. How order, only and allow_fallbacks differ, and what restricting providers costs.

On this page

Even when you pick a single model on OpenRouter, the provider that serves the request can vary. For the case where a model name itself starts pointing to a different version, see our separate DeepSeek V4.1 Flash migration guide. In the official docs, provider.order is a priority order, and with the default allow_fallbacks: true, a request can also move on to other eligible providers outside the list. Before you go to production, decide not only which model to use but also how far requests are allowed to fall back. [1]

Korean original: 한국어 원문 (2026-09-12)Scope: OpenRouter Chat CompletionsOfficial docs checked: 2026-09-12

1. Executive summary

Model
What runs
Provider
Where it runs
Response
Whether it contains the result your task needs

OpenRouter is a platform that connects many models and model-hosting services behind a single API. A provider is the service that actually runs the model, and routing is the process of choosing which model and provider a request goes to. One model can have several providers, and supported features and terms of use can differ from provider to provider. [1]

The key conclusion: Keep settings that try your preferred provider first separate from settings that restrict what is allowed. Then check the route that was actually selected together with the content of the response. Narrowing what is allowed makes control clearer, but it also leaves fewer fallback routes during an outage.

When we checked on 2026-09-12 (Korea Standard Time, UTC+9), the Hacker News (HN) post about an operator's experience with OpenRouter had 663 points and 182 comments. We chose the topic on that signal of interest; it is not a ranking of overall user demand. This guide compares the official docs with an operator's first-hand account; it is not our own experiment on provider performance. [6]

2. Why you need to tell models and providers apart

So you want to use OpenRouter?, published on September 7, records the provider-specific problems with image handling, tool calls and empty responses that the operator of the AI assistant Olly ran into. It also describes how a setup restricted to a few providers lost availability when some routes disappeared or ran into rate limits. These are observations from that operator's own service, not evidence of the current state of every provider. [5]

There is no need to generalize that experience into a defect rate for the product as a whole today. The official docs alone show why developers need to check model and provider separately. OpenRouter supports choosing providers per model, lets you target a provider's regional or special execution routes with separate identifiers, and can filter candidates by whether they support a parameter. [1]

LayerWhat it decidesWhat is easy to confuse
Model selectionThe model ID to requestThe same model ID does not mean a single serving provider
Provider selectionThe service and execution route that runs the modelA priority order is not an allowlist
Model fallbackOther models to try if the first model returns an errorSeparate from switching providers for the same model
Application validationWhether the result lets the next step of the task proceedHTTP success and task success are judged separately

A fallback is an attempt at an alternative route when the original one is unavailable. OpenRouter's models array tries other models in order. The official docs say the model that was finally used is returned in the response's model field and the request is billed for that model. The provider settings in this report are a separate set of rules for choosing providers. [2]

3. A priority order is not an allowlist

The field names below are as they appear in the JSON body of a Chat Completions request; SDKs may spell them differently. Everything happens within the candidates that actually serve the model and pass your account and request filters. None of these settings makes a service outside that candidate list available. [1]

SettingRole in the official docsOperational reading
provider.orderTries the listed providers first, in orderWith default settings, other eligible providers can also become fallback providers
provider.allow_fallbacksDefault true. false blocks moving on to providers outside the listIf you set an order, do not read false as also turning off attempts at the next provider within that order
provider.onlyThe providers allowed for the requestApplied together with the account's allowlist. A provider must satisfy both
provider.ignoreThe providers excluded for the requestCombined with the account's exclusion list

Listing the same two providers can give different results

A, B and C in the next table are hypothetical providers for illustration, not real API identifiers. Assume all three serve the chosen model and pass every other filter. The examples do not configure switching to other models through models.

SettingIf A fails and then B fails tooWhat the choice means
order: [A, B], default fallbacksC can become an eligible fallbackSets a priority but keeps fallback routes wide
order: [A, B], allow_fallbacks: falseDoes not move on to CTries A and B in order only, and accepts an error if both fail
only: [A, B] and order: [A, B]C is outside what is allowedStates the allowed scope and the priority order separately

The official docs say that if no provider satisfies both the account allowlist and the request's only list, the request fails with HTTP 404. So when you get a 404, do not just look for a typo in the URL; also check the model's provider list against the combination of account and request filters. [1]

A provider slug is the string you put in routing settings. A base slug can cover several execution routes within the same provider that differ by region or processing mode. To target a specific region or variant, copy the exact full slug from the model's detail page. Routes split by service tier, such as priority and flex processing, also have their own selection rules. So listing one company name does not mean you have pinned requests to a single execution route. [1]

Restriction has an availability cost. If both allowed providers are unavailable, getting an error may be the intended behavior. Whether to widen the list automatically, queue the work or return a failure in that situation has to be decided before deployment.

4. Where parameter and data policies apply

The default for provider.require_parameters is false. The official docs say that providers that do not support some parameters can still receive the request, and that parameters a provider does not support may be ignored. Setting it to true limits candidates to providers that support every parameter in the request. This is a rule for choosing providers by what they support; it does not guarantee that the results are accurate. [1]

Even at the default, tools, response_format and verbosity have a built-in filter based on support. If the model has providers that support them, only those providers remain as candidates. But if none of the model's providers supports the item, the docs say the request can be sent anyway with the item ignored, instead of the model being dropped from the candidates. For features that must be applied, require them explicitly instead of relying on the default preference rule alone. [1]

RequirementSetting to checkWhat still needs checking
Support for request parametersrequire_parameters: trueWhether the actual response format and tool arguments meet the task's conditions
Restricting providers by data collection policydata_collection: "deny"The provider policies on the model detail page and the terms of each execution route
Restricting to zero data retention (ZDR) routeszdr: trueThe policies of plugins, external tools and your application's logs

ZDR (Zero Data Retention) is a policy under which the provider does not retain data. OpenRouter's ZDR filter restricts selection to model inference routes that have this policy. However, the official docs state explicitly that the filter does not apply to plugins and tools such as web search. They also say in-memory prompt caching is not treated as retention and is therefore allowed. So do not treat zdr: true as a switch that removes logs, caches and tools across your whole system. [3]

A no-training policy is also not the same as a no-retention policy. The OpenRouter docs distinguish routes that do not train on data but do retain it for reasons such as abuse detection. zdr: false in a request does not turn off ZDR that is enabled in account settings or administrative rules. If either side requires it, the restriction applies. [3]

5. How to check the actual route and response

After reviewing the configuration, check what actually happened. The official Router Metadata doc says you can receive routing information by sending the request header X-OpenRouter-Metadata: enabled. The openrouter_metadata field in the response shows the requested model, the candidate providers, the selected provider and details of each attempt. [4]

FieldMeaning in the docsWhat to watch in production
requestedThe model identifier the client sentCompare it with the actual model in the response
endpointsThe candidates considered, and whether each was selectedWhether the provider you expected was selected
attemptIn a successful response, the number of the attempt that succeededIf it is greater than 1, check whether earlier attempts failed and the request fell back
attemptsOn fallback, a record of provider, model and status. An optional fieldWhen present, log it along with the earlier failed routes

The metadata is not present in every response. The docs say the field is stripped when a cached response is replayed, so that stale routing information is not exposed. It can also be missing for some errors that occur before the request reaches the router, and for internal errors. In streaming responses it arrives in the final chunk, so if you read only the first part and close the connection, you may never see it. Do not assume that missing metadata means no fallback occurred. [4]

Separately from the routing record, your application needs its own conditions for a valid result. The operator's post describes cases where the response was HTTP 200 but had nothing to show the user. Rather than turning that into a general failure rate, we suggest setting success conditions that fit your own task, as follows. [5]

  • For a call that answers a user, check that the expected answer is there. With streaming, judge only after assembling everything up to the final result.
  • In a tool-calling step, an empty body can be normal if there is a valid tool call. Check the tool name and the argument format before executing it.
  • If you need structured output, check not just the JSON syntax but also the required fields and business rules.
  • Even if the result is incomplete, do not blindly rerun external tool actions. Distinguish between re-requesting a model response and external actions that may already have run.

Preventing duplicate execution of external actions is covered in our report on agent retry design. This report focuses on confirming which response came back over which route.

6. Pre-production checklist

Below is the order of checks our editors derived from the official rules and the operator's account. It is not a procedure for ranking new models by performance; it is a procedure for confirming that actual behavior matches the scope you decided to allow.

  1. Write the model list and the provider list separately. Record the model IDs you use, the actual providers, and whether you require a specific region or variant route.
  2. Make the priority order and the allowed scope explicit. Check whether you have only order, or whether you need only or a fallback restriction. Look at how this combines with your account-wide settings too.
  3. Define required features and data conditions. Express non-negotiable conditions such as tool calling, structured output and ZDR as filters, and confirm that some candidates still meet them.
  4. Test the case where even the last allowed route fails. Use harmless test requests or mock responses to check error handling, queuing and alerting. Make sure unreviewed routes are not added automatically.
  5. Run comparisons from the same location as production. Match the network location and tool configuration, and check normal tasks, empty responses and tool-argument errors together. Do not judge stability from a request that succeeded once.
  6. Log the final model, selected provider, number of attempts and result validity together. Record missing metadata as a separate state, and do not copy raw inputs or credentials into logs unnecessarily.
A small place to start: Lay out the provider settings of one current request and explain which providers it can go to if the first provider fails. Once you check whether the settings match the actual routing record, the scope you should restrict next becomes concrete.

7. What this is not yet

  • We did not measure per-provider performance ourselves. The operator's experience is a record about that service, that time and those models. We did not turn the numbers in that post into a current provider ranking or a general failure rate.
  • We keep the docs' description of features separate from how an actual account behaves. We checked the official docs on 2026-09-12 but made no paid API calls and changed no account settings. Candidate providers and supported features can change.
  • We did not calculate how much availability improves. We described the structural relationship that more restriction leaves fewer fallback candidates; we give no figures for improvements in failure probability or response latency.
  • This report does not treat ZDR as a retention guarantee for the whole system. It describes OpenRouter's policy categories and where they apply. Plugins, external tools and your own logs need to be checked separately.
  • A successful HTTP status alone does not decide task success. Some valid responses contain only a tool call, so we do not make an empty body the failure condition for every task.
  • The interest signal is a limited observation. We looked at the HN response and at visibility in Korean search results; we did not confirm overall user search volume or that this was the top topic of interest in Korea.

8. Sources

SourceWhat we checkedType and date
[1] Provider Routingorder, only, ignore and fallbacks; slugs; parameter and data filtersOpenRouter official docs · checked 2026-09-12
[2] Model FallbacksSwitching between models; the response's model field and billingOfficial docs · checked 2026-09-12
[3] Zero Data RetentionScope, exclusion of plugins and tools, in-memory caching, account settingsOfficial docs · checked 2026-09-12
[4] Router MetadataRequest header, response fields, and the exceptions for caching, errors and streamingOfficial docs · checked 2026-09-12
[5] So you want to use OpenRouter?The Olly operator's provider-specific problems and outage experience with restricted routesOperator's first-hand account · published 2026-09-07
[6] HN discussion663 points and 182 comments when we chose the topicCommunity response · observed 2026-09-12 (KST)

Product behavior is attributed to the official docs, and the operating case to its author. The hypothetical-provider examples and the checklist are our editors' explanations and suggestions, not results of our own performance measurements.

Newsletter

The week’s new reports, every Sunday

One email a week with that week’s reports, skipped when nothing new came out. Nothing but report news.

Used only to announce new reports. Unsubscribe any time. Privacy Policy
Publisher

Eazler AI Lab is the AI engineering journal of Eazler Inc. We read primary sources in full, and say so when something is unverified.

Editorial standards and method →

We also post report summaries on Threads: @eazler.inc.

Building or adopting AI agents? hello@eazler.com