← All posts
Guides

What Is an LLM Gateway? The Six Jobs It Takes Off Your Code

An LLM gateway is one endpoint in front of every model provider that owns six cross-cutting jobs — auth, cost, limits, safety, observability and failover. What it does, what happens to a request inside it, and when you need one.

nRouter team · 11 min read
What Is an LLM Gateway? The Six Jobs It Takes Off Your Code

The short answer: an LLM gateway is a single API endpoint between your application and every model provider. Your code sends one request with one key; the gateway authenticates it, checks money and limits, screens content, routes to a provider, prices the result, logs it, and fails over when the provider does not answer. Six cross-cutting jobs, owned once instead of once per call site.

The short answer

If you call more than one model — or one model from more than one place in your codebase — you eventually build a small layer in front of it. A place to keep the key. A place to count what it cost. A retry. A switch so you can try a cheaper model without editing forty call sites.

That layer has a name. It is an LLM gateway, and the interesting thing about it is how predictable the shape is: almost every team that builds one arrives at the same six responsibilities, in the same order, usually in the same sequence of incidents. This primer sets out what those six are, what actually happens to a request as it passes through, how the three market shapes differ, and how to tell a real gateway from a thin proxy with a marketing page.

The six jobs a gateway takes off your application

The defining property is not "it forwards requests". It is that your application code stops caring which provider serves a request. It asks for a model; the gateway owns everything else.

JobWhat your code stops doingWhat it looks like when absent
AuthenticationHolding one credential per providerN SDKs, N secrets, N rotation schedules
Cost accountingReconstructing spend from token counts and a price tableA monthly invoice nobody can attribute
LimitsBuilding budget caps and throughput ceilings per serviceOne retry loop bills a quarter's budget
SafetyBolting PII and injection screening onto each call siteThe check exists in the service that remembered it
ObservabilityInstrumenting every service that calls a modelAn incident that starts with a timestamp search
ReliabilityWriting failover per provider, per SDKA provider's bad hour is your bad hour

Every one of those is cross-cutting, which is precisely why they belong at a seam rather than in application code. A control implemented in four services is four controls, three of which are out of date.

The seam is cheap to adopt because the industry converged on one request shape. OpenAI's Chat Completions contract is what most clients speak, it is described the ordinary way with OpenAPI, and the officially maintained clients — the OpenAI Python SDK among them — let you override the base URL. That is why pointing an existing application at a gateway is a two-argument change rather than a rewrite.

The last one is worth a sentence of its own because teams consistently under-rate it until the first outage: failover has to be configuration, not a redeploy, or it will not be there when you need it. The mechanics are in Provider fallback chains: surviving an OpenAI outage.

What actually happens to a request, in order

"It forwards the call" hides the part that matters. A request through a gateway clears a fixed sequence, and knowing the order tells you which failure you are looking at when something comes back non-200.

  1. Authenticate. The credential resolves to an organization, a team and a key. Tenancy comes from the credential, never from a header or body field a caller could set — a gateway that trusts a caller-supplied tenant id has a spend-attribution spoof.
  2. Check money. The estimated cost is reserved against the balance. No balance, no provider call.
  3. Check policy. Budget caps for the relevant scope, then rate limits (RPM and TPM) for velocity.
  4. Screen content. Guardrails run before egress: PII detection, regex filters, keyword blocklists, prompt-injection detection, or a webhook of your own.
  5. Route. Resolve the model name to a provider and a deployment, translate the request shape, and send it with the provider credential the gateway holds. "Request shape" is not a metaphor: OpenAI's Chat Completions and Anthropic's Messages are different JSON contracts for the same idea, and translating between them is work your application no longer does.
  6. Screen the response, then price it from the provider's reported usage, settle the reservation against the real cost, and log the row.

Steps 2 through 4 are the reason a gateway is not a proxy: they can all reject a request before a provider is contacted, which means a blocked call costs nothing. The four gates and the exact status code each returns are enumerated in Credits, budgets, rate limits, guardrails: four pre-flight gates.

Why not just call the provider SDK directly

Calling the provider SDK directly is correct for a prototype and stays correct for a surprisingly long time. It stops being correct the moment one of these is true:

You have……and direct SDK calls cost you
More than one providerN SDKs, N keys, N billing dashboards to reconcile
More than one teamNo per-team attribution and no per-team ceiling
Production trafficNo failover when a provider 5xxs or throttles you
Data you cannot leakNo inline redaction or injection screening
A finance teamSpend is a monthly surprise rather than a live number
A compliance obligationControls scattered across every service that calls a model

