Skip to main content
A single generation is capped at 20 seconds; a film isn’t. This recipe builds length both ways the API gives you:
  1. Cuts inside one generation: write the shots into the prompt and the model executes real cuts, with one soundtrack binding them.
  2. A shot pipeline: script a film as a shot list, generate the shots concurrently (rate limits are per concurrent generation, so a film’s shots can run in parallel), and cut them together with ffmpeg.
By the end you’ll have a four-shot, ~20-second film with a continuous musical idea, built from a shot list you can rewrite into anything.

1. Setup

2. Cuts inside one generation

Write the shots explicitly and mark the cuts. Two things make in-prompt cuts land:
  • Consecutive shots must differ strongly, and scale is the strongest kind of difference: macro to wide to aerial reads as three deliberate cuts, where three similar angles blend into one drifting take.
  • One audio idea across all shots. Name a continuous bed and the cuts read as editing instead of channel-surfing. Here the bed has two layers: a cello drone that never breaks, and one substance (fire) whose sound is scaled per shot rather than restarted.
Keep it to two or three shots per generation. A film’s worth of cuts is what the pipeline in the next section is for.
The same fire, followed from the size of a fingertip to the size of a coastline; the cuts land where the scale jumps.

3. A film as a shot list

Past two or three shots, generate each shot as its own clip and edit. This is how you get films of any length, and it has real advantages over one long generation: shots run in parallel, a miss costs one shot instead of the film, and you keep editorial control of timing. The craft that holds a multi-generation film together:
  • A world bible. One paragraph describing the world (place, palette, light, film grade) pasted into every shot prompt word for word. Consistency across generations comes from consistent text, so copy it, don’t paraphrase it per shot.
  • An audio motif. Name the same musical idea in every shot, staged for where the shot sits in the film (enters, warmer, builds, resolves). You cut the picture; the motif carries the through-line.
  • One beat per shot. Each shot does one thing. The film is the sequence, not any single clip.
The film here: the night shift in the glasshouse. A vast Victorian glasshouse after closing, and the plants are working. Four shots, one night, played straight.

4. Generate the shots concurrently

Rate limits are on concurrent generations (5 per org on the API), not requests per second. Going over returns 429 (too many active tasks): a signal to wait for a slot, never something to retry in a loop. So the pattern for a film is a thread pool. run_shots is the whole thing: three workers keeps two tasks of headroom under the cap. If a shot fails or gets moderated, the cell stops with that shot’s name in the traceback; finished shots are already on disk, so reword the miss and re-run the cell - only the missing shots cost anything.

First job for the pool: one line, three languages

Before the film, a controlled experiment: three payloads, identical except for one templated block, run through the same pool. Hold everything else fixed and any difference in the output traces to the one lever you moved. The lever here is the spoken language, and it rides on two prompt rules that make dialogue reliable anywhere:
  • The exactly-once direction. “Speaks on camera exactly once, the complete sentence, no repetition and no other words in the entire shot.” Without it, lines repeat or pick up filler.
  • The language lock. “Every word in French, no English words at all.” Without it, the model tends to translate the line back to English and speak that.
Because the three payloads are independent, they fill the pool at once: rate limits are per active generation (5 per org), so three in flight is one full, legal batch.
The same carved beak lip-syncs a line it was drawn saying in three languages, voiced and synced in the single generation that draws the picture. Sound on: the words come back transcribable in each language, so the model is speaking the line, not captioning it.

Now the film

Same pool, real workload: the four shots of the shot list, with the retry policy from the quickstart. An Error is worth one resubmit; a moderated result means reword, never resubmit unchanged.

5. The edit

Straight cuts in script order, one re-encode for uniform codec parameters. The dissolve-free cut is the right default: the shots were written to contrast, and the motif carries the continuity.

Scaling it up

Everything past four shots is the same loop with a longer shot list.
  • Length: a 12-shot film is one dict and the same run_shots call. Duration 5 suits action and single beats; 10 to 20 suits scenes that breathe or carry dialogue.
  • A recurring character: hold identity with reference_images on every shot the character appears in. Build the reference sheet once, as in Start from images; a world bible holds the world together, references hold a face.
  • A shot that ended too soon: extend it with start_video (Edit, recast, continue) instead of re-rolling.
  • Webhooks over polling: for long shot lists, set webhook_url on each request and let the results come to you.
The whole workflow (write, generate in parallel, gate, cut) is also the shape an agent can drive unattended. That’s the agent skill recipe.