Gemini Omni Interactions API versus Sume /v1/videos: field mapping
Google returns Omni video as base64 in an Interactions response. Sume returns 202 with a polling_url and a content URL. See the mapping and a bytes helper.

Google's Gemini Omni call is POST /v1beta/interactions with a model and an input, and the video comes back inside the response as base64 data. Sume's equivalent is POST /v1/videos with model and prompt; it returns 202 with a job id and polling_url, and you download the MP4 from a content URL when the status is completed.
The two shapes
Google's minimal request is a model id of gemini-omni-1.1-flash and an input string. Video output appears in a steps array as a model_output with a video content item of MIME type video/mp4 and base64 data; the SDK exposes interaction.output_video.data. Sume follows the OpenRouter video shape: bare model id, prompt, optional duration, resolution, aspect_ratio, frame_images, input_references, and callback_url.
| Concept | Google Interactions API | Sume /v1/videos |
|---|---|---|
| Model id | gemini-omni-1.1-flash | gemini-omni-flash-1.1 |
| Prompt | input | prompt |
| First response | Video inside the response | 202 with id, polling_url, status |
| Output | base64 data in steps | unsigned_urls[0] content URL |
| Auth | API key in the query string | Authorization: Bearer |
| Retry safety | Not documented on the page read | Idempotency-Key header |
What changes in your code
The big change is the loop. With Google you read the video from the response; with Sume you poll GET /v1/videos/{id} and the statuses are pending, in_progress, completed, failed and cancelled. Cost is returned as usage.cost on completion. The single-reference rule also differs: a lone reference goes in input_references and conditions the whole clip.
A helper that behaves like output_video.data
This function returns raw MP4 bytes for a prompt, so the rest of an app that expects bytes from Google's SDK does not need to change.
import os, time, hashlib, json, requests
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
def output_video_bytes(prompt, **extra):
body = {"model": "gemini-omni-flash-1.1", "prompt": prompt, **extra}
key = "map-" + hashlib.sha256(json.dumps(body, sort_keys=True).encode()).hexdigest()[:24]
r = requests.post("https://api.sume.com/v1/videos", json=body, timeout=60,
headers={**H, "Idempotency-Key": key})
r.raise_for_status()
url = r.json()["polling_url"]
while True:
s = requests.get(url, headers=H, timeout=30).json()
if s["status"] == "completed":
return requests.get(s["unsigned_urls"][0], headers=H, timeout=120).content
if s["status"] in ("failed", "cancelled"):
raise RuntimeError(s.get("error", s["status"]))
time.sleep(10)
data = output_video_bytes("A marble rolls down a chain-reaction track", duration=5)
open("out.mp4", "wb").write(data)
print(len(data), "bytes")
Migration steps
A base64 payload in a response is simple but heavy: a 10-second 4K clip can be many megabytes inside a JSON body. A content URL lets you stream the file to disk and keeps your JSON handlers small.
- Swap the model id to
gemini-omni-flash-1.1. - Replace the query-string key with a bearer header.
- Move to a poll loop, or set
callback_urland verify the signature. - Add an
Idempotency-Keyderived from the request body.
Features that do not map one to one
Google's guide lists extension up to 40 seconds and edit inputs of 10 seconds or less; on Sume, edit uses the Video Router's video_url field and no extend field is exposed. Google bills output by the token; Sume bills the provider list per second times 1.25. See the Video Router and Videos guide for the full contract.
Sources
Related posts
More in Developers
- generate-video 409s: preview_not_ready vs preview_image_not_ready
generate-video on an avatar preview can return two 409s: the job is unfinished, or a public preview image is missing. How to tell them apart.
- generation_spend_cap_usd: null means $500, 0 is a 400, per ad variant
What the per-run spend cap does on Sume Format runs for a number, null, 0 and a value over 500, and why every ad variant should set its own.
- Alert when a new TTS model id lands in the Sume router catalog
September and October brought new voice models. A 20-line script diffs GET /v1/tts-router/models against yesterday's ids and tells you when a row is added.
- GitHub Actions: submit a 30 s video, jobs watch, upload the artifact
A workflow that posts to Sume.s /v1/videos, runs sume jobs watch with a timeout, downloads the clip and uploads it as a build artifact.
Written by Sume