OpenRouter "No endpoints found": what the 404 means and the fix
The error that forum threads for SillyTavern, JanitorAI, opencode and aider all end on. It is a 404, so no retry clears it. The three things that cause it, and a catalog where a listed id always has somewhere to go.
What the client prints
HTTP 404{ "error": { "message": "No endpoints found for <model>.", "code": 404 }} # The tool-use variant:"No endpoints found that support tool use." # As SillyTavern and JanitorAI print it:Proxy error 404 No endpoints foundWhat it means
OpenRouter's error reference (read 2026-10-31) defines not_found as "The requested resource (model, file, etc.) does not exist" and 503 as "There is no available model provider that meets your routing requirements". The phrase "No endpoints found" is the message text the 404 carries; it is not listed as a code of its own on that page.
Three things produce it. The id: retired, renamed or misspelled, so nothing serves it. The request: it asks for a capability (tools, a response format, a context length) that no remaining provider of that model offers, which is the "that support tool use" variant. The routing: a provider preference or data-policy setting excludes every provider that could answer.
Clients print it as a proxy error because the request went through one; the proxy is fine.
The retry rule
None. A 404 is deterministic: the same request gets the same answer until the id or the request changes. A retry loop here only adds latency.
Check in order: the model id against the live list; the request without tools and without response_format, to see which one the route lacks; the provider filters, removed.
The structural fix is a catalog that only lists ids with a route and says what each one takes, so the 404 is answered before the request is sent.
A key that fails over, with limits you set
A retry loop treats the symptom. On this key the next route is tried before the error reaches you, every limit is per key, and a failed request costs nothing. From the OpenAPI document, read 2026-10-31.
- Failover before you see it
- A route that fails with a 5xx or a 429 is retried on the next route for the same model. x-uplink-attempts on the answer counts the tries; the price is the model’s own either way.
- Your own fallback list
- models: [...] names up to 5 models tried in order once every route of the one before has failed before a byte was sent. Each bills at its own price when it answers.
- Failed requests are not charged
- A 429, 502 or 503 from this API charges nothing and carries retry-after: back off that long before trying again.
- Limits per key, set by you
- rpm from 1 to 100,000, tpm from 1 to 50,000,000 and concurrency from 1 to 10,000 on each key. Default: 600 requests a minute per key, 50 in flight per account.
- A budget per key
- budget_usd plus a daily, weekly or monthly spend limit. The key stops at its own line with a 402; the rest of the balance is untouched.
- One request id
- x-uplink-request-id on every answer, errors included. Quote it and we find the call.
API route, right now
From GET https://api.relayswitch.io/v1/status, the public feed behind /status, generated 2026-11-02T06:27:17.306Z.
| Service | State | Last check | Latency | Checks today | Failures today |
|---|---|---|---|---|---|
| API | Operational | Nov 2, 2026, 6:07 AM UTC | 884 ms | 7 | 0 |
Every hour the gateway counts the past hour’s real requests to this route: answered or failed. A request answered after a retry counts as answered.
The daily real-model check: 305 of 339 models answered as before, generated 2026-11-02T06:27:17.308Z. Every verdict is on /proof.
The ids this page is about, per million tokens
Four of the ids on this key, read from the catalog at render. Each row in the catalog is an id with a route; availability is read from real traffic.
| Model | Input | Output | Developer list in / out |
|---|---|---|---|
| DeepSeek V4.1 Flashdeepseek-v4.1-flash | $0.06 | $0.18 | $0.30 / $1.20 |
| GLM 5.3glm-5.3 | $0.3276 | $1.0296 | $1.092 / $3.432 |
| Kimi K3kimi-k3 | $0.90 | $4.50 | $3.00 / $15.00 |
| Claude Sonnet 5.5claude-sonnet-5-5 | $1.20 | $3.00 | $2.00 / $10.00 |
Read from the catalog at render. A request that fails over bills at the price of the model that answered.
curl: check the id, then send
# 1. Every id with a route, with its price and availability. No key needed.curl -s https://api.relayswitch.io/v1/catalog | jq -r '.data[] | select(.id | test("deepseek")) | "\(.id) \(.availability)"' # 2. Send to one of them. A wrong id gets 404 model_not_found, not a silent miss.curl https://api.relayswitch.io/v1/chat/completions \ -H "Authorization: Bearer $RELAYSWITCH_API_KEY" -H "Content-Type: application/json" \ -d '{"model": "deepseek-v4.1-flash", "messages": [{"role": "user", "content": "hello"}]}'GET /v1/catalog is the same list this site renders: every id, its price, its availability and its supported_parameters, so a request that needs tools or a JSON schema can be checked against the row first.
A model with more than one route fails over between them before you see an error, and models: [...] names up to 5 fallback ids for when every route of the first has failed. The routing page covers both.
Questions
From what people ask about this error.
A key that does not stop at one host
Failover at the same price, limits and a budget per key, failed requests not charged. Card or crypto, no KYC, no subscription.