Tutorial
How to Use flux-3-video via the HiAPI API: curl, Python, and a Working Request
A practical integration guide covering text-to-video, video continuation, and native audio parameters
What flux-3-video Exposes Through the API
Before you write a single line of code, it helps to know what the flux-3-video model actually lets you do through the HiAPI API. The endpoint family covers two calling modes that share a common request structure, plus an optional audio capability that you can enable or ignore depending on your use case.
Two calling modes
- Text-to-video — you send a text prompt and receive a newly generated clip. This is the mode you reach for when you have nothing but an idea and want motion, framing, and pacing produced for you.
- Video continuation — you send an existing clip (or a reference to it) alongside your instructions, and the model extends it forward. This is the mode you reach for when you have footage and want more of it without a visible seam.
Native audio
The model can also produce native audio alongside the video, controlled by optional parameters in the same payload. Because those parameters are optional, a video-only workflow never has to think about them — you simply omit the audio fields and the request behaves exactly as it would without them.
The important mental model for the rest of this guide: these are not two separate APIs with two separate tutorials. They are two shapes of the same request, and once you understand the shared skeleton, switching between them is a matter of swapping a few inputs. Everything else — credentials, headers, model identifier, response handling — stays the same.
That design is deliberate. It means your authentication code, error handling, retry logic, and response parsing are written once and reused across both modes, and adding audio later doesn't force a rewrite.
Auth, Endpoint, and the Anatomy of a Request
Every call to flux-3-video follows the same skeleton. Learn it once and both calling modes become variations on a theme.
Credentials
HiAPI authenticates requests with an API key. You pass it in the request headers, conventionally as a bearer token. Keep the key out of your source code — read it from an environment variable or a secrets manager so it never lands in version control:
export HIAPI_API_KEY="your-key-here"
Endpoint and model identifier
Calls go to the HiAPI API base URL, and the payload names the model explicitly with the identifier flux-3-video. Naming the model in the body rather than baking it into the URL means the same client code can target other models later with a one-line change.
The shared payload shape
Regardless of mode, the payload is a JSON object with three conceptual parts:
- The model field — always
flux-3-video. - The mode-defining inputs — in text-to-video this is a prompt; in continuation this is the source clip plus a prompt. This is the only part that meaningfully changes between modes.
- Optional modifiers — audio parameters and any other knobs. Omit them and you get the default behavior.
A request in pseudo-structure looks like this:
{
"model": "flux-3-video",
"input": {
"prompt": "..."
}
}
That's the whole idea: a model identifier, a nested input object carrying the mode-specific fields, and optional keys you add only when you need them. The next sections fill in the specifics for each mode.
Text-to-Video: Your First Working curl Request
Here is a minimal, complete request that generates a clip from a prompt. It assumes HIAPI_API_KEY is already exported in your shell.
curl -X POST "$HIAPI_BASE_URL/v1/generate" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "flux-3-video",
"input": {
"prompt": "A slow dolly shot through a rain-soaked neon alley at night, reflections on wet asphalt, cinematic"
}
}'
What each field does
Authorization— carries your bearer token. Without it the request is rejected before any generation happens.Content-Type: application/json— the body is JSON, so say so; omitting it is a common cause of confusing 4xx responses.model— identifiesflux-3-videoas the target model.input.prompt— the only required creative input in text-to-video mode. Write it like a shot description: subject, motion, framing, lighting, mood.
Prompt-writing notes that pay off
Because the prompt is the sole creative lever in this mode, its quality drives the result. Two habits help:
- Describe motion, not just content. "A dolly shot through…" gives the model a camera behavior to animate; a static description gives it less to work with.
- Keep it concrete. Specific lighting and material cues ("wet asphalt," "neon reflections") tend to produce more coherent frames than abstract adjectives.
Once you've run this and inspected the response, you've validated your key, your headers, and the base payload — the foundation for everything that follows.
Video Continuation: Extending an Existing Clip
Continuation reuses the skeleton from the previous section, but the input object changes shape. Instead of standing alone, the prompt is now paired with a source clip that the model extends.
curl -X POST "$HIAPI_BASE_URL/v1/generate" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "flux-3-video",
"input": {
"prompt": "Continue the camera push forward as the alley opens into a crowded market",
"video": "<reference-to-existing-clip>"
}
}'
What changes versus text-to-video
- A video input appears. You supply the existing clip the model should build on. This is the defining difference between the modes.
- The prompt becomes directional, not generative. In text-to-video you describe the whole scene; here you describe what happens next. Write it as a continuation instruction: where the camera goes, what enters frame, how the scene evolves.
- Everything else is identical. Same endpoint, same headers, same model identifier, same
inputwrapper. Your client code doesn't branch until it builds the payload.
Staying consistent across the seam
The model needs to match the source clip's look to avoid a visible cut. Short, specific instructions that preserve existing style tend to work better than long descriptions that re-imagine the scene. If the first continuation drifts, tighten the prompt toward the source's actual content rather than adding more detail elsewhere.
A note on the clip reference
Exact input conventions for the source clip are defined by the model's input schema on HiAPI. Follow that schema rather than guessing at field formats — it's the authoritative source for what the continuation input accepts.
Adding Native Audio Parameters
Native audio is where the optional-modifier pattern earns its keep. Audio parameters live in the same input object as the rest of your fields, and because they are optional, the requests from the previous two sections remain valid without them.
Where they sit
Audio settings belong inside input, alongside prompt and (in continuation mode) video. Conceptually:
{
"model": "flux-3-video",
"input": {
"prompt": "...",
"audio": {
"enabled": true
}
}
}
Keeping video-only workflows safe
The discipline that matters here is simple: treat the audio block as purely additive.
- Don't set audio fields to "off" values explicitly — omit them. An absent block is cleaner and less likely to conflict with future schema changes than an explicit disable.
- Build your payload incrementally. Start from the minimal body, then add the
audiokey only in code paths where the user has actually asked for it. That keeps your default path identical to the video-only examples. - Check the schema for exact flag names and accepted values before wiring audio into production. Parameter naming is defined by the model's input schema on HiAPI; the block name above shows placement, not a guaranteed field spelling.
When to enable it
Enable audio when the deliverable is a finished, self-contained clip — social content, demos, short narrative pieces. Leave it off when you'll lay in your own soundtrack or voiceover downstream; generating audio you're going to discard is wasted work in your pipeline.
Because audio rides inside the same payload as everything else, there is no separate call, no second credential, and no additional response-handling branch to maintain beyond reading whatever the response returns.
The Same Request in Python
Translating the curl call into Python is mechanical because the request shape is identical. The example below uses only the standard library so it runs anywhere, but the structure maps directly onto requests or httpx if you prefer.
import json
import os
import urllib.request
API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]
def generate_video(prompt, video=None, audio=False):
input_block = {"prompt": prompt}
# Continuation mode: attach the source clip.
if video is not None:
input_block["video"] = video
# Audio is strictly additive and omitted by default.
if audio:
input_block["audio"] = {"enabled": True}
payload = {"model": "flux-3-video", "input": input_block}
request = urllib.request.Request(
f"{BASE_URL}/v1/generate",
data=json.dumps(payload).encode("utf-8"),
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
method="POST",
)
with urllib.request.urlopen(request) as response:
return json.loads(response.read().decode("utf-8"))
if __name__ == "__main__":
# Text-to-video
result = generate_video(
"A slow dolly shot through a rain-soaked neon alley at night"
)
print(result)
# Video continuation with native audio
result = generate_video(
"Continue the camera push forward as the alley opens into a market",
video="<reference-to-existing-clip>",
audio=True,
)
print(result)
Why it's structured this way
- One function, two modes. The
videoparameter is optional; when it'sNone, the function produces a text-to-video request. When it's set, the same function produces a continuation request. No separate client, no duplicated headers. - Audio is opt-in. The
audioflag defaults toFalse, so the audio block is never added unless explicitly requested — exactly the pattern described earlier. - Key from the environment. The API key is read from
HIAPI_API_KEY, never hardcoded.
Adapt this by replacing the print calls with whatever your pipeline needs — writing the response to a manifest, enqueuing a follow-up job, or notifying a queue. The request logic itself doesn't change.
Troubleshooting and Production Checklist
When a call fails, work through this list in order — it catches the overwhelming majority of issues.
Diagnostic checklist
- 401 or auth errors — is
HIAPI_API_KEYactually exported in the shell or process running the code? A key set in one terminal doesn't reach a cron job. - 415 or unexpected parse errors — is
Content-Type: application/jsonpresent? Missing it is the classic silent failure. - 4xx on continuation calls — does your payload include the source clip in the form the model's input schema expects? A malformed clip reference fails before generation begins.
- Missing audio in the output — did the
audioblock make it into the payload? Log the serialized body when debugging; it's easy to build the dict and forget to attach the key. - Empty or truncated
input— print the exact JSON you're sending. Nearly every "weird" failure dissolves once you see the body on the wire.
Before you ship
- Never hardcode the key. Environment variables or a secrets manager, always.
- Log the request body and response body together, at least in staging. Reproducing a failure without the exact payload is guesswork.
- Treat optional fields as optional. Build payloads incrementally — minimal body first, then add
video, thenaudioonly when needed. This keeps your default path matching the documented examples. - Keep mode selection explicit in your own code. A single function with an optional
videoargument is fine; a boolean buried three layers deep is not. - Re-check the model's input schema on HiAPI whenever you add a field. It is the authoritative reference for parameter names and accepted formats, and it will stay more current than any tutorial.
The core takeaway bears repeating: text-to-video, continuation, and native audio are three variations on one request shape. Master the skeleton once, and every new capability is an additive change rather than a rewrite. Happy building.
Related articles
View all articles →-
Tutorial
How to Call hailuo-2.3-fast/image-to-video via the HiAPI API: curl and Python
A first working request for the fast, low-cost image-to-video tier — from model ID to downloaded MP4
9 min read -
Tutorial
How to Use hailuo-2.3/text-to-video via the HiAPI API: curl, Python, and a Working Request
11 min read -
Tutorial
Kandinsky 6.0 Pro Text-to-Video on HiAPI: curl and Python Tutorial
A request-first walkthrough: build the prompt-to-clip call, submit it, poll for completion, and download the result
11 min read