The trade is explicit: a few milliseconds of pass-through latency in exchange for not re-implementing cost, safety and reliability at every call site — badly, and once per provider. If latency is the objection, measure it against your model's own p95 before deciding; the methodology is in LLM latency: p50, p95, p99, and time-to-first-token.

Aggregator, self-hosted, managed: three shapes, three bills

The word "gateway" covers three products that fail in different ways.

AggregatorSelf-hostedManaged
Who runs itThe vendorYouThe vendor
Typical revenue modelMarkup on every tokenYour infrastructure billSubscription or platform fee
Governance depthUsually thinWhatever you buildBuilt in
Ops burdenNoneScaling, upgrades, storage, on-callNone
Data residencyVendor'sYoursVendor's
Failure mode to watchCost you cannot auditAn unowned serviceVendor lock-in on config

Aggregators route to many models and commonly recover their cost as a per-token markup, which is invisible in exactly the place you would want to check it. Self-hosted gives you total control and hands you a database, an upgrade path and a pager rotation. Managed runs the infrastructure with governance included and asks you to accept that the data traverses someone else's system.

nRouter is the third kind, with the markup question answered by pricing rather than a promise: credits are bought at face value and the platform fee is charged on top at purchase time rather than skimmed from each call. The argument in full is Markup-free LLM credits, and the managed-versus-self-hosted trade specifically is Managed LLM gateway vs self-hosted.

What a gateway does not do

Being clear about the boundary saves an evaluation cycle.

  • It does not make a bad prompt good. Routing, caching and failover do nothing about output quality. Prompt management and evals help you measure quality; they do not manufacture it.
  • It does not remove the provider's rate limits. It gives you your own limits on top, which is a different and complementary thing.
  • It is not a vector database or a RAG framework. It serves the embedding and chat calls a RAG system makes — see An LLM gateway for RAG — and knows nothing about your chunks.
  • It is not an agent framework. It is what an agent framework calls. The cost-attribution problem agents create is real and specific: Multi-agent cost tracking.
  • It does not store your prompts by default, and should not. On nRouter, request and response content is never written to the log; metadata is. That is the privacy-safe default, and the field list is in What an LLM request log should contain.

The numbers that decide whether it pays for itself

A gateway is worth its cost when the cost is legible, so here is nRouter's, worked rather than asserted.

Pay as you go carries a 4% platform fee added on top of each credit purchase, with a $0 subscription. The 4% is taken of the credits — $100 of credits is charged $104.00 — so the fee on a month's provider spend is 4% of that spend. Pro is $50/mo or $500/yr with a 0% platform fee. The crossover is arithmetic: the fee passes $50 exactly at $1,250/mo of provider spend, and passes the annual equivalent of $41.67/mo at about $1,042/mo.

Below that, Pay as you go is cheaper. Above it, the subscription is. There is no third variable, because plans do not vary the feature set — guardrails, A/B tests, prompt management, evals and per-team budgets are on every plan, and only the fee and the default rate limits move. Why that is a pricing policy rather than a promotion: Every Feature on Every Plan: We Charge a Fee, Not a Gate.

Signup is card-required and takes a real charge; the minimum credit purchase is $5, with the platform fee on top. Current numbers are always on Pricing.

Twelve questions that separate a gateway from a proxy

Take these to any vendor, including this one.

  1. Is the cost figure read or estimated? A real gateway prices from the provider's reported usage, not from a token count it guessed.
  2. What happens when a call cannot be priced? The right answer is a stated unknown. A confident $0 is the wrong answer — the reasoning is Cost honesty.
  3. Can I cap spend, and does the cap hold under concurrency? Ask specifically what happens when many requests race the last dollar: Reserve-and-settle.
  4. Are there separate controls for total spend and for velocity? One number cannot do both jobs — Budgets vs rate limits.
  5. Is safety gated behind a tier? Redaction you have to upgrade to buy is a statement about the vendor's incentives.
  6. What happens when a provider is down? Configuration, or a redeploy?
  7. Is governance multi-tenant? Per-team budgets, per-key limits and roles matter the moment two people share the account.
  8. Where does tenancy come from? From the authenticated credential, or from something the caller can set?
  9. Do I hand over a provider key? If yes, that secret is now in two estates and both are in your audit scope — Why we don't do BYOK.
  10. What is stored, and for how long? Ask about content specifically, not "logs" generally.
  11. What is the real price? Separate the provider cost from the gateway's cut. A gateway with no visible price is charging you somewhere.
  12. What is the compliance posture, stated exactly? "In progress" and "certified" are different words — SOC 2 for an LLM gateway.

