Overview

Bring any model source under BitRouter — a Claude or Codex subscription, an OpenRouter key, or a model you serve yourself.

A model source is wherever your tokens actually come from. BitRouter puts every source behind one endpoint and one registry, so an agent addresses models by their provider/model id and never sees the difference between a subscription, an aggregator, and a GPU in your closet.

There are three shapes of source, by how you authenticate:

How a source is wired

SourceAuthWhere it's configured
Subscriptions (Claude, Codex)OAuth — your plan's loginbitrouter login <provider> (no key, no yaml)
Aggregators / hosted (OpenRouter, …)Bring-your-own API keyA provider block in bitrouter.yaml
Self-hosted (Ollama, vLLM)Usually none — loopbackA provider block in bitrouter.yaml

Subscriptions skip bitrouter.yaml entirely: bitrouter login anthropic or bitrouter login openai-codex runs the plan's OAuth flow and stores the refreshing token for BitRouter to attach at request time. Everything else is a provider block — an api_base, an optional api_key, and the models that source serves.

# bitrouter.yaml
providers:
  openrouter:                          # an id you pick (or a built-in id)
    api_base: https://openrouter.ai/api/v1
    api_key: ${OPENROUTER_API_KEY}     # resolved from the environment at load
    api_protocol:
      - "*": chat_completions          # upstream wire format
    models:
      - id: openai/gpt-4o

providers is a map keyed by an id you choose; api_base is the source's base URL; api_protocol is the upstream wire format (chat_completions for any OpenAI-compatible host — also the inferred default); each models entry is a model that source serves.

Scaffold a config

Generate a starter bitrouter.yaml (defaults to ./bitrouter.yaml):

bitrouter init

This writes a commented config with skip_auth: true, ready for a provider block. Use -c <path> to write it elsewhere, then follow your source's page to fill in the block. (Subscriptions need no config — just bitrouter login.)

Start BitRouter and send a request

Once your source is wired — a provider block in place, or a subscription logged in — start the proxy. It listens on 127.0.0.1:4356 by default:

bitrouter

Then hit the OpenAI-compatible endpoint with a model id from your config (swap in your provider id / model):

curl http://localhost:4356/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openrouter:openai/gpt-4o",
    "messages": [{"role": "user", "content": "Hello from BitRouter"}]
  }'

The bare model name also works — BitRouter auto-cascades it to whichever active source declares it. The provider-qualified form (openrouter:openai/gpt-4o) pins the request to that exact source.

Mix sources freely. Declare a virtual model whose endpoints list a local source first and a hosted one second: requests run on your own hardware for free and fail over to the hosted model on error or overload — one model name, automatic failover.

For the concepts behind this — provider selection, fallback, and registry detection — see Models and Local & private models.

How is this guide?

On this page