How it works Features Docs Compare Blog GitHub
Self-host it Sign up
Open-source LLM gateway · self-hosted

One endpoint for every model.

Point your agents at one URL with one key. polyrouter routes each request to the right model across your providers — explicit-first, with fallbacks, hard spend limits, and honest cost tracking. Your keys, your box, zero markup.

$ curl -fsSL https://polyrouter.app/install.sh | sh
Self-host it → View on GitHub
AGPL-3.0 OpenAI + Anthropic compatible Metadata-only Multi-arch Docker image
localhost:3001
Overview
last 24 hours
Live /v1
Overview · 24h
24h 7d 30d
Spend · 24h
$37.14
6 flagged ~estimated
Requests
48,231
 
Tokens
4.21M
2.86M↑ 1.35M↓
Success rate
99.4%
fallback 0.6% · escalated 1.2%
Requests · 24h
00:0006:0012:0018:00now
Spend by model
spend tokens
claude-sonnet-5$18.90
gpt-5-mini$7.60
gpt-5$3.80
claude-haiku-4.5$2.74
llama-3.3-70bfree
Providers anthropic openai groq ollama · local
Recent requests
View all
TimeModelProviderTierDecided byTokensCostLatencyStatus
12:04:41claude-sonnet-5anthropicbalancedstructural1.2k↑ 380↓$0.00931.8sOK
12:04:38gpt-5-miniopenaifastheader840↑ 210↓$0.00200.7sOK
12:04:35llama-3.3-70bgroqdefaultdefault2.1k↑ 512↓$0.00101.1sFallback
12:04:31claude-sonnet-5anthropicexplicit900↑ 140↓$0.00711.4sOK
12:04:28gpt-5openaibalancedcascade 1.5k↑ 620↓$0.01902.3sOK
The dashboard overview for a self-hosted instance: navigation across requests, costs, agents, providers, routing, limits and users, with the last 24 hours summarised.
The dashboard overview — KPI tiles, the requests chart, spend by model, provider health, and recent requests with the layer that decided each one.
How routing works

Explicit-first. Clever when you want it. Never fragile.

Precedence is dead simple — first match wins. Whatever decides, your budgets and cost recording still apply, and anything that resolves to a tier also gets that tier's ordered fallback chain. All five phases →

01
Explicit model
Name a model in the request and it's always honored. This is the reliable core.
02
Header rules
Send x-polyrouter-tier: fast to pin a request to a tier's ordered chain — or match your own headers with rules you configure.
03
model: "auto"
Smart layers pick for you — L1 structural by default, plus opt-in L2 semantic and opt-in L3 cascade (cheap first, escalate on a failed quality check). A workload target — a whole class pinned to a tier or model — is claimed before any of them.
04
default tier
The guaranteed catch-all. If a smart layer is unavailable, auto quietly degrades here.
Workload · what kind of work it is, recorded on every auto request
code vision structured research writing the dashed two need the semantic module detection is never keyword-based
Classification alone routes nothing. Bind a class to a tier or model with a Workload target and a matching request is claimed before the band targets, L2 semantic and the L3 cascade — recorded as workload. Or scope an auto_high / auto_low band to one class: for a request of that class the scoped rule decides — never a silent swap to the generic target — and the cascade plans both legs inside the same class. A request that matches nothing records none: telemetry only, never routable.
Fallback chain · tries in order until one responds
claude-sonnet-5 → on failure → gpt-5-mini → on failure → llama-3.3-70b drag-to-reorder in the dashboard
Degrades, never fails
Every smart layer falls back to explicit or default. A request never fails because routing tried to be clever.
Never swapped mid-stream
Fallbacks happen before the first token. Once streaming starts the model is committed — no silent swaps.
See everything polyrouter does →
The console

Every request. Every decision. Visible.

Filter by how a request was routed, or by fallback and escalation — then open any row: the inspector shows the routing reason verbatim, the workload class the router recorded, tokens, snapshot-priced cost, and latency.

localhost:3001
All Explicit Auto Fallbacks Escalated 25 shown+ · click a row to inspect the decision
TimeModelProviderDecided byCostLatency
12:04:41claude-sonnet-5anthropicstructural$0.00931.8s
12:04:38gpt-5-miniopenaiheader$0.00200.7s
12:04:35llama-3.3-70bgroqdefault$0.00101.1s
12:04:31claude-sonnet-5anthropicexplicit$0.00711.4s
12:04:28gpt-5openaicascade $0.01902.3s
12:04:24claude-sonnet-5anthropicworkload$0.00841.6s
12:04:19claude-haiku-4.5anthropicsemantic$0.00100.5s
12:04:15llama-3.3-70bgroqdefault$0.00101.0s
The requests list, filterable by how each was decided — explicit, auto, fallback or escalated — showing the model, provider, deciding layer, cost and latency per row, each expandable into its full decision.
Every field above is metadata — tokens, snapshot-priced cost, latency and the routing decision. Prompt and response bodies aren't stored unless you turn on encrypted body capture (self-host only, off by default).
Built for production

Reliability, cost control, and privacy — by default.

ROUTING
Explicit-first routing
Name a model and it just works. Layer tiers and auto on top — every layer degrades back to explicit.
RESILIENCE
Fallbacks & circuit breakers
Ordered fallback chains and Redis-backed per-provider breakers with half-open probes that survive long streams.
BUDGETS
Budgets that block
Day / week / month limits, global or per-agent, enforced with atomic Redis counters across every instance.
COST
Immutable cost records
Every request snapshots its unit price at request time. Later catalog updates never rewrite history.
PROTOCOLS
OpenAI + Anthropic
One base URL, any SDK. Cross-protocol translation is locked by a golden-file contract suite.
PRIVACY
Metadata-only, self-hosted
Metadata only by default — bodies aren't stored unless you turn on encrypted body capture (self-host only, off by default). Credentials encrypted at rest, egress SSRF-guarded.
Explore all features in depth →
Self-host in minutes

