Fix

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.

The error

What the client prints

text
1HTTP 404
2{
3 "error": {
4 "message": "No endpoints found for <model>.",
5 "code": 404
6 }
7}
8
9# The tool-use variant:
10"No endpoints found that support tool use."
11
12# As SillyTavern and JanitorAI print it:
13Proxy error 404 No endpoints found

What 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.

The structural fix

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.
Live

API route, right now

From GET https://api.relayswitch.io/v1/status, the public feed behind /status, generated 2026-11-02T06:27:17.306Z.

ServiceStateLast checkLatencyChecks todayFailures today
APIOperationalNov 2, 2026, 6:07 AM UTC884 ms70

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.

Live prices

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.

ModelInputOutputDeveloper 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.

The switch

curl: check the id, then send

bash
1# 1. Every id with a route, with its price and availability. No key needed.
2curl -s https://api.relayswitch.io/v1/catalog | jq -r '.data[] | select(.id | test("deepseek")) | "\(.id) \(.availability)"'
3
4# 2. Send to one of them. A wrong id gets 404 model_not_found, not a silent miss.
5curl https://api.relayswitch.io/v1/chat/completions \
6 -H "Authorization: Bearer $RELAYSWITCH_API_KEY" -H "Content-Type: application/json" \
7 -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.

FAQs

Questions

From what people ask about this error.

Open the console

A key in under a minute

Get a key

Or email hello@relayswitch.io

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.