Short-form video has one unforgiving brief: it has to be vertical, it has to hook in the first second, and it usually needs sound. Most text-to-video APIs make you assemble that in pieces — generate a clip, add audio in post, re-crop to 9:16. gemini-omni-1.1-flash collapses it into a single async call on hiapi: one prompt in, one finished 9:16 clip out, with ambient audio already on the track.
This guide runs on one real clip — generated for this article, not illustrated — to show the workflow end to end, then digs into the pricing, because gemini-omni's cost model is unusual enough to change how you should render.
The clip, start to finish
Here's an 8-second, 1080p clip the model produced from a single prompt. It plays inline — vertical, with sound:
The exact prompt — copy it, it runs as-is:
Vertical 9:16 cinematic food close-up: a slow ribbon of golden honey drizzles
onto a short stack of warm pancakes, catching soft morning window light as it
pools and slides down the sides. A single pat of butter melts at the top, faint
steam rising. Shallow depth of field, gentle slow push-in, one continuous shot,
warm cozy color grade. Natural ambient sound: the soft drizzle of honey, a quiet
kitchen room tone, distant birdsong. No people, no text, no logos, no watermark.
That one request returned a 1080×1920 H.264 file with a stereo AAC audio track — the ambient sound is generated alongside the video, not layered on afterward. Two prompt habits did most of the work:
- Ask for one continuous shot. A short-form clip reads as a single beat; requesting one uninterrupted camera move stops the model from inventing cuts you didn't want.
- Write an explicit negative line.
No people, no text, no logos, no watermarkkeeps the frame clean for captions you'll add in your editor, and avoids baked-in text you can't remove later.
Why it fits short-form specifically
Three things line up with what vertical video actually needs:
- Native vertical.
aspect_ratio: "9:16"is a first-class input, so you generate portrait directly instead of cropping a 16:9 render down to a letterboxed frame. - Audio in the box. Every clip carries ambient sound. On a feed where most scrolls start muted, having a real track ready for the viewers who do unmute — with no separate music or SFX pass — removes a production step.
- One ID, every mode. The same
gemini-omni-1.1-flashID also accepts a reference image, first/last frames, or a source video. You can open with a text hook and later push a product still or a rough cut through the identical endpoint and key.
The flat-rate math that should change how you render
Most video APIs bill per second and scale that rate with resolution, so 1080p costs meaningfully more than 480p. gemini-omni doesn't. It bills a flat price per clip, and for every resolution up to 1080p that price is identical — only the clip length moves it:
| Clip length | 360p / 720p / 1080p | 4K |
|---|---|---|
| 4s | $0.45 | $1.05 |
| 6s | $0.60 | $1.20 |
| 8s | $0.75 | $1.35 |
| 10s | $0.90 | $1.50 |
Pricing verified against hiapi's live pricing page, October 2026. Passing reference videos switches billing to a flat $1.20 per clip up to 1080p (or $1.80 at 4K), regardless of length.
The practical consequence: render every draft at 1080p. On this model it costs exactly what 360p costs, so there's no reason to preview at low resolution and re-render later. The only lever that moves your bill on a non-4K clip is duration — so the discipline is about length, not quality. Fire 8-second 1080p drafts at $0.75 each, keep the ones that land, and reach for 4K only on the hero cut that's actually going out.
One API call
Creating a clip is a POST to open the task, then polling until it finishes.
curl -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-<your-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-omni-1.1-flash",
"input": {
"prompt": "<your prompt>",
"duration": 8,
"resolution": "1080p",
"aspect_ratio": "9:16"
}
}'
You get a task id back:
{"code":200,"data":{"taskId":"tk-hiapi-01M4MJDW91CEF46R26CJJ5NK5N"},"message":"success"}
Then poll GET /v1/tasks/<taskId> until status moves from handling → archiving → success. The finished payload puts the clip at output[0].url:
import time, requests
API = "https://api.hiapi.ai/v1"
H = {"Authorization": "Bearer sk-<your-key>", "Content-Type": "application/json"}
def make_clip(prompt, duration=8, resolution="1080p", ratio="9:16"):
body = {"model": "gemini-omni-1.1-flash",
"input": {"prompt": prompt, "duration": duration,
"resolution": resolution, "aspect_ratio": ratio}}
tid = requests.post(f"{API}/tasks", headers=H, json=body, timeout=30).json()["data"]["taskId"]
while True:
data = requests.get(f"{API}/tasks/{tid}", headers=H, timeout=30).json()["data"]
if data["status"] == "success":
return data["output"][0]["url"]
if data["status"] == "fail":
raise RuntimeError(data.get("error"))
time.sleep(6)
url = make_clip("<your prompt>")
open("clip.mp4", "wb").write(requests.get(url, timeout=120).content)
Four input fields matter: prompt, duration (4, 6, 8, or 10), resolution (360p, 720p, 1080p, or 4k), and aspect_ratio (16:9 or 9:16). Send a value outside those and the API rejects the request before it queues — a stray 2160p, for instance, comes back as invalid input: resolution: value must be one of '360p', '720p', '1080p', '4k', so a typo never costs you a clip. The full task-API reference lives in the hiapi docs.
One caveat worth coding around: output[0].url carries an expireAt timestamp and is not a permanent link. Download the file or push it to your own storage the moment the task reports success — don't persist the temporary URL.
Producing a set, not a single clip
Short-form is a volume game, so the real workflow is batch. Each clip is an independent task, which makes a mid-run crash cheap to recover from: key every job by a hash of its prompt, skip anything already downloaded, and a restart never double-bills a clip.
A workable loop:
- Write 8–12 prompt variants on one theme — different angles, lighting, subjects — all at 8s / 1080p / 9:16.
- Fire them as separate tasks and poll, or register a callback and let the results come to you.
- Review the set, keep the two or three that actually hook, and only then re-render those at 4K or a longer duration if the platform you're posting to rewards it.
When a still or a rough cut is your real starting point, feed it to the same gemini-omni-1.1-flash ID: a reference image to lock a product's look, first and last frames for a controlled transition, or a source clip for a restyle. The key and the polling code stay the same; only the input object changes.
How it compares
gemini-omni's flat rate makes it the cheapest way to get a short clip with audio out the door — $0.75 for 8 seconds at 1080p, with no per-second multiplier. Where another model wins, it wins on a specific axis:
- Seedance 2.5 bills per second and tops out at 720p today, but stretches to 30-second single takes — the pick when length matters more than resolution.
- Kling 3.0 layers synced speech on top of ambience and reaches 4K — better for talking or lip-synced content.
- Veo 3.1 is the image-to-video choice when you're animating an existing still rather than generating from text.
All four run on the same hiapi key and the same /v1/tasks endpoint, so switching is a one-line change to model — choose per shot, not per project. You can browse them side by side in the model catalog.
FAQ
Does gemini-omni-1.1-flash really include audio?
Yes. The clip in this guide came back as an MP4 with a real stereo audio track — ambient sound generated with the video, not added in post. You describe the sound in the prompt (the Natural ambient sound: ... line above) the same way you describe the visuals.
What's the cheapest way to test it? A 4-second clip is $0.45 at any resolution up to 1080p. Because those three resolutions cost the same, test at 1080p — there's no price reason to preview lower.
Can I make horizontal video too?
Yes. Set aspect_ratio: "16:9" for landscape; 9:16 is the short-form default. The price is identical either way.
How long can a clip be? 4, 6, 8, or 10 seconds per generation. For a longer edit, generate several clips and stitch them, or use a reference / first-and-last-frame pass to keep continuity across cuts.
Is the output URL permanent?
No. output[0].url has an expireAt and should be treated as a one-time handoff — download or re-host it as soon as the task reports success.
Ready to try it? Grab a key from the hiapi dashboard, drop your own prompt into the curl call above, and render your first vertical clip at 1080p — it costs the same $0.75 whether you preview small or go straight to full resolution.



