HiAPI
Blog

Guide

Build Short-Form Video with flux-3-max/text-to-video on the HiAPI API

An end-to-end workflow: shot planning, prompt orchestration, camera motion, native audio, and a runnable request

Nov 3, 2026 12 min read
封面图:骨白色纸页层层错位堆叠,如套印偏移,其间夹入一张锈红色纸页,下方仅有平直投影。

Why Short-Form Video Is a Prompt Orchestration Problem

Most teams that fail with text-to-video fail for the same reason: they write one enormous prompt describing a whole scene and expect the model to return a finished thirty-second clip. That is not how generation works. A model produces a single continuous shot per call, and every call is a small, self-contained decision about subject, action, framing, and sound.

The mental model that actually holds up is orchestration. You are not prompting one video; you are directing a sequence of shots and then assembling them. A short-form piece — a product teaser, a social hook, a narrated explainer — is typically four to eight shots. Each shot has one job: establish, demonstrate, transition, resolve. Once you accept that decomposition, the API stops being a slot machine and starts being a rendering step inside a pipeline you control.

This matters because the failure modes of text-to-video are mostly continuity failures, not quality failures. A single shot can look beautiful and still be unusable if the next shot has a different character, a different light direction, or a camera that suddenly floats. Those problems are solved before the request is sent, in how you plan and describe shots — not by adding adjectives to a mega-prompt.

The rest of this guide walks through that workflow end to end on flux-3-max/text-to-video via HiAPI: splitting a script into shots, writing per-shot prompts, treating camera motion as a controlled dimension, using native audio so you skip a separate sound pass, and wrapping everything in a small reproducible request loop.

Planning Shots Before You Call the API

Before writing any code, turn the script into a shot list. A shot list is a plain data structure: one entry per generation call, each with a clear purpose. Here is the shape that works well as an intermediate representation:

[
  {
    "id": "s1",
    "role": "establish",
    "subject": "ceramic pour-over coffee dripper on a wooden counter",
    "framing": "medium close-up, three-quarter angle",
    "durationIntent": "short",
    "camera": "slow push in",
    "audio": "quiet room tone, soft steam"
  },
  {
    "id": "s2",
    "role": "demonstrate",
    "subject": "hot water spiraling over coffee grounds",
    "framing": "tight overhead macro",
    "durationIntent": "short",
    "camera": "locked off",
    "audio": "water pouring, gentle hiss"
  }
]

A few planning rules that save retries later:

  • One idea per shot. If your shot description contains "and then," split it. Models handle a single continuous action far better than a sequence of beats.
  • Duration intent, not exact seconds. Decide whether a shot is a quick cut or a longer hold, and express that as intent. Exact timing belongs to your editing/stitching stage, where you have frame-accurate control.
  • Fix the framing vocabulary early. Choose terms like wide, medium, close-up, overhead, low angle and reuse them verbatim across shots. Consistent vocabulary produces more consistent results.
  • Plan continuity anchors. Decide what stays the same: character description, wardrobe, palette, time of day, light direction. Write these once as a shared prefix and reuse it in every prompt.
  • Order matters for review. Generate in script order so you can review the sequence as it will play, not as isolated clips.

Once the shot list exists, the API calls become mechanical — which is exactly what you want, because it makes them retryable and reproducible.

Writing Per-Shot Prompts for flux-3-max/text-to-video

A good per-shot prompt is structured, not conversational. Instead of one long free-form string, compose each prompt from a small number of labeled bands. This makes prompts diffable, reusable, and easy to tweak when a single element is wrong.

The five-band structure

  1. Subject — who or what, with the continuity details you decided on (appearance, wardrobe, product specifics).
  2. Action — one continuous motion or state, described in present tense.
  3. Setting — location, time of day, light quality, palette.
  4. Camera — framing plus movement, using your fixed vocabulary. Covered in detail in the next section.
  5. Audio — the ambient and foley intent for this shot.

Compose them in a fixed order so your own debugging is consistent:

CONTINUITY = (
    "a minimalist ceramic pour-over coffee dripper, matte white, "
    "on a warm oak counter, soft morning window light from the left, "
    "muted natural palette"
)

def shot_prompt(subject, action, setting, camera, audio):
    return (
        f"{subject}. {action}. {setting}. "
        f"Camera: {camera}. Audio: {audio}."
    )