Your keys. Your box. One container.

Requires Docker with Compose v2. The first account you create becomes the admin.

1Install
curl -fsSL
  https://polyrouter.app/install.sh | sh
Boots the SPA, API and proxy next to PostgreSQL 16 + Redis.
2Mint an agent key
Agents → New agent

poly_9f2cKq3… # shown once
Sign up, then create a key. Rotate any key with one click.
3Point your agent
curl https://you/v1/chat/completions \
  -H "Authorization: Bearer poly_…" \
  -H "Content-Type: application/json" \
  -d '{"model":"auto",
       "messages":[…]}'
Any OpenAI or Anthropic SDK that takes a base URL works unchanged.
Read the full quickstart →
How we compare

polyrouter vs. alternatives

Two open-source gateways making different bets on routing — plus a closed hosted proxy for contrast.

polyrouterManifestHosted proxy
Automatic routingSmart auto — L1 structural by default, opt-in L2 semantic + L3 cascade, per-workload targets, degrades safelyCustom tiers · rule-based retiredVaries
Harness system promptsFingerprinted & subtractedPrompted the move to custom tiers
Tier pinningx-polyrouter-tierx-manifest-tierVaries
Prompt & response dataMetadata only by defaultConfigurableOften logged
Where it runsSelf-host · one containerSelf-host or managed CloudManaged cloud
CostFree & open source · BYOKFree & open source · paid CloudPer-token margin
Lock-inLow · AGPL-3.0Low · open sourceHigher · proprietary
On routing
Manifest — an open-source gateway like polyrouter — recently retired its rule-based complexity and specificity routing after finding that large harness system prompts (from tools like OpenClaw) tended to skew requests toward the top tier, and that static rules struggled outside English.
Manifest's answer is explicit custom tiers, deliberately skipping AI-based routing to avoid its added latency and cost.
polyrouter makes a different bet — keep automatic routing but harden it: its L1 structural layer excludes the harness system prompt from scoring outright and subtracts each agent's own rolling size baseline, so boilerplate can't inflate complexity.
It runs sub-millisecond at zero cost and always degrades to explicit or default.
Same problem, two reasonable answers.
Manifest's announcement github.com/mnfst/manifest
Coming soon
Don't want to run it yourself?
Polyrouter Cloud is on the way — the same router, fully managed.
You're on the list — we'll email you when Cloud opens.
Please enter a valid email address.
FAQ

Questions, answered.

Does polyrouter store my prompts?+

By default, no — only metadata (tokens, cost, latency, routing decision) is recorded; prompt and response bodies stay out of the database. Self-hosted instances can optionally enable body capture: encrypted at rest, off by default, behind an explicit consent gate, retention-bounded, and self-host only — cloud instances never capture.

Which providers work?+

Any OpenAI- or Anthropic-compatible endpoint: BYOK API keys, custom endpoints, and local models. You can also connect a Claude Pro/Max or ChatGPT Plus/Pro subscription over OAuth instead of paying per token. Cross-protocol requests are translated automatically.

Can it use my Claude or ChatGPT subscription?+

Yes — connect a Claude Pro/Max or ChatGPT Plus/Pro subscription through a guided OAuth wizard instead of pasting a token. Access and refresh tokens are stored encrypted at rest and auto-refresh safely across requests and instances; if a grant is revoked, a one-click Reauthorize reconnects it while your fallback chain keeps serving. One caveat: using flat-rate consumer subscriptions programmatically may violate the provider's ToS, so pair one with a pay-per-token fallback (the dashboard surfaces this). Subscription routing →

How does automatic routing decide?+

Explicit routing comes first — a named model or tier always wins. For model:"auto" it runs L1 structural by default (sub-millisecond local features — the harness system prompt is excluded from scoring and the agent's own rolling size baseline is subtracted). L1 also records a workload class — what kind of work the request is: code, vision or structured in the baseline, never by keyword. Bind a class to a tier or model and that Workload target claims the request before the bands, L2 and the cascade; you can also scope an auto_high / auto_low band to one class. Two more layers are opt-in via ROUTING_AUTO_LAYERS: L2 semantic (a local embedding that refines only what L1 finds ambiguous — needs the -semantic image, and the same opt-in adds the research and writing classes) and L3 cascade (try the cheap tier, escalate on a failed quality check — inside a class when the band is scoped). A disabled, skipped or faulted layer never fails the request: the decision falls through to the next enabled layer, and to your default tier when none is left. Every decision is recorded in the inspector. How routing works →

How do agents connect?+

One base URL and one poly_ key. Any SDK that accepts a base URL works unchanged — OpenAI clients use /v1, Anthropic clients hit the root. See the docs →

Is there a hosted version?+

Self-host is available today. Polyrouter Cloud — the same router, fully managed — is coming soon. Join the waitlist →

What's the license?+

AGPL-3.0. Run it, self-host it, fork it — if you offer a modified polyrouter as a network service, share your modified source.

What do I need to run it?+

Docker with Compose v2. One container serves the SPA, API and proxy next to PostgreSQL 16 + Redis; a prebuilt multi-arch image is available to skip the local build.