# Parameter policy

> How the gateway handles a request parameter the selected model doesn't support.

URL: https://boelabs.com/en/docs/ai-gateway/parameter-policy
Language: English

Parameter policy controls how AI Gateway 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](https://boelabs.com/docs/ai-gateway/parameter-policy#quality-on-image-and-video-generation).

## Declaring support in the catalog

Each model's `operations["text.generate"].parameters` map marks every parameter it recognizes:

```json
"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` &lt; `medium` &lt; `high` &lt; `xhigh` &lt; `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 includes `unified_routing.unsupported_parameter_strategy` (when
  `x-unified-routing-metadata` is requested — see [Headers](https://boelabs.com/docs/ai-gateway/headers)); the operation log's
  `parameterPolicy` field 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 a `400` naming the
  first unsupported parameter as `param`.
- **`allow`**: whatever the upstream provider returns.

## Configuring it

```bash
curl -X PUT "$GATEWAY/admin/router-settings" \
  -H "Authorization: Bearer $MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "unsupportedParameterStrategy": "error" }'
```

## Next steps

- [Routing](https://boelabs.com/docs/ai-gateway/routing) — the other global router setting, orthogonal to this one.
- [Headers](https://boelabs.com/docs/ai-gateway/headers) — `x-unified-routing-metadata` response shape.
- [Model catalog](https://boelabs.com/docs/ai-gateway/model-catalog) — the full `parameters` map schema.
- [Troubleshooting](https://boelabs.com/docs/ai-gateway/troubleshooting) — the `unsupported_parameter` error code.

