Parameter policy
How the gateway handles a request parameter the selected model doesn't support.
Parameter policy controls how Bifrost handles a request field that a deployment does not support. The catalog declares support per model; the router setting chooses whether to drop the field, reject the request, or pass it through.
The parameters map below applies to the chat-shaped endpoints — /v1/chat/completions,
/v1/messages, and /v1/responses. Images, embeddings, and audio transcriptions validate their own
parameters against the catalog profile unconditionally (a hard 400 unsupported_parameter), with one
exception: quality on image and video generation, which follows the same three strategies. See
Quality.
Declaring support in the catalog
Each model's operations["text.generate"].parameters map marks every parameter it recognizes:
"parameters": {
"seed": true,
"parallel_tool_calls": false,
"temperature": { "mode": "range", "min": 0, "max": 1.5 },
"response_format": { "mode": "mapped", "upstreamField": "text.format" }
}A bare true/false means supported/unsupported. An object refines it: mode (supported,
unsupported, ignored, range, mapped), with min/max/values as the accepted range or enum,
upstreamField when the wire name differs from the canonical one, and notes for anything
provider-specific. A parameter absent from the map is treated as unknown, not unsupported — the
gateway doesn't reject on missing catalog data, only on an explicit unsupported/ignored mode.
The three strategies
Set globally with PUT /admin/router-settings (unsupportedParameterStrategy); there is no per-model
or per-request override.
| Strategy | Behavior |
|---|---|
drop (default) | Strip the unsupported parameter(s) from the request before sending it upstream to the chosen deployment. The request still succeeds. |
error | Exclude any deployment that doesn't support a requested parameter from candidacy before routing. If the pool has another deployment that does support it, the request is served by that one — silently, no error. Only if every deployment in the pool lacks the parameter does the client get a 400 unsupported_parameter. |
allow | Forward the parameter as-is. The upstream provider decides — it may ignore it, error, or (worst case) silently misbehave. |
error's per-candidate exclusion means it behaves less like "reject this request" and more like "only
route this request where it'll actually work" — a pool with mixed-capability deployments (e.g. one
model that supports seed and one that doesn't) keeps serving requests that need it, as long as at
least one deployment can.
quality on image and video generation
Image and video models expose wildly different quality rungs — GPT Image 2.5 goes low through max,
earlier GPT Image models stop at high, DALL·E speaks standard/hd, some Gemini image models
translate the knob into a thinking level, and others have no knob at all. The gateway takes one
canonical ladder — low < medium < high < xhigh < max — and reconciles the requested
rung with whatever the chosen model declares:
| Strategy | Behavior |
|---|---|
drop (default) | Snap to the declared rung nearest the request, in either direction, the lower one on a tie. A model with no rungs at all gets no quality field. |
error | Exclude any deployment that does not declare the requested rung from candidacy, exactly as it does for a chat parameter. The client only sees 400 unsupported_parameter if every deployment in the pool lacks it. |
allow | Forward the rung verbatim and let the provider decide. |
Snapping is what lets a request survive a fallback: a request for max that lands on a deployment
whose ladder stops at high degrades instead of failing. It handles gaps too — on a model declaring
only low and high, max resolves to high and medium resolves to low.
auto is not a rung. It means "no choice expressed", so it is accepted for every model, never
snapped, and never sent upstream — the model's own default applies. standard, hd and the video
vocabulary's native are still accepted from clients and normalized onto the ladder
(standard → medium, hd → high, native → max); a model that natively speaks one of them
declares the translation back in its profile, so DALL·E still receives hd on the wire.
When drop changes the rung, the operation log records a qualityAdjustment in its metadata with the
requested and effective values, so a silent downgrade stays auditable — this matters because rungs
carry real cost differences.
Seeing what happened
drop: the response includesunified_routing.unsupported_parameter_strategy(whenx-unified-routing-metadatais requested — see Headers); the operation log'sparameterPolicyfield records exactly which parameter names were dropped for that request, so dropped-silently is still auditable after the fact.error: the client either gets a normal response (routed around the gap) or a400naming the first unsupported parameter asparam.allow: whatever the upstream provider returns.
Configuring it
curl -X PUT "$GATEWAY/admin/router-settings" \
-H "Authorization: Bearer $MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{ "unsupportedParameterStrategy": "error" }'Next steps
- Routing — the other global router setting, orthogonal to this one.
- Headers —
x-unified-routing-metadataresponse shape. - Model catalog — the full
parametersmap schema. - Troubleshooting — the
unsupported_parametererror code.