'model_params has an empty allowlist': omit it or send {}

Video Router v1 has no pass-through knobs. model_params with any key gets a 400; {} is fine. /v1/videos refuses provider.options the same way. What to change.

4 min readSume
All posts

"model_params has an empty allowlist in Video Router v1; omit the field or send {}." means the request carried a model_params object with at least one key. No video model on Sume accepts provider-specific parameters in v1, so the only valid forms are no field or an empty object. The OpenRouter-shaped route has the same rule under a different name: a non-empty provider.options returns 400 unsupported_parameter.

Where the rule applies

The check runs for pinned catalog models and for the Auto aliases. For Genjutsu and H3 Max Recast the message is model-specific: "Genjutsu does not accept model_params." and "H3 Max Recast does not accept model_params." Every model reports an empty allowed_passthrough_parameters list in the catalog, which is the machine-readable form of the same fact.

Provider-specific knobs on Sume video routes on main (read 2026-10-05)
FieldRouteResult
model_params with keysPOST /v1/video-router/generate400: model_params has an empty allowlist in Video Router v1
model_params: {}POST /v1/video-router/generateAccepted
provider.options with keysPOST /v1/videos400 unsupported_parameter
seedPOST /v1/videosRejected: each model reports seed false
sizePOST /v1/videos400 unsupported_parameter: use resolution and aspect_ratio

Why this matters if you came from open weights

A self-hosted pipeline usually exposes sampler settings, step counts and conditioning strengths, and a client written for one tends to forward a dictionary of them. A hosted catalog with a stable, billed contract does not forward arbitrary dictionaries; each model exposes a fixed set of named fields instead: duration, resolution, aspect ratio, frames and references. If you rely on a knob that is not among them, the honest options are to pick a model whose named fields cover the need or to run that model yourself.

Strip unknown keys in one place

The function removes the pass-through fields before sending and returns what it removed, so your logs show what was dropped instead of the API refusing the request. It prints the cleaned body and sends nothing.

DROP = ("model_params", "seed", "size")

def clean(body: dict):
    removed = {k: body[k] for k in DROP if body.get(k) not in (None, {})}
    out = {k: v for k, v in body.items() if k not in DROP}
    opts = (out.get("provider") or {}).get("options")
    if opts:
        removed["provider.options"] = opts
        out["provider"] = {k: v for k, v in out["provider"].items() if k != "options"}
    return out, removed

body, gone = clean({
    "model": "wan-3.0", "prompt": "A kite over a beach",
    "model_params": {"steps": 30}, "seed": 7,
})
print(body, gone)

Limits

Dropping a key changes the result, so do it on purpose. If a setting is essential to your look, such as a fixed seed for a repeatable shot, treat the lack of it as a model-selection fact and test whether the available fields give you enough control. The catalog and the docs are the source for what a model accepts; a new field appears there before it is safe to rely on.

If you maintain more than one integration, keep one shared request builder and one shared list of the keys it may emit. The empty allowlist is easiest to respect when a single function owns the outgoing body, because a stray key added in a feature branch then fails a test instead of production.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume