Videos
Every video model behind one request shape. Per-model credits, durations, qualities and levels are listed under Video models on the overview.
Generate a video
Submits a video job and charges it. The accepted fields vary by model family. Every field below documents which models read it, and fields a model does not read are ignored rather than rejected.
A duration, quality, aspect_ratio, model_level, seedance_mode,
sync_mode or output_format outside the model's set in GET /models/
is rejected with 400 invalid_request naming the field and the legal
values. Send these values as JSON strings. An omitted duration,
quality or aspect_ratio takes the model's default. Nothing is charged
for a rejected request, but a request rejected after it claimed upload ids
has used them up; upload the files again before retrying.
prompt is required for every model except kling-motion and genjutsu
(where it refines the motion taken from the reference video) and
lipsync (which does not use a prompt). Over the model's
max_prompt_chars it fails with prompt_too_long.
Input images are upload ids in image1…imageN (this endpoint does not
read uploads) or hosted https:// URLs in image_urls, which fill the
lowest free imageN slots in order. Send multipart/form-data instead of
JSON to attach image files directly as image1…imageN. Reference video
and audio must be upload ids.
Headers
Idempotency-KeyMakes this submission safe to retry. A replay within 15 minutes returns
the original body with status 200 and is not charged again; a replay while
the first request is still in flight returns 409 request_in_progress.
The key is fingerprinted with the request's prompt (its dialogue, for
speech), so reusing a key with a different prompt starts a new
generation. A client_request_id body field works identically.
Generate a video › Request Body
modelAccepted as mode too; if both are sent, model wins. An unknown value fails with invalid_model.
promptRequired for every model except kling-motion, lipsync and
genjutsu. Over the model's max_prompt_chars the request is
rejected.
durationLength in seconds, as a string, from the model's durations in
GET /models/; anything else is rejected and an omitted value takes
the model default. Send it as a string: a JSON number passes the
check but the model then renders its default length. Ignored where
the length comes from an input: kling-motion, lipsync,
genjutsu, gemini-omni-video when video1 is sent, and
seedance25 in seedance_mode: edit.
qualityOne of 480, 720, 1080, 4k, per model, from its qualities in
GET /models/; anything else is rejected and an omitted value takes
the model default. Send it as a string, as with duration. kling
is 1080-only and lipsync takes only auto.
aspect_ratioPer-model set from GET /models/. image makes the output follow the
input image where supported (sent upstream as auto or adaptive).
Anything outside the model's set is rejected; an omitted value takes
the model default.
model_levelSelects the variant within a model family, and with it the price.
| Model | Values | Default |
|---|---|---|
seedance2 | pro, mini, fast | mini |
kling-motion | 2.6, 3.0 | 2.6 |
lipsync | v2-pro, v3 | v3 |
genjutsu | standard, lite | standard |
A value outside the model's set is rejected. Send it as a string:
a JSON number such as 2.6 is not read and the default is used.
lipsync at v2-pro
needs a video input; v3 takes either one video or one image.
genjutsu at lite takes a reference video of at most 15 s.
seedance2 renders 1080 and 4k only at pro; asking for them at
another level is rejected rather than quietly lowered.
veo_modeveo3 only. Derived from the number of input images when omitted:
none → text-to-video; one → first-frame-last-frame, with the
image as the first frame; two or three → image-to-video, with the
images as references. Send first-frame-last-frame explicitly to use
two images as the first and last frame. image-to-video takes 1 to 3
images and first-frame-last-frame 1 or 2.
seedance_modeseedance2 and seedance25 only. Derived when omitted: no images →
text-to-video; one image → image-to-video; two images →
first-frame-last-frame on seedance2 but reference-to-video on
seedance25; three or more images, or any video1/audio1 →
reference-to-video.
reference-to-video is the multimodal scene and needs at least one
image or video. Limits:
seedance25 | seedance2 | |
|---|---|---|
| Images | 30 | 9 |
| Videos | 10 | 3 |
| Audios | 10 | 3 |
| Each reference video or audio | 2–30 s | 2–15 s |
| Total reference length | 30 s | 15 s |
| Reference video size | 200 MB | 50 MB |
edit and extend are seedance25 only and need at least one input
video. In edit the output follows the input footage, so duration,
aspect ratio and mode come from it, and every input video must be at
least 4 s; it holds twice the input seconds plus 3 s at the
with-video rate. extend continues the footage and charges the input
plus the requested duration. Both settle on delivery to the input
plus the delivered seconds.
generate_audioseedance2 and seedance25. The price is identical either way, so
leaving it on never costs extra.
web_searchNo longer has any effect. seedance2 text-to-video requests always ground the scene in a web lookup.
output_formatseedance25 only.
sync_modelipsync only. How a video and an audio of different lengths are
matched: bounce plays the video back and forth, loop repeats it,
cut_off trims the longer one, silence pads the audio with
silence, and remap changes the video speed. The price follows the
output length: the audio length, except the longer of the two with
silence and the shorter with cut_off.
character_orientationkling-motion. Which source sets the character's facing. image limits the reference video to 10 s.
background_sourcekling-motion at model_level: 3.0 only. Which source provides the background.
image_urlsHosted input images, https:// only and not on Hoosha media hosts;
they are handed to the provider as-is. They fill the lowest free
image1…imageN slots: if you sent only image2, the first URL
becomes image1. They count toward the model's image cap.
image1Input image: an upload id (/videos/ reads upload ids only from
these positional fields, not from uploads), or a file part in
multipart (png, jpg, jpeg, webp or gif, at most
10,000,000 bytes, not converted). Continue with image2, image3, …
How many images each model reads: seedance25 30, seedance2 9,
genjutsu 8 (at least 1 required), grok-imagine 7,
gemini-omni-video 7 (5 when video1 is sent), veo3 3, kling3
1, kling-motion exactly 1, lipsync 1 when no video1 is sent
(ignored with one), runway and seedance only image1. On kling,
image2 is the end frame. Only grok-imagine and genjutsu reject
extra images with too_many_images; elsewhere images beyond the
limit are dropped. For first-frame-last-frame, image1 is the
first frame and image2 the last.
video1Reference video, as an upload id. Required by kling-motion (3–30 s),
by genjutsu (5–30 s, 5–15 s on lite, at most 200 MB) and by
lipsync at model_level: v2-pro; optional on v3, which falls back
to image1. gemini-omni-video reads video1 only (at most 10 s and
100 MB). seedance25 reference scenes take up to video10 and
seedance2 up to video3.
audio1Reference audio, as an upload id. Required by lipsync, where its
length (2–30 s, 2–15 s with an image) sets the bill and files over
10 MB are rejected. seedance25 reference scenes take up to
audio10 and seedance2 up to audio3.
Generate a video › Responses
An Idempotency-Key replay within 15 minutes. The body is byte-identical
to the original 202 and nothing was charged again.
idPoll this with GET /generations/{id}/.
typeMedia type of the job.
modelThe model as you requested it.
statusAlways processing — nothing is rendered yet.
credits_chargedAlready debited. This is the final price, except for seedance25 edit/extend jobs where it is a hold that is partially refunded after delivery.
created_at