Skip to content

Feature: inject OpenRouter provider.only for BYOK / no-fallback routing #18

Description

@echarrod

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions