Gateway headers and extensions

Besides the standard OpenAI and Anthropic fields, LYRouter defines a few request headers, response headers and special model names: request headers control parameter validation, declare a session and require native passthrough; response headers report dropped parameters and remaining quota; special model names call a virtual model, Auto routing or the Default Model. All of these are optional, and calls without them work as in the standard protocols. HTTP header names are case-insensitive.

Quick reference

Name Direction Purpose Endpoints
X-Gateway-Strict-Parameters: true Request Returns 400 instead of dropping parameters Images, videos
x-session-id Request Declares a session so logs are grouped by it; forwarded to the upstream as is All
x-gateway-passthrough: require Request Requires Anthropic native passthrough and returns 400 when it is not possible /v1/messages
X-Title Request Identifies your application in the Client column of the logs All
X-Gateway-Unsupported-Parameters Response Lists the parameters the gateway dropped Images, videos
x-aigw-quota-<metric>-limit / -remaining / -reset Response Limit, remaining amount and reset time of the applicable quotas Endpoints that call a model
anthropic-ratelimit-* Response Rate limit information in the Anthropic format /v1/messages
Retry-After, X-RateLimit-Reason, X-RateLimit-Reset Response The API key is circuit-broken or banned Endpoints that call a model
@vmodel/<name>, @preset/<name> Model name Calls a virtual model Chat endpoints and others
lyrouter/auto Model name Auto routing Chat endpoints
model omitted Model name Uses the workspace's Default Model All model endpoints

Request headers

X-Gateway-Strict-Parameters

Image and video endpoints drop parameters the selected model does not support, carry on, and list the dropped parameters in the X-Gateway-Unsupported-Parameters response header. With this request header, the gateway returns 400 as soon as any parameter would be dropped, without calling the upstream and without billing.

  • Value: only lowercase true is recognized; any other value (including True and 1) counts as absent.
  • Endpoints: /v1/images/generations, /v1/images/edits, /v1/videos, /v1/videos/regenerations, /v1/videos/context. It does not control the parameters chat endpoints remove during cross-protocol conversion; see Chat Completions.
curl https://api.lyrouter.com/v1/images/generations \
  -H "Authorization: Bearer $LYROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Gateway-Strict-Parameters: true" \
  -d '{"model":"MODEL_ID","prompt":"A Shiba Inu wearing sunglasses","guidance_scale":7}'

When the selected model does not support guidance_scale, the response is:

{
  "error": {
    "message": "unsupported parameters for this model: guidance_scale",
    "type": "invalid_request_error",
    "code": "unsupported_parameters"
  }
}

The parameters each model supports are listed in Multimodal capabilities.

x-session-id

Assign a fixed session ID to a conversation (for example, generate a UUID for each conversation) and send the same value with every request in that session. For log grouping, x-session is equivalent.

  • Log grouping: the Session column of the logs groups requests by this value, with the source shown as "Declared (client x-session-id)", and you can also filter by Session ID. Without this header, the gateway infers sessions from the conversation content, the source shows "Inferred (gateway-derived)", and the tag ends with ≈.
  • Forwarded as is: the gateway forwards this header to the upstream without changing its value.
  • Upstream session affinity: the platform has turned on session affinity for a few channels. On those channels, when you do not send this header, the gateway adds X-Session-Id: aigw-<hash> automatically; when you send it, your value is used. Whether it affects upstream caching or instance assignment is up to the provider.
  • Does not affect gateway routing: the gateway's own session affinity works per "API key + model", as described in Channels and routing, and has nothing to do with this header.
curl https://api.lyrouter.com/v1/chat/completions \
  -H "Authorization: Bearer $LYROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -H "x-session-id: 6f1c7e2a-3b4d-4e5f-9a8b-1c2d3e4f5a6b" \
  -d '{"model":"MODEL_ID","messages":[{"role":"user","content":"Let us pick up where we left off"}]}'

x-gateway-passthrough

When you call an Anthropic-protocol channel through /v1/messages, the gateway by default converts the request into its internal format and back. Sending x-gateway-passthrough: require means "the request body must reach the upstream as is, with no conversion": when that cannot be met, the gateway returns 400 and states which condition failed, instead of silently falling back to conversion.

Value Behavior
require (case-insensitive) Native passthrough is mandatory; returns 400 when it is not possible
prefer, any other value, or absent Default behavior: passthrough when possible, conversion otherwise, and the request completes as usual
  • This header is read only by the gateway and is not forwarded to the upstream.
  • The LYRouter public gateway currently has native passthrough turned off, so every request with require returns 400; do not send this header unless you need it.

When a request is rejected, the error message is native passthrough was required by `x-gateway-passthrough: require` but is not available for this request (<reason>). On /v1/messages it comes back in the Anthropic error format (invalid_request_error); on other endpoints (such as /v1/responses) it is a single line of plain text, yet its response header is currently still Content-Type: application/json, so check whether the body is JSON before parsing it. For what each reason code in parentheses means and how to handle it, see Protocol compatibility and limits.

X-Title

Send X-Title: <app name> in the request headers. When the gateway has not recognized a known tool (such as Claude Code or Cursor) from other signals, the Client column of the logs shows this app name, and usage analytics uses it for the client breakdown. This header is forwarded to the upstream as is.

Response headers

X-Gateway-Unsupported-Parameters

