Model ids are not portable: api.anthropic.com wants dated ids, Gemini wants its own version strings, and every gateway defines slugs. A 404 here means "this host has no model by that exact string" — the fix is always to ask the endpoint what it serves.
The error
{
"error": {
"type": "model_not_found",
"message": "The model 'claude-sonnet' does not exist or you do not have access to it.",
"code": "model_not_found"
}
}Causes and fixes at a glance
| Cause | Fix |
|---|---|
| Model id from a different host | Each API has its own namespace — copy ids from the endpoint's own model list, not from blog posts. |
| Deprecated/renamed version | Providers retire dated snapshots; pin to a current id and subscribe to deprecation notes. |
| Typo'd or truncated slug | claude-sonnet isn't a model anywhere; exact strings matter. |
| Model exists but is disabled for your key/plan | Some hosts gate models by plan — the list endpoint shows what YOUR key can call. |
List models from the endpoint you're calling
GET /v1/models is the ground truth on any OpenAI-compatible host — it returns exactly the ids your key can use:
curl -s https://api.kunavo.com/v1/models \
-H "Authorization: Bearer $KUNAVO_API_KEY" \
| python3 -c "import json,sys; print('\n'.join(m['id'] for m in json.load(sys.stdin)['data']))"Resolve models at runtime, not hardcoded
Catalogs move (new snapshots, retirements). Resolve the model list at startup, prefer configured slugs with a fallback, and alert when a configured slug disappears from /v1/models instead of 404ing in production.
If you’re calling through Kunavo
Kunavo uses stable human-readable slugs (claude-sonnet-5, gpt-5-6-terra, claude-fable-5) listed at GET /v1/models with per-model metadata, and retired slugs 301 to their successors on the site's model pages so links don't rot. The list endpoint is authoritative — llms.txt says the same to any agent reading it.
Frequently asked questions
Why does the same model id work on one API and 404 on another?
Because ids are namespaced per host: Anthropic's dated ids, Gemini's versioned names and each gateway's slugs are all different strings for related models. Always copy from the target endpoint's own model list.
How do I future-proof against model retirement?
Resolve /v1/models at startup, keep the model id in config (not code), define a fallback chain, and page yourself when a configured id vanishes — that turns a production 404 into a config change.
Related guides
More error semantics live in the error reference; getting a key takes a minute via signing up and the authentication guide.