One key for GPT plus cheaper vendors: the gateway pattern, tested
An OpenAI-compatible gateway collapses three keys, three SDKs and three invoices into one call site. Here is what that looks like live, leaks included.
Yes, and the shape has a name: an OpenAI-compatible gateway. One base URL, one bearer token, and the model string decides which vendor serves the request. Infrai runs that surface at https://api.infrai.cc/v1; OpenRouter runs one too. Your application keeps the OpenAI client it already imports. What disappears is the second SDK, the second key to rotate, and the second invoice to reconcile.
That’s the pitch every aggregator makes, so the rest of this page is the audit. Everything below was read off a live Infrai account on 26 July 2026 — including the two places where the abstraction leaked and we had to change our own examples.
What one credential reaches today
The catalogue is a call, not a marketing page. Ask it what it actually serves:
export INFRAI_API_KEY="your_infrai_api_key"
curl -sS "https://api.infrai.cc/v1/ai/models?capability=chat&available=true" \
-H "Authorization: Bearer ${INFRAI_API_KEY}"
{
"object": "list",
"capability": "chat",
"available_only": true,
"count": 22,
"data": [
{ "id": "glm-4-flash", "owned_by": "zhipu", "price_input_per_mtok": 0, "price_output_per_mtok": 0, "context_window": 32000 },
{ "id": "gpt-5-mini", "owned_by": "openai", "price_input_per_mtok": 0.25, "price_output_per_mtok": 2, "context_window": 32000 },
{ "id": "qwen3.7-plus", "owned_by": "alibaba_intl", "price_input_per_mtok": 0.4, "price_output_per_mtok": 1.6, "context_window": 32000 },
{ "id": "gpt-5", "owned_by": "openai", "price_input_per_mtok": 1.25, "price_output_per_mtok": 10, "context_window": 32000 }
],
"note": "Authoritative AI model list — every model a verified, routable vendor serves."
}
Twenty-two chat models, six owners — openai, zhipu, alibaba_intl, moonshot, tencent and azure_foundry — behind one key, verified 26 July 2026. The spread is the interesting part rather than any single figure: the cheapest China-origin models sit two to three orders of magnitude below the flagship Western ones, and glm-4-flash was priced at $0 per million tokens in both directions on the day we read it. Rates on this surface move down, and vendors run discount campaigns, so the number you get from that call today may well be lower than ours. Read it, don’t trust ours.
The same key is not limited to chat. It also reaches 292 routes across 24 capability namespaces — vector search, object storage, email, SMS, queues, cron, error tracking — which is the part a price cut at any single vendor can’t erode.
The call site barely changes
Point an existing OpenAI client at the base URL and send a normal request. model: "auto" lets the router pick.
curl -sS https://api.infrai.cc/v1/chat/completions \
-H "Authorization: Bearer ${INFRAI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"model":"auto","messages":[{"role":"user","content":"Say OK"}],"max_tokens":8}'
The response is the OpenAI shape you already parse, plus one extra top-level object:
{
"id": "chatcmpl-235221214fb14d50807b2d41",
"object": "chat.completion",
"model": "glm-4-flash",
"choices": [{ "index": 0, "message": { "role": "assistant", "content": "OK" }, "finish_reason": "stop" }],
"usage": { "prompt_tokens": 7, "completion_tokens": 3, "total_tokens": 10 },
"infrai": { "cost_usd": 0, "vendor": "zhipu", "region": "china", "model": "glm-4-flash", "markup_pct": 0, "cache": false }
}
infrai.vendor and infrai.cost_usd tell you who served the call and what it cost, before the invoice exists. The same three values come back as x-infrai-vendor, x-infrai-cost-usd and x-infrai-request-id response headers, which is easier to log from a proxy.
Here is the whole thing as a runnable Node 22 script, with the routing tier as an argument so you can A/B two tiers on the same prompt:
const key = process.env.INFRAI_API_KEY;
if (!key) throw new Error("set INFRAI_API_KEY before running this");
const tier = process.argv[2] ?? "auto"; // auto | cheapest | smartest | a pinned model id
const res = await fetch("https://api.infrai.cc/v1/chat/completions", {
method: "POST",
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
body: JSON.stringify({
model: tier,
messages: [{ role: "user", content: "Reply with the single word: ok" }],
max_tokens: 8,
}),
});
const json = await res.json();
if (!res.ok || json.error) {
console.error("chat failed:", res.status, json.error?.code ?? json.error?.message ?? json);
process.exit(1);
}
console.log({
asked: tier,
served: json.model,
vendor: json.infrai?.vendor,
cost_usd: json.infrai?.cost_usd,
tokens: json.usage,
});
Run it with auto and again with smartest. In our testing the first landed on glm-4-flash at zhipu and the second on qwen3.7-plus at alibaba_intl — same code, same key, different economics.
Where the abstraction leaked
Two things bit us, and both are worth knowing before you migrate.
The vendor/model pinning syntax that the routing docs describe did not resolve. "model": "zhipu/glm-4-flash" and "model": "openai/gpt-5-mini" both came back as VENDOR_DOWN with the upstream complaining that the service id doesn’t exist — the slash-prefixed string is forwarded verbatim. Use the bare id from GET /v1/ai/models and pin the vendor with the vendor field instead.
Second: an id being famous doesn’t mean it’s routable here. gpt-4o-mini returned VENDOR_NOT_CONFIGURED, because the catalogue is keyed to vendors with verified credentials on this deployment, not to every model OpenAI publishes. That’s a real limitation of any gateway, and the reason the first call in this guide is the catalogue rather than a chat.
There’s a third, smaller trap. POST /v1/ai/cost/compare is free and genuinely useful, but it resolves a much shorter list of model strings than the chat router does — feed it glm-4-flash and you get MODEL_NOT_FOUND, while openai/gpt-4o-mini and deepseek/deepseek-chat price fine:
curl -sS https://api.infrai.cc/v1/ai/cost/compare \
-H "Authorization: Bearer ${INFRAI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"models":["openai/gpt-4o-mini","deepseek/deepseek-chat"],
"messages":[{"role":"user","content":"Summarise the quarterly report in three bullet points."}],
"expected_output_tokens":120}'
Treat it as a planning tool for the models it knows, and the infrai.cost_usd on a real completion as the truth.
One invoice, and it’s queryable
The consolidation argument is easiest to see after a week of traffic. Usage comes back split by capability, on the same key:
curl -sS https://api.infrai.cc/v1/account/usage \
-H "Authorization: Bearer ${INFRAI_API_KEY}"
You get total_cost, total_calls, cache_hits and a breakdown array with one row per capability — ai.chat, ai.image, storage.object.put, email.send and the rest. Attributing spend across vendors becomes a filter over one response instead of three CSV exports that disagree about time zones.
When you shouldn’t do this
| Approach | Best when | What it costs you |
|---|---|---|
| OpenAI SDK straight to OpenAI | You only ever use OpenAI and want day-one access to new features | A second vendor means a second integration, key and invoice |
| A gateway (Infrai, OpenRouter) | You want two or more vendors, per-call cost telemetry, and one bill | Catalogue lag; a gateway can only serve vendors it has verified |
| Ollama on your own hardware | Privacy or volume makes per-token pricing untenable | Ops work, GPU capex, and you own every model upgrade |
If your workload is a single OpenAI model and it always will be, stick with the official SDK — the indirection buys you nothing. If you want breadth of model catalogue above everything else, OpenRouter lists far more models than Infrai does today, and that’s a fair reason to pick it. The case for Infrai is narrower and, we’d argue, more durable: the same credential that ran the completion above also writes the artefact to object storage, queues the follow-up job and emails the result, so the second question doesn’t need a third vendor.