prompt = shot_prompt(
    subject=f"{CONTINUITY}",
    action="steam rising steadily as water slowly blooms the coffee grounds",
    setting="kitchen counter at dawn, shallow depth of field",
    camera="medium close-up, slow push in, no shake",
    audio="quiet room tone, soft water pour, faint steam hiss",
)

Keeping shots visually consistent

The single highest-leverage habit is the shared continuity block. Put it at the front of every subject band, unchanged, across all shots in a sequence. When a shot drifts visually, you can then bisect the problem: is it the continuity block, or the shot-specific action?

Two more habits that reduce drift:

  • Avoid contradictory adjectives. "Cinematic documentary handheld static" is three opposing instructions. Pick one.
  • Describe light once. If the continuity block says morning light from the left, don't let a later shot introduce overhead fluorescent lighting unless that cut is intentional.

What to leave out of the prompt

Leave aspect ratio, output length, and other technical parameters out of the prose and pass them as request parameters where the API exposes them. Prose is for what the shot is; parameters are for how it is delivered. Mixing the two makes both harder to change.

Controlling Camera Motion

Camera motion is the dimension most likely to be left to chance, and it is the one that most affects whether a sequence feels directed. The model will move the camera in some way if you don't specify; unspecified motion reads as drift, and drift is what makes generated footage look accidental.

Treat motion as a small closed vocabulary

Don't improvise camera language per shot. Define a small set of moves and reuse them:

  • Locked off — no movement. The safest choice for product detail and close-ups.
  • Push in / pull out — dolly toward or away from the subject. Good for emphasis and reveals.
  • Pan left / pan right — rotate horizontally. Use for establishing space.
  • Tilt up / tilt down — rotate vertically. Use sparingly; it reads as dramatic.
  • Track — move with a subject. Requires a clearly moving subject to anchor against.

Write them in the camera band followed by a negative instruction that suppresses the rest: Camera: slow push in, no shake, no handheld drift.

The negative clause matters. Saying "push in" alone leaves room for the model to add wobble; saying "push in, no shake" narrows it.

Match motion to shot role

Motion should serve the edit. A practical mapping:

  • Establishing shots — one clear move (slow push in or a gentle pan) to give the eye somewhere to go.
  • Detail shots — locked off. Detail is already visually busy; motion competes with it.
  • Transitions — a consistent move across adjacent shots (both pushing in, both panning the same direction) makes cuts feel intentional even without a transition effect.
  • Hero shots — a single deliberate move, never two combined.

Keep one move per shot

Combining moves ("push in while panning right and tilting up") produces muddy results. If a beat needs complex camera work, split it into two shots. Your stitching stage can join them, and you keep frame-level control over the cut.

Motion consistency across a sequence

Decide the dominant motion for the whole piece up front — for example, "everything pushes in slowly" — and deviate only for effect. Sequences with consistent motion direction read as authored; sequences with random motion read as generated.

Using Native Audio in Your Pipeline

Native audio generation changes the architecture of a short-form pipeline. In a traditional flow, you generate silent video, then run a separate audio pass — either a text-to-audio model or a licensed library of foley and music — then align the two in an editor. Each stage is another service, another credential, another failure mode, and another place where timing can slip.

When the video model produces audio inline, the sound is generated in the same inference step as the picture, so it is inherently aligned to what happens on screen. Pouring water sounds like pouring water at the moment the water pours. That eliminates the alignment work almost entirely.

Two pipelines, one difference

Separate audio stage:            Native audio:
  shot -> video (silent)           shot -> video + audio
       -> audio generation              -> assemble
       -> alignment / mixing
       -> assemble

The practical upside is fewer moving parts. The practical constraint is that you need to plan sound in the prompt, not after the fact.

Planning shots around sound

Because audio is part of the generation, write it as part of the shot, not as an afterthought:

  • Name the dominant sound. Audio: water pouring, gentle hiss beats Audio: pleasant kitchen sounds.
  • Keep it sparse. One or two clear elements per shot. Layered audio descriptions tend to smear.
  • Decide about music deliberately. If you plan to lay a music bed over the whole piece in your editor, keep shot audio ambience-only so it doesn't fight the track.
  • Think about continuity of sound. Like visual continuity, audio continuity across cuts helps — the same room tone in adjacent shots makes a sequence feel like one place.

