Your AI Control Plane. Self-hosted, in a single Rust binary: one endpoint speaks every major SDK; fault-aware circuit breaking and in-flight failover keep your app serving when your providers aren't.
📖 Docs: getbusbar.com
⚡ Install: curl -fsSL https://getbusbar.com/install.sh | sh
🐳 Docker: getbusbar/busbar — FROM scratch, multi-arch, cosign-signed
📊 Footprint: a tiny FROM scratch image (see the image-size badge above) · sub-millisecond request handling — live benchmarks carry the current throughput, latency, and memory figures for this release
🤖 Agent-readable: getbusbar.com/llms.txt
Busbar sits between your application and every AI provider. Point any SDK at one URL (OpenAI, Anthropic, Gemini, Bedrock, Cohere, or the Responses API) and Busbar routes each request to the backends you chose, translating losslessly between protocols where they differ: chat, embeddings, images, audio, and moderations. When a provider fails, it keeps serving.
Stable. The SemVer-protected contract is the RUNTIME: the data-plane HTTP surface your application integrates against and the six wire-protocol contracts. Those do not break inside a major version. The
config.yamlis an OPERATOR deployment artifact (like nginx or postgres config), explicitly outside the SemVer freeze: it MAY change between releases, always with a migration path (busbar --migrate-config) and a loud fail-closed boot on an outdated config, never a silent behavior change. The admin API carries its own contract version (/api/v1/admin); a break there is expressed by that contract version, not the binary version. Every release ships an SBOM and a build-provenance attestation. Apache-2.0. (Current version: the Release badge above, never hand-written, so it can't go stale.)
Your code already speaks OpenAI (or Anthropic, or Gemini). Swap the base URL:
- client = OpenAI(api_key=OPENAI_KEY)
+ client = OpenAI(api_key=BUSBAR_TOKEN, base_url="http://busbar:8080")
# `model` now names a single model OR a pool you define in config
# (e.g. "fast" = 80% Claude / 20% GPT-4o, Gemini on failover)
client.chat.completions.create(model="fast", messages=[...])That request left your app as OpenAI. It may have been served by Anthropic, and it came back as OpenAI, translated in both directions. If Anthropic had returned a 429 before the first byte, Busbar would have moved on to the next pool member without your client noticing. The model name is a config value, not a code dependency.
- Six wire protocols, lossless in both directions; any client protocol reaches any pool → Protocols
- Fault-attributed circuit breaking and streaming-safe in-flight failover → Reliability
- Weighted pools with smooth weighted round-robin, session affinity, and per-lane concurrency caps → Reliability
- Routing policies. Five built-ins, your own
kind: hookplugin, or an out-of-process sidecar (socket or webhook). A policy sees each member's cost, latency, live concurrency, budget, and rate headroom, and a failing policy falls back instead of blocking → Routing - Native TLS and optional mTLS, terminated by Busbar itself, with no reverse proxy in front → Security
- Governance when you want it: signed expiring keys, hierarchical groups with request / token / budget / concurrency limits, spend tracking → Governance
- A verified provider catalog, plus any provider on the six protocols in a few lines of YAML → Providers
- Hardening throughout: SSRF guards, constant-time auth, SHA-256 key storage, secrets never logged → SECURITY.md
- Observability over open standards: Prometheus
/metrics, OTLP traces, a per-request audit webhook → Configuration
Busbar shares an arena with LiteLLM and OpenRouter, but it was built reliability-first, and the differences are bigger than a feature list. The honest comparison lives at Why Busbar.
curl -fsSL https://getbusbar.com/install.sh | sh # busbar + providers.yaml into ./A minimal config.yaml. Keys come from environment variables; the config names the variable and never holds the key:
providers:
anthropic: { api_key: { env: ANTHROPIC_KEY } } # the NAME of the env var, not the key
models:
claude: { provider: anthropic, max_concurrent: 10 }
pools:
fast: { members: [ { model: claude, weight: 1 } ] }export ANTHROPIC_KEY=sk-ant-...
BUSBAR_PROVIDERS=./providers.yaml BUSBAR_CONFIG=./config.yaml ./busbar
curl -s localhost:8080/v1/chat/completions -H 'content-type: application/json' \
-d '{"model":"fast","messages":[{"role":"user","content":"Hello!"}]}'Full walkthrough → Getting Started
Full documentation is at getbusbar.com (agent-readable at llms.txt). Contributor docs (architecture, internals, ADRs) live in docs/.
Single Rust binary, MSRV 1.87. Contributions welcome (CONTRIBUTING.md). Licensed Apache-2.0 (LICENSE): permissive, commercial-friendly, with an explicit patent grant.
