Every provider gives you a key. After the third one, the keys stop being a convenience and start being a system you have to build and maintain. You have N providers, each with its own base URL, its own auth header, its own rate limit semantics, its own error codes, its own billing page. The moment you want to route a request to "the best available model" instead of "the one I hardcoded," you have a routing problem, and that is what a gateway solves.
The problem is not the API, it is the operations
The raw API calls are easy. It is everything around them that compounds:
•Credential sprawl. A key per provider, rotated on different schedules, stored in different secret managers.
•Rate limits. Each provider throttles differently, and their error responses are not consistent, so your retry logic has to special-case each one.
•Usage visibility. Every provider has its own dashboard. No single place shows total spend across all of them.
•Failover. If provider A goes down, moving traffic to provider B means redeploying with a new key and a new endpoint.
None of this is visible in a demo. It shows up in production at 2 a.m. when a provider is down and your retry queue is backing up.
What a gateway actually is
A gateway sits between your application and the model providers. Your app talks to one endpoint with one key. The gateway handles auth, routing, rate limiting, usage accounting, and fallback. To your code it looks exactly like a single LLM API.
+------------------+
| Your app |
+--------+---------+
| one key, one base URL
v
+--------+---------+
| LLM gateway |
| auth / routing |
| rate limiting |
| usage metering |
+--+-----+----+----+
| | |
v v v
Provider A B C
(GPT-4o) (DeepSeek) (Qwen)The important design decision is that the gateway speaks the OpenAI-compatible protocol on the inbound side. That means your existing SDK code does not need a new client library. You change the base URL and the key, and you keep writing normal chat.completions.create calls.
One key, one endpoint, many models
Here is the whole integration on the client side:
from openai import OpenAI
client = OpenAI(
base_url="https://api.token8341.com/v1",
api_key="sk-one-key-for-everything",
)
for model in ["gpt-4o", "claude-3-5-sonnet", "deepseek-chat", "qwen-max"]:
resp = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": "Reply with the word 'ok'"}],
)
print(model, "->", resp.choices[0].message.content)The same key authorizes every model in the catalog. You do not provision four accounts or track four balances. You pay one metered bill, and usage is broken down by model so you can see where the tokens actually went.
The gateway also makes routing a config decision instead of a code change. Want a cheap model for the high-volume lane and a frontier model for the hard lane? That is a mapping in one place:
ROUTES = {
"summarize": "deepseek-chat",
"reason": "qwen-max",
"frontier": "gpt-4o",
}And fallback becomes ordinary control flow rather than a multi-vendor integration:
def call_with_fallback(prompt, primary, backup):
try:
return ask(primary, prompt)
except Exception:
return ask(backup, prompt)When you need a gateway, and when you do not
A gateway is overhead you should not take on if you do not need it. If you use one provider and one model and you have no failover requirement, a direct key is simpler and that is the right call. Adding an extra hop and an extra vendor to the critical path has a cost.
A gateway earns its place when at least one of these is true:
•You use two or more models and want to switch between them freely.
•You need fallback when a provider is down or rate limited.
•You want a single bill and a single place to see spend by model.
•You want to A/B test models on live traffic without redeploying.
If any of those applies, the operational savings outweigh the extra hop. The actual added latency of a well-run gateway is a few milliseconds, small enough that it disappears next to model inference time.
Managed or self-hosted?
One decision worth making deliberately is whether to run your own gateway or rent one. Self-hosted routers like LiteLLM and one-api are excellent and give you full control over routing tables, keys, and logging. They also give you a service to run, monitor, patch, and keep highly available, which is exactly the operational burden you were trying to shed.
A managed gateway inverts the trade. You give up control over the internals and gain not having to operate them: someone else keeps the endpoint up, rotates upstream keys, and absorbs provider outages. For a small team that is usually the right deal. For a larger team with a platform group on staff, self-hosting may be worth it for the auditability alone. Either way, keep the inbound contract OpenAI-compatible so the choice stays reversible.
TokenWorks is built around this idea: one API key, one OpenAI-compatible endpoint at https://api.token8341.com/v1, and a catalog that spans GPT-4o, Claude, Gemini, DeepSeek, Qwen, ERNIE, Doubao, Spark, and Pangu, with metered billing and usage broken out per model.