Reading the response: the signals a gateway gives back

A gateway earns its place partly through what it hands back on every call. On nRouter the response carries x-nr-* headers you can capture from the SDK you already use:

import os
import time

from openai import OpenAI

client = OpenAI(
    api_key=os.environ["NROUTER_API_KEY"],
    base_url="https://api.nrouter.ai/v1",
)

started = time.perf_counter()
resp = client.chat.completions.with_raw_response.create(
    model="gpt-5.4-mini",
    messages=[{"role": "user", "content": "hello"}],
)
elapsed_ms = (time.perf_counter() - started) * 1000

print(resp.headers.get("x-nr-request-id"))     # always present
print(resp.headers.get("x-nr-request-cost"))   # ABSENT when the call is unpriced
print(resp.headers.get("x-nr-cost-status"))    # "exact" or "unpriced"
print(resp.headers.get("x-nr-model"))          # the model that actually served it
print(round(elapsed_ms, 1))                    # latency is yours to measure

x-nr-request-cost is absent when a call cannot be priced, which is not the same as zero and must never be read as zero. Client code that defaults a missing header to 0.0 under-reports its own spend while the ledger stays correct.

Latency is the one signal that does not arrive as a header: time the call on your own clock, as above, and store the elapsed value beside x-nr-request-id so the two views reconcile. Percentiles across your whole traffic are on the dashboard.

When a request is rejected, the code field tells you which of the gates fired — and the status code alone is not enough, because two gates return 402 and two return 429. Both are ordinary HTTP: 402 is reserved by RFC 9110 and 429 Too Many Requests is defined in RFC 6585, so the transport carries nothing bespoke and the code field is what disambiguates.

SituationStatuscode
Balance cannot cover the call402insufficient balance
Org / team / user budget hit402budget_exceeded
Per-key budget hit429key_budget_exceeded
RPM or TPM exceeded429rate_limit_exceeded
Content blocked pre-egress400guardrail_blocked

Branching client retries on code rather than status is the single highest-value thing to get right in an integration — Handling 429 and 402 errors.

When you do not need one

Honest scoping, because the wrong answer here wastes a month.

You do not need a gateway if you call exactly one model from exactly one service, the spend is small enough that nobody asks about it, the data is not sensitive, and an outage is an inconvenience rather than an incident. The provider SDK is genuinely fine, and adding infrastructure to that situation buys you a dependency.

You are past the line the moment you can say yes to any of: I call more than one model; more than one team shares the spend; this serves production traffic; or I handle data I cannot afford to leak. Notice that three of those four are organizational rather than technical, which is why the decision usually arrives from finance, security or a customer questionnaire rather than from engineering.

If you already run a gateway and are comparing, the vendor-by-vendor version of this page is LLM gateway buyer's guide 2026.

Try it

The fastest way to understand a gateway is to send one request through one and read the headers that come back. That takes about two minutes: point the OpenAI client you already import at https://api.nrouter.ai/v1, pass an nRouter key, and print x-nr-request-cost.

Every governance feature described above — guardrails, per-team budgets, rate limits, A/B tests, prompt management, evals and request logs — is available on every plan. Plans vary the platform fee (4% on Pay as you go, 0% on Pro at $50/mo or $500/yr) and the default rate limits, never the feature set.

Load the $5 minimum — the platform fee rides on top — at app.nrouter.ai/signup. Browse what is currently servable on Models, send a call from the browser in the Playground, or follow the step-by-step build in Ship your first AI feature. Questions get answered in the nRouter community.

See also

Sources

Verified 2026-06-14; every external reference was re-checked on 2026-08-23. Product behaviour, headers, status codes and pricing come from nRouter's own documentation and pricing page; the definitional claims about the wire contract come from the providers' own references, linked below. If something has drifted, email hello@nrouter.ai and we will correct it.

Share
Written by nRouter teamEngineering, product, and company posts from the nRouter team — code-first, cost-honest, no vendor-marketing fluff.