Lint a Video Router request offline: reference limits in Python
Check reference_image_urls (10), reference_video_urls (3), reference_audio_urls (1-5) and the video_url rule in Python before POST /v1/video-router/generate.

A 400 from a submit is a wasted round trip, and a bad batch of fifty bodies is a wasted afternoon. Lint the body in Python first: count each reference list against the limits in the OpenAPI schema and refuse a Gemini Omni video_url edit source that rides with other media fields.
The linter checks shape only. Which reference types a particular model accepts still comes from its catalog entry.
Which limits does the lint check?
These are the limits in the Video Router request schema and docs (read 2026-10-09).
| Field | Limit | Notes |
|---|---|---|
| reference_image_urls | 1 to 10 when present | Public HTTPS URLs |
| reference_video_urls | 1 to 5 in the schema | gemini-omni-flash-1.1 accepts at most 3, each 3 seconds or less |
| reference_audio_urls | 1 to 5 when present | An empty list is not valid |
| video_url | One source clip | For gemini-omni-flash-1.1 edits it cannot be combined with image_url, end_image_url or reference_*_urls |
| wait_timeout_seconds | 0 to 30 | Blocking wait for sync or subscribe only |
What is the function?
It returns a list of problems, so a batch run can print every bad body at once instead of stopping on the first.
def lint(body: dict) -> list[str]:
bad = []
caps = {"reference_image_urls": (1, 10),
"reference_video_urls": (1, 5),
"reference_audio_urls": (1, 5)}
for field, (low, high) in caps.items():
if field in body:
n = len(body[field])
if not low <= n <= high:
bad.append(f"{field}: {n} entries, allowed {low}-{high}")
if body.get("model") == "gemini-omni-flash-1.1":
if len(body.get("reference_video_urls", [])) > 3:
bad.append("Omni takes at most 3 reference videos")
if "video_url" in body:
clash = [f for f in body if f.startswith("reference_")
or f in ("image_url", "end_image_url")]
if clash:
bad.append(f"video_url cannot ride with {clash}")
for field, urls in body.items():
if field.endswith("_urls") or field.endswith("_url"):
for u in urls if isinstance(urls, list) else [urls]:
if isinstance(u, str) and not u.startswith("https://"):
bad.append(f"{field}: not https: {u}")
w = body.get("wait_timeout_seconds")
if w is not None and not 0 <= w <= 30:
bad.append("wait_timeout_seconds must be 0-30")
return bad
print(lint({"model": "gemini-omni-flash-1.1", "video_url": "https://a.co/a.mp4",
"reference_image_urls": ["https://a.co/a.png"]}))What stays out of the lint?
Clip length. A reference video of three seconds or less needs the file itself, and the catalog may allow fewer types for the model you chose. Fetch GET /v1/video-router/models/{id} for those. Other models can differ: h3-max-recast, for example, takes a video_url together with reference_image_urls, so the edit-source rule above is applied only to Omni. Do not copy the limits above into other docs, since a model entry can be stricter than the router.
Where should the lint run?
Run it in the step that builds the body, before the Idempotency-Key is assigned, so a rejected body never consumes a key. Log the whole list of problems with the item's index and then continue with the next item.
Sources
Related posts
More in Developers
- List Sume's video endpoints from the OpenAPI JSON in Python
Pull the OpenAPI snapshot, print every /v1/videos and Video Router operation, and know which copy is the source of truth. A short Python script.
- List Sume video model limits with curl, jq and column in one table
curl GET /v1/videos/models into jq and column to see each model's duration range, resolutions and audio flag in one table. Documented limits for six models.
- List Sume video models: /v1/videos/models for limits, /v1/catalog
Two discovery routes, two jobs. /v1/videos/models returns durations, resolutions, aspect ratios and audio flags; the public /v1/catalog lists the wider catalog.
- LTX-2.5 on Windows or Mac: natten, attention and fallbacks
LTX-2's README: natten (VAE decode) is Linux and CUDA only, with a Triton or eager fallback elsewhere; FlashAttention 4 on B200, 3 on Hopper, SDPA otherwise.
Written by Sume