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; agent-native x402/MPP pay-per-use, or BYOK on top. - Local proxy. A single binary on your machine, BYOK with your own provider keys. Zero infrastructure dependencies.
Both modes run the same open-source core (Apache 2.0) — the routing engine is identical, so you can start in one mode and switch later without touching your harness.
Self-host or Cloud?
Every core capability works the same either way — Cloud only adds what needs a server you don't run.
- 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 and per-request billing, a managed provider network without provider signups, team workspaces, or an uptime SLA.
| Capability | Self-hosted (OSS) | Cloud |
|---|---|---|
| Universal API + cross-protocol routing | ✅ | ✅ |
| BYOK (bring your own provider keys) | ✅ | ✅ |
| Local / private model serving | ✅ | ✅ |
| Model fallback & provider selection | ✅ | ✅ |
| Model variants & presets | ✅ | ✅ |
| Adaptive routing policies | ✅ | ✅ |
| Guardrails | ✅ | ✅ |
| Observability (OTLP trace + metric export) | ✅ | ✅ |
| MCP & ACP gateways | ✅ | ✅ |
| Structured outputs | ✅ | ✅ |
| Namespace isolation primitive | ✅ | ✅ |
| Managed provider network (no upstream keys needed) | — | ✅ |
| Team seats & per-workspace access control | — | ✅ |
| Hosted observability console | — | ✅ |
| Managed billing (one wallet, per-request) | — | ✅ |
| SLA on the hosted endpoint | — | ✅ |
| Priority support | — | ✅ |
| Agentic payment marketplace | — | ✅ |
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
<Tabs items={['macOS / Linux', 'Homebrew', 'npm', 'cargo']}>
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:
bitrouter skills add bitrouter # via BitRouter's own installer
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.
Onboard via the CLI wizard
For terminal-first setup, launch the wizard:
bitrouterBare bitrouter 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, or prints a one-line status when it is. It never re-onboards a configured user and never silently spawns a daemon. 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:
bitrouter init --yes --provider openai --provider-api-key "sk-..." --harness claude --after serve
bitrouter init --yes --use-detected --harness claude --after serve # accept env keys, run proxy
bitrouter init --yes --api-key "brk_..." --after exit # Cloud key, no launch
bitrouter init --reset # clear credentials, start overEvery flag is documented in the bitrouter 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
bitrouter 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:
bitrouter init # writes ./bitrouter.yaml (override with `-c <path>`)
bitrouter 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:
bitrouter cloud login # RFC 8628 device flow against api.bitrouter.ai
bitrouter 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:
bitrouter models # every model id routable right now
bitrouter route anthropic/claude-opus-4.8 # preview the routing decisionAdaptive 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:
bitrouter 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:
bitrouter policy status # path, digest, writeback mode, bindings
bitrouter policy evolve # dry-run: which routes would materialize
bitrouter policy unlock # permit programmatic writeback
bitrouter policy evolve --apply # atomically republish policy-lock.yaml
bitrouter policy reload # daemon picks it up — no restart
bitrouter 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.
Next steps
How is this guide?