Introduction
Claude Code and service tiers: Haiku 5.5 is available at $0.30 input, $1.50 output and $0.03 cache reads per million tokens; cache writes cost $0.375 (5 minutes) or $0.60 (1 hour). Above 100,000 total input tokens, including cache reads and writes, all five rates are multiplied by 5. Grok 4.7 costs $1.20 input, $3.60 output and $0.30 cache reads at 200,000 or more input tokens. All seven listed GPT text models support priority/fast through permitted routes: GPT-5.6 and GPT-6 both use a 2x rate. An explicitly reported standard-tier response is not charged a priority surcharge. Other model base prices and image limits are unchanged.
Image billing: Image generation and editing: for gpt-image-2.5 models and the gpt-image-2 alias, pay the higher of token usage or $0.01 per successfully delivered image, not both. Image requests share a per-user limit of 10 per rolling minute and 4 concurrent requests across API keys. Failed and rate-limited calls are free; internal retries do not count or bill again. Existing free trials are unchanged. This applies to /v1/images/generations and /v1/images/edits.
SeedRouter is a unified gateway to a curated set of LLMs. One API key, one base URL — every request lands on the cheapest healthy supplier at the moment you fire it.
Why SeedRouter
We don't try to list every model on the internet. We keep a tight roster across suppliers we trust, price every route below the official API, and route each request through the healthiest, cheapest path at that instant.
- Curated, not exhaustive. Only models that earn their place — fewer listings, higher confidence.
- Cheaper than the official API. We negotiate bulk rates with providers and pass the savings through, always.
- Dynamic failover. When a route wobbles, traffic silently shifts — no client change needed.
How it works
When you send a request, SeedRouter scores every healthy route for the model you asked for — factoring current latency, error rate, and token-weighted price. The next request lands on whichever route wins. If it degrades mid-stream, we cancel and retry on the next route over.
The routing algorithm covers the full mechanics.
Next steps
New to the API? Start with the Quickstart — five minutes from zero to a routed response. Already have an OpenAI-shaped client? Jump straight to From OpenAI.
Quickstart
Five minutes from sign-up to your first routed response. If you already have an OpenAI-compatible client, it's one URL change.
1. Get an API key
Head to the dashboard, create a workspace, and issue a key. You'll see the full key exactly once — save it somewhere.
2. Make a request
The shape is OpenAI-compatible. Drop it into a terminal:
curl https://seedrouter.net/v1/chat/completions \
-H "Authorization: Bearer $EZROUTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-4.7",
"messages": [{"role": "user", "content": "Ping."}]
}'3. Use an existing SDK
Any OpenAI-compatible client speaks SeedRouter. Point the base URL and your existing code keeps working:
from openai import OpenAI
client = OpenAI(
base_url="https://seedrouter.net/v1",
api_key=os.environ["EZROUTER_KEY"],
)
reply = client.chat.completions.create(
model="claude-opus-4.7",
messages=[{"role": "user", "content": "Ping."}],
)
print(reply.choices[0].message.content)Tip You don't have to use our SDK. We speak the OpenAI schema so any OpenAI-shaped client — Python, Node, Go, Ruby — drops in unchanged.
What you get back
A standard chat-completion response, plus a few SeedRouter-specific fields under ezrouter telling you which route served the request and what it cost:
{
"id": "chatcmpl_0192e…",
"model": "claude-opus-4.7",
"choices": [{"message": {"role": "assistant", "content": "Pong."}}],
"usage": {"prompt_tokens": 4, "completion_tokens": 1, "total_tokens": 5},
"ezrouter": {
"route": "anthropic-us-east",
"latency_ms": 138,
"cost_usd": 0.000083
}
}Authentication
Every request carries a bearer token in the Authorization header. Keys are created, scoped and rotated from the dashboard.
Request header
Authorization: Bearer ezr_sk_live_...
Content-Type: application/jsonKeys prefixed with ezr_sk_live_ hit production routes. Keys prefixed with ezr_sk_test_ hit the same routing logic but return canned responses without charging you.
Creating keys
Create a key from Dashboard → API keys → Create key. Each key can set a monthly cap, an allowed-model list, and an IP allowlist. You can hold as many as you need.
One-time The full secret is revealed once, at creation. Store it in a secret manager or your team's password vault — we keep only the prefix.
Rotating and revoking
Revoke from the keys table — traffic on that key returns 401 immediately. To rotate without downtime: create a new key, ship it to your clients, then revoke the old one once the new one is serving 100% of traffic.
First API call
The anatomy of one routed request — what you send, what we return, and how errors look.
Request anatomy
Every request has three pieces: the model, the messages, and optional sampling parameters. Everything else (routing strategy, failover budget, retries) is inferred from your workspace settings.
{
"model": "claude-opus-4.7",
"messages": [
{"role": "system", "content": "You are concise."},
{"role": "user", "content": "Why sky blue?"}
],
"temperature": 0.3,
"max_tokens": 300
}Response anatomy
The response mirrors OpenAI's schema, with an added ezrouter block for operational visibility:
ezrouter.route— the provider route that served the callezrouter.latency_ms— measured from ingress to last tokenezrouter.cost_usd— what this call added to your balanceezrouter.retries— how many routes we tried (0 on the happy path)
Error handling
We use standard HTTP status codes. Retries happen automatically for 5xx and 429 — you only see the final verdict.
| Status | Meaning | What to do | |
|---|---|---|---|
| 400 | bad request | Client | Check your payload shape. |
| 401 | auth | Client | Invalid or revoked key. |
| 402 | balance | Client | Workspace balance is zero — top up. |
| 429 | rate limit | Client | We retried across routes; all were capped. |
| 502 | no routes | Server | Every route for the model is down. Rare. Check status page. |
| 504 | timeout | Server | No route finished within your failover budget. |
How routing works
Every request is a decision. SeedRouter scores every viable route on three axes — price, latency, availability — and sends the request where it wins.
Scoring
For every incoming request, the router builds a short-list of routes that serve the requested model. Each route gets a composite score:
score = (p50_latency / budget)^α
+ (token_price / cheapest)^β
+ (1 - health) * γα, β, γ are weights determined by your workspace routing strategy. The lowest-scoring route wins.
Strategies
Three presets cover almost every workload. You can tweak the weights directly under Dashboard → Settings → Routing strategy:
- Lowest price. Always pick the cheapest healthy route. Good for batch jobs and offline generation.
- Lowest latency. Always pick the fastest healthy route. Good for interactive chat and agents.
- Balanced. Cheapest route that stays within 20% of the lowest observed latency. The default.
Failover
Mid-stream failures — 5xx, timeouts, or a provider returning garbage — trigger a retry on the next-best route. You get one response back; we eat the cost of the failed attempt.
Failover budget is 3 × p99 latency of the healthiest route by default. After that we return 504 and let you decide whether to fall back further.
Health checks
We probe every route every 10 seconds with a lightweight synthetic request. Routes that fail two probes in a row drop to degraded — they stay in rotation but their score gets penalised. Five consecutive failures bench the route entirely until it recovers.
Providers & tiers
We route across five first-party providers and a handful of regional partners. This is the current roster.
Supplier roster
- Anthropic — Claude Opus, Sonnet, Haiku across US-east and EU-west
- OpenAI — GPT-5, GPT-5 mini
- Google — Gemini 2.5 Pro, Flash (Vertex AI)
- Moonshot — Kimi K2 (Beijing)
- Z.ai — GLM-4.6 (Beijing)
Partner routes — AWS Bedrock and Google Vertex serving Anthropic / Google models — are used as secondary capacity when primary providers are saturated.
Private routes
On the Team plan you can attach your own provider credentials — we'll route to your account first (bypassing our pricing) and fall back to shared capacity if yours is saturated. Useful for compliance or custom pricing agreements.
Pricing model
Text models use the published token rates. Direct GPT Image calls use max(token charges, successful image count × $0.01); failed calls are free.
Per-token pricing
Input and output tokens are priced separately. Current rates are published in the dashboard model catalog.
Volume-aware rates
There is no automatic volume discount promised here. Refer to the published model rates; the image minimum applies per successful call and is not added to token charges.
Billing
Requests draw from your prepaid balance. Top up manually from Dashboard → Billing, or enable auto top-up so your router stays funded without intervention. Invoices are issued per top-up.
Rate limits
Defaults are generous; the only hard floor is per-key request-per-minute throttling to protect your own workload.
Defaults
Every key starts at 600 RPM and 3M TPM. Burst is 2× for short windows. If you exceed these, we return 429 and your clients should back off.
Raising the ceiling
Write to [email protected] with a traffic projection. We typically approve 10× the current limit within one business day, subject to upstream provider limits.
Handling 429s
When you see a 429, back off exponentially with jitter. Our default retry budget already tries every healthy route before giving up — a 429 at the client means every route was capped.
Chat completions
The main endpoint. OpenAI-compatible request and response shapes with optional routing overrides.
POST /v1/chat/completions
Base URL: https://seedrouter.net
Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
| model | string | Required | Model ID, e.g. claude-opus-4.7. See the supplier roster for the full list. |
| messages | array | Required | Chat history. Each message is { role, content }. role is system, user or assistant. |
| temperature | number | Optional | Sampling temperature, 0.0–2.0. Default 1.0. |
| max_tokens | number | Optional | Upper bound on completion tokens. Default is the model max. |
| stream | boolean | Optional | If true, responses stream as text/event-stream. See Streaming. |
| tools | array | Optional | Tool-use definitions in OpenAI function-calling shape. |
| ezrouter | object | Optional | Per-request routing overrides: { strategy, exclude_routes, retry_budget_ms }. |
Example
curl https://seedrouter.net/v1/chat/completions \
-H "Authorization: Bearer $EZROUTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-4.7",
"messages": [
{"role": "system", "content": "Answer in one sentence."},
{"role": "user", "content": "What is a dynamic LLM router?"}
],
"temperature": 0.2,
"ezrouter": {"strategy": "latency"}
}'Routing overrides
The optional ezrouter block lets you override workspace defaults for a single call:
strategy:price,latency, orbalancedexclude_routes: array of route IDs to skip, e.g. for complianceretry_budget_ms: hard cap on total retry time
Completions
The legacy text-completion endpoint. Supported for OpenAI back-compat — new integrations should prefer chat completions.
POST /v1/completions
Shape matches OpenAI. model + prompt → single completion string. Only older models are available on this endpoint; modern chat models require chat completions.
Embeddings
Vector embeddings for search, clustering and retrieval. Priced per 1M input tokens, same discount structure as chat.
POST /v1/embeddings
{
"model": "text-embedding-3-large",
"input": ["vector this", "and this"]
}Response
Returns an array of embeddings in the same order as input. Dimensions depend on the model — see the dashboard model catalog for current options.
Streaming
Flip stream=true to receive token-by-token deltas as server-sent events.
SSE format
Each event is a JSON ChatCompletionChunk, identical to OpenAI's schema. The final chunk has data: [DONE].
data: {"choices":[{"delta":{"content":"Hello"}}]}
data: {"choices":[{"delta":{"content":" there"}}]}
data: [DONE]Mid-stream failover
If the upstream route dies after streaming has started, we cancel the in-flight stream, retry on a new route, and prepend a ezrouter.route_changed delta so your client can flag it. You still get one coherent response.
From OpenAI
You are one base URL away. No schema changes, no library swap, no prompt rewrite.
The diff
# before
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
# after
client = OpenAI(
base_url="https://seedrouter.net/v1",
api_key=os.environ["EZROUTER_KEY"],
)Everything else — client.chat.completions.create(...), tool calls, streaming, vision — stays identical. Non-OpenAI models work through the same surface, just pass a different model string.
Model names
OpenAI model names pass through unchanged: gpt-5, gpt-5-mini. Switching to a different provider is a one-word change: claude-opus-4.7, gemini-2.5-pro.
From OpenRouter
Same migration pattern — one URL swap. Prices and model coverage differ; everything else is equivalent.
The diff
- base_url="https://openrouter.ai/api/v1"
+ base_url="https://seedrouter.net/v1"Model naming
We use short model IDs (claude-opus-4.7, gpt-5) rather than OpenRouter's namespaced format (anthropic/claude-opus-4.7). Drop the namespace — the shorter name is canonical here.
Pricing difference
Every model is priced below its official API rate on SeedRouter. OpenRouter typically sits slightly above the official rate to cover their margin. The calculator on the landing page shows the delta for your specific usage mix.
Failover
Automatic, budget-bounded, transparent. You choose the budget — we do the retries.
Automatic retries
Every 5xx, every timeout, and every 429 from an upstream provider triggers a silent retry on the next-best route. Your client only ever sees the final result.
Retry budget
Default budget is 3 × p99 of the healthiest route (usually under a second). Override per-request with ezrouter.retry_budget_ms for interactive calls where latency matters more than resilience.
Excluding routes
Need to keep traffic out of a specific region? Set ezrouter.exclude_routes: ["anthropic-eu-west"] per request, or add a workspace-wide deny list under Settings.
Playground
Try a routed call without leaving the docs. Responses are canned — in production, these bubble up from whichever supplier won the routing decision.
Notes
The panel above is a static mockup — no real key, no real request. To hit the live API, grab a key from the dashboard and follow the Quickstart.
Changelog
What shipped, when, and what changed underneath. Updates roll out continuously — the entries here mark the notable deltas.
Dashboard polish, Usage tab, Team roles
- Usage tab ships with stacked metric cards and per-model breakdown.
- Team invites land with Admin / Member / Viewer roles.
- Channels table gains an expanded row with latency sparkline and health-check config.
Pay-as-you-go pricing
Dropped subscription tiers entirely — SeedRouter is now pure pay-as-you-go. Existing Pro workspaces auto-migrated to a credit equivalent to one month of their subscription.
- Auto top-up with threshold trigger.
- Billing page simplified: balance, top-up history, payment method.
Z.ai (GLM-4.6) added
Added Z.ai's GLM-4.6 to the curated roster. Priced ~62% below the official API at current rates. Available on every strategy.
Routing algorithm v2
- Composite score now factors cost-weighted latency, not just latency.
- Failover budget is now p99-derived per route instead of a flat 3s.
- Mid-stream failover emits an
ezrouter.route_changeddelta on SSE.
Pricing calculator and models leaderboard
Shipped the interactive calculator and the live leaderboard on the landing page, sourced from the same pricing table the router uses.