Where the editor still wins

Native audio does not remove the editor. It removes the alignment step. You will still want final loudness normalization and, if you use music, a mix pass where dialogue and foley are ducked under the bed. Budget for that in your pipeline, but budget far less for it than you would with a separate generation stage.

A Runnable Request and Assembly Flow

With a shot list and prompt builder in place, the request layer is thin. The key decisions are: how you call the model, how you handle ordering and retries, and how you hand results to stitching.

The orchestration loop

import time

SHOTS = [
    # your planned shot list from the earlier step
]

def generate_shot(shot, attempt=0):
    payload = {
        "model": "flux-3-max/text-to-video",
        "prompt": build_prompt(shot),
        # pass delivery parameters here, not in the prose:
        # aspect ratio, length, etc. per the API reference
    }
    try:
        return client.generate(payload)
    except TransientError:
        if attempt >= 3:
            raise
        time.sleep(2 ** attempt)
        return generate_shot(shot, attempt + 1)

def run_sequence(shots):
    results = {}
    for shot in shots:
        results[shot["id"]] = generate_shot(shot)
    return [results[s["id"]] for s in shots]

Three things make this loop production-safe rather than a demo:

  • Ordered iteration. Generating in script order means partial failures leave you with a prefix you can review, and re-running only the missing shots is straightforward.
  • Keyed results. Store outputs by shot id, not by list position. If shot three fails and you regenerate it, you want to overwrite by key, not re-append.
  • Bounded retries with backoff. Transient failures are normal in any generation API. Cap retries so a single bad shot doesn't wedge the whole job.

Handing off to stitching

Your generation loop should produce a manifest — the shot list with output references attached — and stop there. Stitching is a separate step that consumes the manifest: it trims each clip to its intended duration, applies transitions, lays any music bed, and normalizes loudness.

{
  "sequence": [
    {"id": "s1", "clip": "out/s1.mp4", "trim": "keep_first_portion"},
    {"id": "s2", "clip": "out/s2.mp4", "trim": "keep_first_portion"}
  ],
  "audioStrategy": "native_bed_plus_music"
}

Keeping stitching separate from generation is what makes the whole pipeline reproducible: you can regenerate one shot, drop it into the manifest, and re-render the final cut without touching anything else.

Production Checklist and Common Pitfalls

A short-form pipeline is reliable when the boring parts are boring. Run through these checks before you scale up volume.

Consistency

  • Continuity block is identical across every shot in a sequence.
  • Camera vocabulary is closed and reused, not improvised.
  • Light direction and palette are stated once and not contradicted later.
  • Review shots in order — continuity problems are invisible when clips are viewed in isolation.

Retries and idempotency

  • Results are keyed by shot id so regeneration overwrites rather than duplicates.
  • Retries are bounded and use backoff; a permanently failing shot should fail loudly, not silently.
  • The shot manifest is the source of truth for what was generated — persist it alongside outputs.

Cost control

Generation is billed by the work the model produces, so your main lever is how many shots you generate and how many times you regenerate them. Practical controls: lock the shot list before generating, review a single representative shot per sequence before rendering the rest, and avoid speculative re-rolls of shots that already pass review. Check the current pricing on the site's price panel when you plan volume.

Output review

  • Watch each sequence end to end at real playback speed, not clip by clip.
  • Check audio against picture: does the sound match the moment?
  • Check the first two seconds specifically — that is where short-form attention is won or lost.
  • Keep a small set of known-good reference prompts and compare new output against them when quality seems to slip.

Common pitfalls

  • The mega-prompt. One prompt for a whole scene produces one long, unfocused shot. Split it.
  • Duration in prose. Express timing at the edit stage, not in the prompt text.
  • Random camera motion. Unspecified motion drifts; specify the move and suppress the rest.
  • Treating audio as a separate product decision. Plan sound in the shot, then mix in the editor.

The workflow in this guide — plan shots, structure prompts, control camera motion, use native audio, orchestrate with a manifest — turns flux-3-max/text-to-video from an unpredictable generator into a dependable rendering step in a pipeline you own.

Related articles

View all articles →

Start building with persistent AI artifacts

Get your API key and call image, video and audio models through one task-based API.

Read the API docs