When the gateway drops parameters from an image or video request, the response carries this header, with comma-separated parameter names as the value, for example X-Gateway-Unsupported-Parameters: response_format or guidance_scale,watermark. The request itself runs as usual. In production, check this header, or use X-Gateway-Strict-Parameters: true to turn dropping into an error.

x-aigw-quota-*

When a quota applies to the call, the response carries quota headers. They appear on successful responses and on the 429 returned when a quota is reached, and also on many 400s, for example a wrong Content-Type, a model that does not support the endpoint called, a 400 returned by the upstream, or a rejected native passthrough; 401, 403, 503 and the 400 for a missing model (missing_model) do not carry them. There are three headers per applicable metric:

Response header Meaning
x-aigw-quota-<metric>-limit The limit. Whole Credits for credits; token or request counts for the others
x-aigw-quota-<metric>-remaining The remaining amount, based on usage when the request was sent and excluding this request's consumption; never below 0
x-aigw-quota-<metric>-reset The next reset time, as a UTC instant in RFC 3339 format. This value is currently later than the actual reset: about 2 minutes later for daily and monthly quotas (for example, a monthly quota that resets at 16:00:00Z returns 16:02:00Z to 16:02:06Z) and about 1 minute later for per-minute quotas, and it also varies by a few seconds between requests. Use it only to estimate the reset time, not for precise timing. Total quotas without a reset period do not include this header

The metrics are credits, tokens, requests, input-tokens and output-tokens. When several quotas apply to the same metric at once (for example an API key quota and a workspace quota), the one with the least remaining is reported.

x-aigw-quota-credits-limit: 2000
x-aigw-quota-credits-remaining: 1532
x-aigw-quota-credits-reset: 2026-10-31T16:02:00Z
x-aigw-quota-requests-limit: 600
x-aigw-quota-requests-remaining: 597
x-aigw-quota-requests-reset: 2026-10-14T06:31:00Z

Reading response headers with an SDK:

curl -s -D - -o /dev/null https://api.lyrouter.com/v1/chat/completions \
  -H "Authorization: Bearer $LYROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"MODEL_ID","messages":[{"role":"user","content":"Hello"}]}' \
  | grep -i '^x-aigw-quota-'

Quota headers appear only on endpoints that call a model (chat, Responses, Messages, embeddings, rerank, images, audio and video submission); /v1/models, video task queries and similar endpoints do not carry them. For the 429 returned when a quota is used up, see 429: rate limits and quotas.

Retry-After, X-RateLimit-Reason, X-RateLimit-Reset

These headers appear only when the gateway circuit-breaks or bans an API key because of a high error rate:

Scenario Status Response headers
Temporary circuit break (api_key_circuit_open) 429 Retry-After: <seconds>, X-RateLimit-Reason: api_key_circuit_open, X-RateLimit-Reset: <Unix seconds when it lifts>
Permanent ban (api_key_permanently_banned) 403 X-RateLimit-Reason: api_key_permanently_banned

anthropic-ratelimit-*

When you call through /v1/messages, the response carries rate limit headers in the Anthropic format, which clients such as Claude Code use to pace their requests:

  • When the upstream serving the request returns anthropic-ratelimit-*, the gateway forwards them as is (together with the upstream's Retry-After); these numbers are the upstream account's limits.
  • When the upstream returns none and you have request or token quotas, the gateway generates -limit, -remaining and -reset for anthropic-ratelimit-requests-*, -tokens-*, -input-tokens-* and -output-tokens-* from your quotas. Credits quotas have no Anthropic equivalent; read x-aigw-quota-credits-* instead.

It is normal for anthropic-ratelimit-* and x-aigw-quota-* to show different numbers in the same response: the former may come from the upstream, while the latter is always your quota on LYRouter.

Request ID

The gateway does not return a request ID in the response headers. To investigate a particular call, copy the Request ID at the top of the log detail in the console; see Errors and request identifiers.

The response body from some upstreams (such as channels serving GLM models) contains "request_id":"aigw-…": this is the session ID the gateway adds automatically (X-Session-Id; see "x-session-id" above), echoed back by the upstream. It is not LYRouter's Request ID. When the request carries x-session-id, the echoed value is the one you sent.

Special model names

Value Meaning Available on
@vmodel/<name> Calls a virtual model in the workspace /v1/chat/completions, /v1/messages, /v1/responses; when the virtual model's model list consists entirely of embedding or rerank models, also /v1/embeddings and /v1/rerank
@preset/<name> The old prefix for virtual models, equivalent to @vmodel/ Same as above
lyrouter/auto Auto routing, which picks among the candidate models by the intent of the request /v1/chat/completions, /v1/messages, /v1/responses
model omitted, or "" or null Uses the workspace's Default Model Every endpoint that takes model
  • Virtual models and lyrouter/auto used on image, video or audio endpoints return 403 Model is not available in the model plaza; these endpoints accept only specific model IDs.
  • Enabled virtual models and lyrouter/auto appear in the results of GET /v1/models; see List models.
  • When model is omitted and the workspace has no Default Model, the request returns 400 you must provide a model parameter (missing_model). The Default Model is usually a chat model, so omitting model on embeddings, rerank or audio endpoints most likely returns 400 unsupported_model_api; always name the model ID on these endpoints. How to write model IDs is covered in Model identifiers and discovery.