Validate a Gemini Omni Flash 1.1 request in Python before sending

A 28-line Python check for Sume's gemini-omni-flash-1.1 rules: 3-10 s, 10 reference images, 3 reference videos, no audio off, and edit mode exclusions.

4 min readSume
All posts

Gemini Omni Flash 1.1 (gemini-omni-flash-1.1) on Sume has a handful of rules that you can check before you spend a request: 3 to 10 seconds, resolution from 360p to 4K, aspect ratio 16:9 or 9:16, at most 10 reference images and 3 reference videos, no generate_audio false, and edit mode through video_url that cannot be mixed with the image and reference fields. A local function that returns a list of problems saves a failed call and keeps bad payloads out of your queue.

The rules in one table

Native audio is always on, so the API rejects generate_audio false. The docs also list no bitrate_mode and no reference_audio_urls.

Gemini Omni Flash 1.1 request rules from the Video Router docs, read 2026-10-08
CapabilitySendLimits
text_to_videoprompt3-10 s, 360p/720p/1080p/4K, 16:9 or 9:16
image_to_videoimage_url and optional end_image_urlSame envelope
reference_to_videoreference_image_urls and reference_video_urlsUp to 10 images and 3 videos, each video 3 s or less
video_to_video (edit)video_urlNo image_url, end_image_url or reference urls. No aspect_ratio or duration. Resolution defaults to 720p

The check

The function returns an empty list when the body looks valid. It cannot measure the length of a reference video, so keep the 3-second limit on those clips in your upload step. The main block shows an edit request that also carries a duration and generate_audio false.

import json
REF_KEYS = ("reference_image_urls", "reference_video_urls")
EDIT_BLOCKS = ("image_url", "end_image_url", "aspect_ratio", "duration") + REF_KEYS
def check_omni(body):
    errs = []
    if body.get("generate_audio") is False:
        errs.append("generate_audio:false is rejected, audio is always on")
    for key in ("bitrate_mode", "reference_audio_urls"):
        if key in body:
            errs.append(f"{key} is not supported")
    if len(body.get("reference_image_urls") or []) > 10:
        errs.append("at most 10 reference_image_urls")
    if len(body.get("reference_video_urls") or []) > 3:
        errs.append("at most 3 reference_video_urls (each 3 s or less)")
    if body.get("video_url"):
        errs += [f"video_url cannot combine with {k}" for k in EDIT_BLOCKS if body.get(k)]
    else:
        if body.get("duration") is not None and not 3 <= body["duration"] <= 10:
            errs.append("duration must be 3-10 seconds")
        if body.get("aspect_ratio") not in (None, "16:9", "9:16"):
            errs.append("aspect_ratio must be 16:9 or 9:16")
    if body.get("resolution") not in (None, "360p", "720p", "1080p", "4K"):
        errs.append("resolution must be 360p, 720p, 1080p or 4K")
    return errs
if __name__ == "__main__":
    bad = {"prompt": "x", "video_url": "https://example.com/a.mp4", "duration": 5, "generate_audio": False}
    print(json.dumps(check_omni(bad), indent=1))
    print(check_omni({"prompt": "x", "duration": 8, "resolution": "720p"}))

What a pass costs

A passing request still costs money, so size it first. Sume bills the provider list price times 1.25 for each output second. At 720p the provider list is $0.10 a second, so an 8-second clip is 8 x ($0.10 x 1.25) = 8 x $0.125 = $1.00. A 3-second 360p draft is 3 x $0.0375 = $0.1125.

  • Run the check at the edge of your service, before the Idempotency-Key is created, so a rejected body never holds a key.
  • Keep the rule values in one constant block so a catalog change is a one-line edit.
  • Read GET /v1/video-router/models for the live capabilities and let the code trust that over this table.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume