Quickstart
Install BitRouter and get your agent routing in under a minute — pick self-host or Cloud, then onboard via the Agent Skill, the CLI wizard, or manual env keys.
This page gets BitRouter routing for your agent in under a minute. There are two deployment modes, and three ways to onboard either one — the Agent Skill, the CLI wizard, or manual env keys.
- BitRouter Cloud (default). Hosted endpoint at
api.bitrouter.ai. No upstream keys to manage; per-request billing, or BYOK on top. - Local proxy. A single binary on your machine, BYOK with your own provider keys. Basic routing requires no external service.
Both modes use the same open-source routing core (Apache 2.0). The deployment boundary changes, but the client protocol does not, so you can switch modes without rewriting your harness.
Self-host or Cloud?
The routing contract is shared, while operational surfaces follow the deployment boundary:
- Self-host if you already have provider keys, run local/private models, have data-residency rules, or are prototyping solo.
- Cloud if you want no key management, per-request billing, and a managed provider network without upstream provider signups.
| Capability | Self-hosted (OSS) | Cloud |
|---|---|---|
| Universal API + cross-protocol routing | ✅ | ✅ |
| BYOK (bring your own provider keys) | ✅ | ✅ |
| Local / private model endpoints | ✅ | — |
| Model fallback & provider selection | ✅ | ✅ |
| Model variants & presets | ✅ | ✅ |
| Adaptive routing policies | ✅ | ✅ |
| Guardrails | ✅ | ✅ |
| OTLP trace + metric export | ✅ | — |
| Local MCP gateway & server tools | ✅ | — |
| Local ACP adapters | ✅ | — |
| Structured outputs | ✅ | ✅ |
| Namespace isolation primitive | ✅ | ✅ |
| Managed provider network (no upstream keys needed) | — | ✅ |
| Hosted activity and request receipts | — | ✅ |
| Managed billing (one wallet, per-request) | — | ✅ |
BitRouter does not package a separate enterprise suite today. Teams with deployment, security, procurement, or support requirements can contact the founders and help shape the team offering.
Do you need your own provider keys? Only if you self-host with BYOK — a Cloud account needs no upstream keys: one sign-in covers the whole hosted network, billed per request, failed requests not charged. You can also attach Cloud to a self-hosted binary and use both.
Install the binary
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/bitrouter/bitrouter/releases/latest/download/bitrouter-installer.sh | shbrew install bitrouter/tap/bitrouternpm install -g bitroutercargo install bitrouterOnboard via the Agent Skill
For agent runtimes that support skills (Claude Code, Cursor, Codex, Copilot, etc.). BitRouter ships a /bitrouter Agent Skill so the agent can install, configure, migrate to, and troubleshoot BitRouter on its own — the skill carries the facts that drift easily (the listen port, env var names, the provider/model slash form, which subcommands exist), and it lives in the main repo at skills/bitrouter/, kept in sync with the code in the same change. Install once:
npx skills add bitrouter/bitrouter # via the generic skills CLIThen ask your agent: "Set up BitRouter for me." — the agent runs the wizard, picks Cloud by default, and verifies the connection autonomously.
The /bitrouter Skill explains which structured bro command to use. The agent host still owns approval and execution; BitRouter does not publish the local skill directory as an MCP origin server.
Onboard via the CLI wizard
For terminal-first setup, launch the wizard:
broBare bro runs a network-free credential probe — BYOK env keys, the cloud session file, and the local credential store — then launches the wizard when nothing is configured. After setup, it opens the configured TUI conversation. The wizard walks three steps:
- Credentials — sign in to BitRouter Cloud (default), log in to a provider, or paste a BYOK key.
- Harness —
claudeorcodex, installed via the native installer when missing. - Finish — launch the harness, start the proxy at
http://127.0.0.1:4356, or exit.
Every step maps to a flag, so an agent (or CI) can run the whole flow without a human. --yes never blocks: it consumes flag-supplied credentials, reports-and-skips anything that would need interactive OAuth, and emits a JSON result envelope on stdout:
bro init --yes --provider openai --provider-api-key "sk-..." --harness claude --after serve
bro init --yes --use-detected --harness claude --after serve # accept env keys, run proxy
bro init --yes --api-key "brk_..." --after exit # Cloud key, no launch
bro init --reset # clear credentials, start overEvery flag is documented in the bro init reference. The wizard never writes bitrouter.yaml beyond the canned starter template — your routing config stays yours to edit.
Run self-hosted
Set your provider keys in the environment and start the proxy:
export OPENAI_API_KEY=sk-... # ANTHROPIC_API_KEY / GEMINI_API_KEY also work
bro start
# Proxy running at http://127.0.0.1:4356BitRouter auto-detects any key set in the environment — no config file needed. Any provider whose key is present is immediately available. See BYOK for the full list of recognized variables, or local & private models to point BitRouter at Ollama, vLLM, or LM Studio for free.
For advanced routing rules, guardrails, or multi-account failover, scaffold a config file:
bro init # writes ./bitrouter.yaml (override with `-c <path>`)
bro startUse BitRouter Cloud
Sign in to a BitRouter Cloud account from the terminal — one account covers every model the hosted network offers, with no upstream provider keys required:
bro cloud login # RFC 8628 device flow against api.bitrouter.ai
bro start # the `bitrouter` provider auto-enables once signed inCloud is not a different binary — it's an account you attach. Signing in from a self-hosted binary routes Cloud-managed models alongside your BYOK keys, and you can add or remove the Cloud account at any time without affecting the binary's self-hosted capabilities. You can also point an agent straight at the hosted endpoint without running a local binary at all. See the Supported Models catalog for pricing.
Point your agent at the proxy
However you start it, BitRouter is a drop-in proxy. Point your agent runtime at the proxy base URL — http://127.0.0.1:4356 when self-hosting — and every model call routes through BitRouter with no harness changes.
Verify with a request:
curl http://127.0.0.1:4356/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4o",
"messages": [{"role": "user", "content": "Hello!"}]
}'Point any OpenAI-compatible runtime at http://127.0.0.1:4356/v1 to route through BitRouter.
Two commands make the routing decision itself legible:
bro models # every model id routable right now
bro route anthropic/claude-opus-4.8 # preview the routing decisionModel selectors use two similar-looking forms for different jobs:
| Form | Meaning | Example |
|---|---|---|
provider/model | Stable logical model id; BitRouter may route it through any eligible provider | anthropic/claude-opus-4.8 |
provider:model | Explicit provider pin for local routing | anthropic:anthropic/claude-opus-4.8 |
Use the slash form by default. Use the colon form only when you intentionally need one configured provider, such as a subscription-backed route. See Routing for the complete resolution order.
Adaptive routing
Everything above is a static router. The adaptive half — the learn step of the act → observe → evaluate → learn loop — is opt-in, deterministic, and adds no LLM call to the path. Its artifact is policy-lock.yaml, living next to bitrouter.yaml: Git owns its history; the local database owns the evidence.
One command scaffolds everything:
bro policy init coding --preset coding --economy moonshotai/kimi-k2.7-codeThat writes a two-tier table (strong = your preset's model, economy = the cheap one), clamps tool-carrying requests to the strong tier so a downgrade never strands a tool call, and binds the policy to the preset in bitrouter.yaml with writeback: locked. Selecting the preset as the model is the entire opt-in boundary — bare model requests are never touched by a policy:
curl http://127.0.0.1:4356/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "@coding", "messages": [{"role": "user", "content": "..."}]}'Each request is fingerprinted by loop step (opening, after_<tool>, midstream) and resolved fingerprint → tier → model. An unmatched fingerprint falls back to default_tier, and the table starts conservative: everything routes strong until evidence says otherwise.
Learning from live traffic
With adequacy enabled, every request through a policy-bound route is classified by outcome and recorded against its fingerprint — deterministically, with no LLM judge in the path. Two halves act on that signal:
- Escalation (the safety half) — a downgraded fingerprint that hard-fails
escalation_thresholdconsecutive times is pinned up to the strong tier. Pins decay after a cooldown. - Exploration (the aggressive half) — with
explore_enabled, roughly 1-in-explore_intervalcandidate requests is trialed on the economy tier;explore_thresholdconsecutive adequate trials qualify that fingerprint for the cheap tier. A failed trial escalates and stops.
# policy-lock.yaml
adequacy:
enabled: true
escalation_tier: strong
escalation_threshold: 2
pin_cooldown_secs: 1800
explore_enabled: true
explore_tier: economy
explore_threshold: 3
explore_interval: 5The evidence rule is asymmetric: negative evidence escalates immediately, while a cheaper route needs repeated success before it becomes effective. A policy with adequacy off behaves exactly like its deterministic table.
The signal itself — the outcome classes it records, the per-request cost metering alongside it, and the objective-scored eval engine landing on top — is Evaluation.
Publishing what it learns
Qualified downgrades live in the database until you publish them. The cycle is explicit and digest-checked:
bro policy status # path, digest, writeback mode, bindings
bro policy evolve # dry-run: which routes would materialize
bro policy unlock # permit programmatic writeback
bro policy evolve --apply # atomically republish policy-lock.yaml
bro policy reload # daemon picks it up — no restart
bro policy lock # forbid programmatic writes againevolve --apply only adds qualified routes — it never overwrites or removes anything you or Git wrote, and a detected intervening edit aborts the publish instead of clobbering it. Commit the result and the improved table is in Git, where a policy belongs.
bro policy create + bro key sign are a different surface — per-key access control (allowed models, budgets, rate limits), not routing. See Guardrails.
Next steps
How is this guide?