Pin your OpenRouter provider before it bites you

OpenRouter sells convenience: one API endpoint that “handles fallbacks automatically and picks the most cost-effective option for each request.” You call a single model, and OpenRouter routes you to the best available backend. According to Simon Willison, who flagged a write-up by Mohamed Moustafa, that same convenience can quietly break your app. The problem isn’t the routing itself. It’s that you often don’t know which provider you actually got, and different providers don’t behave the same way.

This guide walks through what can go wrong and how to take back control.

Quick Start

What you’ll learn: why OpenRouter’s automatic routing can produce inconsistent results, and how to lock requests to a specific provider so your model behaves the way you expect.

What you need: an OpenRouter account, a model ID you’re already calling, and access to the API request body where you set options.

Why routing can hurt you

Willison points to the core issue Moustafa raises: providers behind the same OpenRouter endpoint run different serving software, with different optimizations and settings. That means one model ID can return meaningfully different responses depending on who served the request.

Three specific traps stand out:

  • Inconsistent behavior. The same endpoint can serve requests that behave differently, because each backend is configured its own way.
  • Missing vision support. Some providers lack vision capability even for models you’d expect to handle images. Route to the wrong one and your multimodal call fails.
  • Reasoning effort handled differently. The way the reasoning effort option gets processed can vary from provider to provider, so a setting that works in testing may act differently in production.

Why this matters: if you built and tested against one provider’s behavior, an automatic fallback to another can silently change your output, drop a capability, or ignore a parameter you rely on. You may not notice until users do.

Step 1: List the providers for your model

Before you trust a model ID, find out who can actually serve it. Call the /endpoints method, which returns the list of available providers for a specific model ID.

This is your ground truth. It shows you every backend OpenRouter might route you to, so you can check which ones support the features you need, such as vision or your reasoning settings.

Why it matters: you can’t pick a reliable provider until you know the full set of options and their differences.

Step 2: Pin the provider you want

Once you know which backend behaves correctly for your use case, force OpenRouter to use only that one. Use the provider.only option in your request.

This overrides the automatic routing for that call. Instead of letting OpenRouter chase the cheapest available backend, you tell it exactly which provider is allowed to serve the request.

Why it matters: pinning removes the variability. You get consistent serving software, consistent settings, and the capabilities you confirmed in Step 1.

Step 3: Verify the behavior you depend on

After pinning, test the specific features that vary: send an image if you need vision, and confirm your reasoning effort setting produces the result you expect. Don’t assume the pin fixed everything until you’ve watched it work.

Why it matters: the whole point is predictable output. Verification is how you prove you got it.

What stands out here

OpenRouter’s pitch is real, and for quick experiments the automatic routing is genuinely useful. The catch is that “most cost-effective” and “most correct for my app” aren’t the same thing. For anything in production, the abstraction leaks, and the leak shows up as vision calls that fail or reasoning settings that don’t stick.

The fix is cheap. Check /endpoints, pin with provider.only, and verify. You keep the single-endpoint convenience while cutting out the surprises.

Next steps

  • Audit any production app already calling OpenRouter. Log which provider served recent requests and check for silent changes.
  • Build the provider check into your setup: query /endpoints when you adopt a new model, and document which backends pass your feature tests.
  • Treat provider.only as the default for anything user-facing, and reserve automatic routing for prototyping.

Moustafa’s full breakdown, surfaced by Simon Willison, is worth reading before you ship your next OpenRouter integration.

Scroll to Top