Skip to navigation

Video Generation

Video takes much longer to make than text or images, so it runs as a job: you start it, poll until it’s done, then download the file. Flow AI follows the OpenAI Videos API.

Find a video model

  • On the Models page, pick the Video type. Each model’s page shows its price per second, which can vary by resolution.
  • From the API, GET /v1/models lists the models your key can call; video models have "mode": "video".

How it works

  1. Start the job with POST /v1/videos. You get a video id straight away, with status queued.
  2. Poll GET /v1/videos/{id} until the status is completed or failed.
  3. Download the MP4 from GET /v1/videos/{id}/content.

Start a job

The samples use the OpenAI SDK set up as in the Quickstart.

curl https://ai.hyperflow.fun/v1/videos \
-H "Authorization: Bearer $HYPERFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "google/veo-3.1-generate-001",
"prompt": "A paper boat drifting slowly across a calm lake, static camera, soft light",
"seconds": "4",
"size": "1280x720"
}'

The response is the new job:

{
"id": "video_3f9c2a...",
"object": "video",
"model": "google/veo-3.1-generate-001",
"status": "queued",
"progress": 0,
"seconds": "4",
"size": "1280x720",
"created_at": 1782886429,
"completed_at": null,
"error": null
}

Parameters

ParameterRequiredNotes
modelYesA video model id
promptYesWhat happens in the video: subject, motion, camera, lighting
secondsNoLength in seconds, a positive whole number. Each model offers its own lengths
sizeNoResolution, such as 1280x720 or 720x1280. Some models price sizes differently
input_referenceNoAn image to start the video from, on models that take one

Any other field is removed before the request reaches the model.

Poll for the result

GET /v1/videos/{id} returns the job. Videos usually take from about thirty seconds to a few minutes.

import time
while video.status in ("queued", "in_progress"):
time.sleep(10)
video = client.videos.retrieve(video.id)
if video.status == "failed":
print("Failed:", video.error)

The OpenAI SDKs also have client.videos.create_and_poll(...) (Python) and client.videos.createAndPoll(...) (TypeScript), which start the job and wait for it.

Statuses

StatusMeaning
queuedThe job is waiting to start
in_progressThe video is being made
completedThe video is ready to download
failedThe video wasn’t made. error.code says why
error.codeMeaning
video_failedThe model couldn’t make the video
video_expiredThe video wasn’t ready within an hour and was given up on

Download the video

Once the status is completed, GET /v1/videos/{id}/content returns the MP4 itself.

curl https://ai.hyperflow.fun/v1/videos/video_3f9c2a.../content \
-H "Authorization: Bearer $HYPERFLOW_API_KEY" \
--output video.mp4

Asking before the video is ready returns 409 with the code video_not_ready.

List your videos

GET /v1/videos returns your recent videos, newest first, in a data list. Add ?limit= for up to 100; the default is 20.

curl "https://ai.hyperflow.fun/v1/videos?limit=10" \
-H "Authorization: Bearer $HYPERFLOW_API_KEY"

Videos are tied to your account: any of your keys can read them, and no one else’s can.

Best practices

  • Describe motion and camera. “Slow pan left”, “static camera”, “handheld” and the lighting matter as much as the subject.
  • Start short. Try prompts at the shortest length and smallest size, then make the final video.
  • Poll gently. Every 10 to 30 seconds is plenty.
  • Handle failed. Check status and error on every poll.

Troubleshooting

400 when starting a job. seconds must be a positive whole number, and seconds and size must be ones the model offers. Check the model’s page.

The job stays queued for a long time. Hosts can be busy. Keep polling; a job not done within an hour fails with video_expired.

404 not_found on status or content. The id is wrong. Video ids start with video_.

409 video_not_ready. Wait until the status is completed before downloading.

Billing

A video is held when you start it, for the seconds you asked for at the price for its size. Once it’s made, you’re charged for those seconds at the price it was held at. A video that fails, or is given up on after an hour, isn’t charged, and its hold is released.