Summary
Add support for OpenRouter's provider routing field so requests can be pinned to specific upstream provider(s) — enabling BYOK-only routing and preventing silent cross-provider fallback (e.g. Anthropic → Bedrock, Google → Vertex) that bills credits.
This was previously requested in #8 and closed by the requester (they moved to a different proxy), but the feature was never implemented.
Problem
When using OpenRouter with a BYOK key, OpenRouter can fall back to a different provider serving the same model if the primary provider errors or is rate-limited. That fallback bills OpenRouter credits, even when the user only wants to use their own provider key. The "Always use for this provider" toggle only governs OpenRouter's own key for a given provider; it does not prevent cross-provider fallback.
OpenRouter's documented fix is to send a provider field in the request body:
{ "provider": { "only": ["google-ai-studio"] } }
The proxy already builds the OpenAI request body in internal/converter/converter.go and marshals it directly, so it is well placed to inject this field — but there is currently no way to configure it.
Proposed change
A new env var, OPENROUTER_PROVIDER_ONLY (comma-separated provider slugs), that the proxy injects as {"provider": {"only": [...]}} into every request body when the detected provider is OpenRouter.
Implementation (small, ~3 files):
pkg/models/types.go — add Provider map[string]interface{} json:"provider,omitempty" to OpenAIRequest.
internal/config/config.go — add OpenRouterProviderOnly []string, parsed from OPENROUTER_PROVIDER_ONLY.
internal/converter/converter.go — in the OpenRouter path, set openaiReq.Provider = {"only": cfg.OpenRouterProviderOnly} when configured.
Notes:
allow_fallback is intentionally omitted — OpenRouter rejects it as an unrecognized key inside provider, and only already implies fail-hard (no fallback).
- Provider pinning only constrains the slug. It does not prevent within-slug fallback from a BYOK endpoint to OpenRouter's own pool for the same slug; that still requires the "Always use for this provider" toggle on a Prioritized BYOK key. Worth documenting alongside the feature.
Use case
Running Claude Code through the proxy to Google Gemini via a Google AI Studio BYOK key, with zero OpenRouter credit usage and no silent rerouting.
Happy to open a PR with the implementation + tests if there's interest.
Summary
Add support for OpenRouter's
providerrouting field so requests can be pinned to specific upstream provider(s) — enabling BYOK-only routing and preventing silent cross-provider fallback (e.g. Anthropic → Bedrock, Google → Vertex) that bills credits.This was previously requested in #8 and closed by the requester (they moved to a different proxy), but the feature was never implemented.
Problem
When using OpenRouter with a BYOK key, OpenRouter can fall back to a different provider serving the same model if the primary provider errors or is rate-limited. That fallback bills OpenRouter credits, even when the user only wants to use their own provider key. The "Always use for this provider" toggle only governs OpenRouter's own key for a given provider; it does not prevent cross-provider fallback.
OpenRouter's documented fix is to send a
providerfield in the request body:{ "provider": { "only": ["google-ai-studio"] } }The proxy already builds the OpenAI request body in
internal/converter/converter.goand marshals it directly, so it is well placed to inject this field — but there is currently no way to configure it.Proposed change
A new env var,
OPENROUTER_PROVIDER_ONLY(comma-separated provider slugs), that the proxy injects as{"provider": {"only": [...]}}into every request body when the detected provider is OpenRouter.Implementation (small, ~3 files):
pkg/models/types.go— addProvider map[string]interface{} json:"provider,omitempty"toOpenAIRequest.internal/config/config.go— addOpenRouterProviderOnly []string, parsed fromOPENROUTER_PROVIDER_ONLY.internal/converter/converter.go— in the OpenRouter path, setopenaiReq.Provider = {"only": cfg.OpenRouterProviderOnly}when configured.Notes:
allow_fallbackis intentionally omitted — OpenRouter rejects it as an unrecognized key insideprovider, andonlyalready implies fail-hard (no fallback).Use case
Running Claude Code through the proxy to Google Gemini via a Google AI Studio BYOK key, with zero OpenRouter credit usage and no silent rerouting.
Happy to open a PR with the implementation + tests if there's interest.