Reference
Gateway headers.
Every x-gateway-* header the Leanroute API emits (and the ones it accepts), with direction, example values, and when to look for each.
All headers are ASCII (RFC 7230 §3.2.4 enforced by CI). Header names are case- insensitive per HTTP spec, but we emit them lower-case. Cmd/Ctrl+F within the page works fine — headers are alphabetical within each direction group.
Request headers
Headers you send to Leanroute on the way in.
x-gateway-routing
requestAppears: Optional. Send on requests you want pinned to a specific model.
Set to "explicit" to disable cheaper-model swaps and provider arbitrage for this single request, even when your org has them enabled. Used when you want deterministic routing to the exact model you named — e.g., you're benchmarking, or the request needs a specific model's tool-calling behavior.
Example
x-gateway-routing: explicitJavaScript
fetch("https://api.leanroute.dev/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${key}`,
"Content-Type": "application/json",
"x-gateway-routing": "explicit",
},
body: JSON.stringify({ model: "anthropic/claude-sonnet-4-6", messages }),
})Python
# With openai SDK, use extra_headers on the create call:
client.chat.completions.create(
model="anthropic/claude-sonnet-4-6",
messages=[...],
extra_headers={"x-gateway-routing": "explicit"},
)Response headers
Headers Leanroute emits on the way back — cost, provider, routing decisions, cache state, failover, and throttling.
x-gateway-benchmark-basis
responseAppears: Every successful response where the served model is in our model catalog.
Comma-separated list of the public benchmarks that place the SERVED model in its quality tier. Auditable signal: if we swapped Sonnet → DeepSeek-V4 for cost, this header names the benchmarks (MMLU / GPQA / HumanEval) that justify the pairing. See /tiers for the full mapping.
Example
x-gateway-benchmark-basis: MMLU,GPQA,HumanEvalx-gateway-model
responseAppears: Every successful response.
The canonical model id that actually answered your request. Useful when arbitrage or failover changed the model — this is authoritative for what got billed and what generated the tokens.
Example
x-gateway-model: deepseek/deepseek-v4-flashx-gateway-model-deprecated
responseAppears: When we auto-rewrote a request from a deprecated model id to its current canonical name.
Original model id you sent, when our model catalog marks it as retired. We transparently rewrite to the replacement so your code keeps working — but you should update your code to the current model id. Example rewrites: claude-sonnet-4.6 → claude-sonnet-4-6 (dotted to hyphenated), google/gemini-2.5-flash → google/gemini-3.1-flash-lite (upstream soft-deprecated).
Example
x-gateway-model-deprecated: google/gemini-2.5-flashx-gateway-provider
responseAppears: Every successful response.
Provider name that actually served the request. When arbitrage or failover changed the provider, this reflects the final choice, not the originally-requested one. Values: openai, anthropic, google, deepseek, xai, qwen, glm, doubao, kimi, sarvam, krutrim.
Example
x-gateway-provider: anthropicJavaScript
const res = await fetch(url, opts);
console.log("served by:", res.headers.get("x-gateway-provider"));Python
resp = client.chat.completions.with_raw_response.create(...)
print("served by:", resp.headers.get("x-gateway-provider"))x-gateway-routed-from
responseAppears: When the gateway swapped from the requested model to a cheaper same-tier alternative (cheaper-model-swap opt-in).
The canonical model id you originally requested, before the swap. If you sent anthropic/claude-sonnet-4-6 with cheaper-model-swap on, we may serve you deepseek/deepseek-v4-flash and this header carries the original id. Format: "<original> -> <served>".
Example
x-gateway-routed-from: anthropic/claude-sonnet-4-6 -> deepseek/deepseek-v4-flashx-gateway-swap-reason
responseAppears: When a swap occurred (cheaper-model swap or failover).
Why we swapped models. Named values documented in the routing decider (apps/api/src/routing/decide.ts SwapReason). Absent when no swap happened. Combine with x-gateway-benchmark-basis for a full audit trail.
Example
x-gateway-swap-reason: cheapest-in-tierx-gateway-failover
responseAppears: When the originally-routed provider returned 5xx and we retried on an alternative.
Set to "true" when the customer's request succeeded via failover after the first-choice provider returned 5xx. Together with x-gateway-failover-from, this lets your monitoring detect provider-side incidents even though your customer got a clean 200.
Example
x-gateway-failover: truex-gateway-failover-from
responseAppears: Only present when x-gateway-failover is set.
Provider name that returned 5xx and triggered failover. Correlate this with your monitoring for provider-outage detection.
Example
x-gateway-failover-from: anthropicx-gateway-mcp-mode
responseAppears: When the request included an mcp_servers array.
Always 'proxy'. Confirms the gateway ran the MCP tool loop itself rather than handing mcp_servers to the provider, which is what makes every tool call visible, billable and auditable.
Example
x-gateway-mcp-mode: proxyx-gateway-mcp-allowlist
responseAppears: When the request included an mcp_servers array. See /docs/mcp for the full flow.
Number of MCP servers that passed your org's allowlist check. Should equal the number you sent. Server URLs and auth tokens are never surfaced in headers.
Example
x-gateway-mcp-allowlist: 2x-gateway-mcp-tools-discovered
responseAppears: When the request included an mcp_servers array.
Total tools discovered across all connected MCP servers and offered to the model. Zero means the servers connected but returned no tools, which usually points at an auth or capability problem on the server rather than at the gateway.
Example
x-gateway-mcp-tools-discovered: 8x-gateway-mcp-tool-calls
responseAppears: When the request included an mcp_servers array.
Number of tools the gateway actually executed on your behalf during the loop.
Example
x-gateway-mcp-tool-calls: 2x-gateway-mcp-iterations
responseAppears: When the request included an mcp_servers array.
Model round trips made inside the loop. 1 means the model answered without calling any tool. The usage object on the response is the sum across all of them.
Example
x-gateway-mcp-iterations: 3x-gateway-mcp-iteration-cap
responseAppears: Only when the loop stopped at its 10-iteration ceiling.
Present when the gateway stopped because it hit the iteration cap rather than because the model finished. Usually means the model got stuck retrying a tool that keeps failing.
Example
x-gateway-mcp-iteration-cap: truex-gateway-mcp-server-failures
responseAppears: Only when one or more MCP servers could not be reached.
Count of MCP servers that failed to connect or failed tools/list. The run continues with whatever the remaining servers offered rather than failing the whole request, so a non-zero value here explains a thinner tool set.
Example
x-gateway-mcp-server-failures: 1x-gateway-cache
responseAppears: When the response came from cache instead of the upstream provider.
Cache tier that served the response. Two values: "exact" (SHA-256 hash match on request bytes — free, zero false positives) or "semantic" (embedding-based nearest-neighbor at ≥0.92 cosine similarity, every plan, uses OpenAI text-embedding-3-small). Cache hits are billed at $0. Never present on requests carrying mcp_servers: those bypass both cache tiers, read and write, because the answer depends on what the tools return at run time, and a cached answer to "what is on my calendar today" is a wrong answer tomorrow.
Example
x-gateway-cache: exactx-gateway-cache-similarity
responseAppears: Only present when x-gateway-cache: semantic.
Cosine similarity score of the semantic-cache match, four decimal places. Useful for debugging cache-hit accuracy — if you're seeing wrong answers on semantic hits, look for scores clustering right at the threshold and tune GATEWAY_SEMANTIC_CACHE_THRESHOLD.
Example
x-gateway-cache-similarity: 0.9412x-gateway-byok
responseAppears: When your request was dispatched using your own BYOK key for that provider.
Set to "true" when the gateway used your stored BYOK provider key instead of our managed one. Useful for confirming that traffic you expect to be BYOK actually is — e.g., you added a Krutrim BYOK key and want to verify it's being used, not our managed budget.
Example
x-gateway-byok: truex-gateway-cost-usd
responseAppears: Every successful non-streaming response. Not on streams: the cost is only known once the stream ends, after headers are sent; it appears in your request logs.
USD cost of this single request. Six-decimal precision. Reflects the actual upstream cost — no per-request markup on inference. Cache hits show 0.000000 (billed at $0).
Example
x-gateway-cost-usd: 0.000823x-gateway-credit-balance-usd
responseAppears: Credits-plan customers, every response.
Remaining prepaid credit balance after this request debited its cost, in USD with 6-digit precision. Not present on BYOK-subscription plans.
Example
x-gateway-credit-balance-usd: 47.324180x-gateway-latency-ms
responseAppears: Every successful non-streaming response.
End-to-end request latency in milliseconds, measured at the gateway. Includes upstream provider dispatch + our routing + cache checks. Useful for client-side monitoring without needing your own timer.
Example
x-gateway-latency-ms: 847x-gateway-prompts-persisted
responseAppears: Every successful response.
Values: "true" (prompts may have entered the prompt cache) or "false" (org has enabled no-persistence mode via /dashboard/settings and this request bypassed the cache entirely). Auditable signal for compliance-sensitive customers to verify their setting actually applied.
Example
x-gateway-prompts-persisted: falsex-gateway-throttle-scope
responseAppears: On 400 (guardrail block), 402 (spend cap or balance) and 429 (rate limit) error responses.
Which specific limit fired. Spend caps: org_daily, org_monthly, key_daily, key_monthly (402). Rate limits: org_rpm, key_rpm, org_tpm, key_tpm (429). Balance: credit_balance, low_balance (402). Guardrails: guardrail_library, guardrail_block, guardrail_moderation (400 on the prompt), guardrail_outbound (422 on the response). Use this to route retry logic on the client: a *_daily cap clears at 00:00 UTC, an *_rpm limit within a minute.
Example
x-gateway-throttle-scope: org_dailyRelated
- Developer Guide — endpoints, request shapes, error codes.
- Quality tiers — the model-to-tier mapping that governs when
x-gateway-swap-reasonfires. - Compliance posture — details behind
x-gateway-prompts-persistedand no-persistence mode. - Playground — send a request and see these headers on a real response. No signup.