Your gateway's public model list is a contract. Most of them break it quietly. A developer spent a day calling the public model-list endpoints of four LLM gateways twice, twenty minutes apart, and compared the responses against vendor documentation, finding that these lists change silently and are treated as contracts they do not honor. The same public endpoint returned 477 models on 22 September and 199 models on 29 September, while OpenRouter's list went from 445 to 460 models in ten days, and one gateway's response schema dropped the `capabilities` field entirely, silently breaking every derived metric built on it. The developer recommends dating any figure pulled from an endpoint and using optional chaining such as `capabilities?.tool_calling` so a missing key does not crash clients. Every LLM gateway publishes an endpoint that lists what you can call. Clients read it, pricing pages quote it, comparison articles count it, and nobody treats it as an interface that can change. That is the mistake. I spent a day calling four of them and comparing what came back against what the vendors' own documentation says. On 29 September 2026 I called the public model list of each gateway, twice, twenty minutes apart, with no API key, and compared the response against whatever the vendor documents about it. Nothing here needed an account, which is the point — a list that requires a key to read is not a public list. Five things, in the order they tend to bite: This is the cheapest check and the one that fails most often, because it costs nothing to verify and almost nobody does. An OpenAI-compatible client appends its own path. The Python SDK takes base url="https://example.com/v1" and then calls /chat/completions on top of it; the OPENAI BASE URL environment variable behaves the same way, which the openai-python README https://github.com/openai/openai-python documents. An Anthropic client appends /v1/messages to whatever base you hand it, as the Messages API reference https://docs.anthropic.com/en/api/messages shows. So the base URL is half of a path, and if the vendor writes the wrong half the client gets a 404 that reads like an auth problem. On my own site I had this backwards in one place and right in another: the OpenAI base was correct on the SDK page and wrong in the file written specifically for agents to read, because both were generated from a single JSON registry and the stale value sat in that registry. One wrong entry, two surfaces, one of them broken. The test takes one request, and the status code is the whole answer: curl -s -o /dev/null -w '%{http code} ' -X POST https://example.com/v1/chat/completions A 401 means the route exists and wants a key. A 404 means the route does not exist, and no key will help. That distinction is the entire test. Run it against the Anthropic base too POST