Gemini Omni Flash edit on Sume: a Python preflight for bad fields
A 29-line Python preflight for Sume video-router edit requests on gemini-omni-flash-1.1: catches the fields the docs say it rejects before you pay for a job.

Sume's Video Router docs say an Omni edit takes video_url and a prompt, an optional resolution, and nothing that mixes in other media. They also say native audio is always on and that generate_audio: false is rejected. The function below checks a request body for those cases before you send it.
The preflight
It only encodes rules written in the docs. Anything else is left to the API, and the OpenAPI reference is the final word on field names.
EDIT_SOURCE = "video_url"
CONFLICTS = ["image_url", "end_image_url", "reference_image_urls",
"reference_video_urls"]
NOT_ON_EDIT = ["aspect_ratio"]
NOT_ON_OMNI = ["bitrate_mode", "reference_audio_urls"]
RESOLUTIONS = {"360p", "720p", "1080p", "4K"}
def preflight(body):
problems = []
if body.get("model") != "gemini-omni-flash-1.1":
problems.append("model must be gemini-omni-flash-1.1")
if body.get("generate_audio") is False:
problems.append("generate_audio=false: native audio is always on")
problems += [f"{k}: not available on Omni" for k in NOT_ON_OMNI if k in body]
if body.get("resolution", "720p") not in RESOLUTIONS:
problems.append(f"resolution must be one of {sorted(RESOLUTIONS)}")
if EDIT_SOURCE in body:
problems += [f"{k}: cannot combine with video_url" for k in CONFLICTS if k in body]
problems += [f"{k}: not used by edits" for k in NOT_ON_EDIT if k in body]
if not body.get("prompt"):
problems.append("an edit needs a prompt with the instructions")
return problems
if __name__ == "__main__":
bad = {"model": "gemini-omni-flash-1.1", "video_url": "https://example.com/c.mp4",
"image_url": "https://example.com/i.png", "aspect_ratio": "16:9",
"generate_audio": False, "resolution": "2K"}
for p in preflight(bad):
print(p)The rules behind it
The three rows are the documented request shapes for the one catalog id, gemini-omni-flash-1.1.
| Capability | Send | Notes |
|---|---|---|
| Text to video | prompt | 3 to 10 s, 360p to 4K, 16:9 or 9:16 |
| Image to video | image_url, optional end_image_url | Same limits |
| Edit | video_url plus prompt | resolution optional (default 720p); no aspect_ratio |
| Reference to video | reference_image_urls up to 10, reference_video_urls up to 3 | Videos up to 3 s each |
What it does not catch
- Whether your clip is within the source limits, which this post does not cover.
- The
durationfield. See the linked post on how an edit reserves a default length. - The price. Read the live endpoint price before a batch.
Sources
Related posts
More in Developers
- Two failure channels in the Sume SDK: submit error vs failed job
A generateVideoV1 error means no job exists; a failed job means one did and billing was settled. Handle both channels in TypeScript without double-submitting.
- generation_spend_cap_usd on a Format run: null is $500, 0 is a 400
On a Format run request, omit generation_spend_cap_usd for the Format cap, send a number up to 500, null for the $500 maximum. 0 or above 500 returns 400.
- Get transcript text from a captioned video: caption jobs return none
A Sume caption job returns the burned video, not the transcript. For text and word times run STT or video inspect with transcribe. Prices and a recipe.
- Go: a context timeout stops waiting on a Sume job, not the job
context.WithTimeout cancels your status read, never the generation. A 29-line Go loop shows the DeadlineExceeded branch, and why the job id must be stored.
Written by Sume