# Video generation

> Part of the ChinaAPI documentation. HTML: https://dash.chinaapi.ai/docs/api/video/

Video models answer as tasks rather than as a single response. `POST /v1/videos` returns a task id with `"status": "queued"`, and `GET /v1/videos/{task_id}` reports progress until the task reaches `completed` or `failed`. On completion the finished file is the signed URL under `metadata.url`; it carries an `Expires` parameter, so download the file rather than storing the link. A failed task carries the upstream code and text in `error.code` and `error.message`, which is usually enough to see which field the request was missing. `POST /v1/video/generations` reaches the same handler for clients already written against that path.

**POST /v1/videos**

```
curl https://api.chinaapi.ai/v1/videos \
  -H "Authorization: Bearer $CHINAAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wan2.7-i2v",
    "prompt": "the cat turns and walks toward the camera",
    "input_reference": "https://example.com/first-frame.jpg",
    "size": "1280*720",
    "duration": 5
  }'

# {"id":"task_9f2c...","task_id":"task_9f2c...","object":"video",
#  "model":"wan2.7-i2v","status":"queued","progress":0}
```

**GET /v1/videos/{task_id}**

```
curl https://api.chinaapi.ai/v1/videos/task_9f2c... \
  -H "Authorization: Bearer $CHINAAPI_KEY"

# {"id":"task_9f2c...","object":"video","model":"wan2.7-i2v",
#  "status":"completed","progress":100,
#  "metadata":{"url":"https://.../output.mp4?Expires=..."}}
```

## wan2.7-t2v — Text to video

`model` and `prompt` are the only required fields. Without `size` and `duration` the gateway submits `1280*720` for five seconds.

## wan2.7-i2v — Image to video

Animate a still image. `input_reference` takes a publicly reachable image URL and becomes the first frame; send `size` and `duration` with it.

## wan2.7-r2v — Reference to video

Build a video from reference material. `input_reference` takes one reference image; to pass several use `images` instead, and `video_url` adds a reference video — references count together, up to five. Do not send `input_reference` and `images` together, because the gateway keeps only `input_reference`.

## wan2.7-videoedit — Video editing

Edit an existing clip from a prompt. `video_url` takes the source video, which has to be 2 to 10 seconds of MP4 or MOV, and `size` sets the output.

## doubao-seedance-2-5-260628 — 30-second video

Reference images go in `images`, and `input_reference` takes a single one; sending both keeps both. Length goes in `seconds` or `duration`, and vendor parameters go in `metadata`, where `resolution` is either `480p` or `720p`.

## doubao-seedance-2-0-260128 — Seedance 2.0

Same request shape as `doubao-seedance-2-5-260628`, including the `role` rules for `metadata.content`. `doubao-seedance-2-0-fast-260128` and `doubao-seedance-2-0-mini-260615` trade quality for speed and cost, and the 2.0 line needs at least one image or video reference where 2.5 also accepts audio alone.

## kling-v3 — Kling 3.0

The first frame goes in `image`; this family never reads `input_reference`. `mode` defaults to `std` and `duration` to 5 seconds. `metadata` carries the rest: `image_tail` for a closing frame, `sound` as `on` or `off` (`off` by default), plus `negative_prompt`, `cfg_scale` and `camera_control`.

## kling-3.0-turbo — Value tier

Send `prompt` for text to video, or add `image` and the gateway builds the `contents` array upstream expects. Sizing lives under `metadata.settings`: `resolution` is `720p` or `1080p`, `duration` runs 3 to 15 seconds, and `aspect_ratio` is `16:9`, `9:16` or `1:1`. Audio is always included and has no switch.

## kling-v3-omni — Multi-image reference

Reference-driven generation from several images at once. Every parameter lives in `metadata`, and there is no `resolution` field — `mode` is the quality tier. See the worked example below.

## MiniMax-H3 — Native audio

Takes the gateway's own fields and assembles the upstream payload for you: `image` or `input_reference` becomes the first frame, `images` become reference images, and `video_url` becomes a reference video. `size` selects `768P` or `2K` and `duration` is a whole number from 4 to 15. Text-only requests need an explicit `metadata.ratio` other than `adaptive`.

## MiniMax-Hailuo-2.3 — Hailuo

Together with `MiniMax-Hailuo-2.3-Fast` and `MiniMax-Hailuo-02`. These read only `prompt`, `duration` and `size` from the top level; every image goes through `metadata`, as `first_frame_image`, `last_frame_image` or `subject_reference`.

## happyhorse-1.1-t2v — 480P tier

With `happyhorse-1.1-i2v` and `happyhorse-1.1-r2v`. The fields match the `wan2.7` family — `prompt`, `input_reference`, `size`, `duration` — and 480P is priced here, so `832*480` is accepted where `wan2.7` refuses it. Multiple references go in `metadata.input.media`, because the automatic assembly the `images` field triggers is specific to `wan2.7-r2v`.

> [!NOTE]
> Tip
>
> Spell `size` as width and height joined by an asterisk, as in `1280*720`. The letter x is not accepted: `832x480` comes back as `invalid size: 832x480, example: 1920*1080`. `duration` is a whole number of seconds. For `wan2.7-i2v`, `wan2.7-r2v` and `wan2.7-videoedit` the gateway folds `size` into a resolution tier and upstream has only two, so send `1280*720` for 720P or `1920*1080` for 1080P. A 480P size such as `832*480` has no price at these three and is either refused outright or accepted and then failed upstream with `InvalidParameter`; a failed task is refunded, but the round trip is wasted either way. `wan2.7-t2v` takes the value as written.

> [!NOTE]
> Tip
>
> The Kling family reads the aspect ratio from `size` through a fixed table that spells sizes with the letter x — `1280x720`, `1920x1080`, `720x1280`, `1080x1920`, `1024x1024`, `512x512` — and anything it does not recognise becomes `1:1` without an error. Sending the asterisk form `1280*720` to `kling-v3` therefore returns a square video rather than a complaint, so set `metadata.aspect_ratio` directly when the framing matters.

> [!NOTE]
> Tip
>
> `MiniMax-Hailuo-2.3`, `MiniMax-Hailuo-2.3-Fast` and `MiniMax-Hailuo-02` drop top-level `image`, `input_reference`, `images` and `video_url` without saying so: the request succeeds, but it runs as text to video and is billed as such. Put the image in `metadata.first_frame_image` instead, add `metadata.last_frame_image` for a closing frame, and use `metadata.subject_reference` for subject references. `MiniMax-H3` is the exception in this family and does read the top-level fields.

**kling-v3-omni · multi-image reference**

```
curl https://api.chinaapi.ai/v1/video/generations \
  -H "Authorization: Bearer $CHINAAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kling-v3-omni",
    "prompt": "the character from the references walks through a neon-lit street",
    "metadata": {
      "image_list": [
        {"image_url": "https://example.com/character.jpg"},
        {"image_url": "https://example.com/outfit.jpg"},
        {"image_url": "https://example.com/scene.jpg"}
      ],
      "mode": "std",
      "duration": "5",
      "aspect_ratio": "16:9",
      "sound": "off"
    }
  }'
```

**GET /v1/video/generations/{task_id}**

```
curl https://api.chinaapi.ai/v1/video/generations/task_9f2c... \
  -H "Authorization: Bearer $CHINAAPI_KEY"

# {"code":"success",
#  "data":{"task_id":"task_9f2c...","status":"SUCCESS",
#          "progress":"100%","fail_reason":"",
#          "result_url":"https://.../output.mp4"}}
```

> [!NOTE]
> Tip
>
> A reference image carries no `type`; the field exists only to mark `first_frame` or `end_frame`, and `aspect_ratio` is required whenever no first frame is present. `mode` is the quality tier — `std`, `pro` or `4k` — and the upstream default is `pro`, which bills 1.33x the listed price, while `4k` bills 5x; send `mode` explicitly so the charge is the one you expect. `duration` is a string from `"3"` to `"15"` and `sound` defaults to `off`. A reference video goes in `video_list` and must set `"refer_type": "feature"`: the editing mode `base` is billed by the length of the video you supply, cannot be priced before submission, and is refused. Reference images also have a minimum size upstream, and an icon-sized file passes submission only to fail the task with `Image pixel is invalid`; the failed task is refunded, but the round trip is lost.

> [!NOTE]
> Tip
>
> The two paths report results in different shapes. `GET /v1/videos/{task_id}` answers in the OpenAI video format, where the file is `metadata.url` and progress is a number. `GET /v1/video/generations/{task_id}` answers `{"code": "success", "data": {…}}`, where the file is `data.result_url`, `data.status` is an upper-case word such as `SUCCESS` or `FAILURE`, `data.progress` is a string such as `"100%"`, and a failure explains itself in `data.fail_reason`. Poll whichever path you submitted to.

**doubao-seedance-2-5-260628 · first frame**

```
curl https://api.chinaapi.ai/v1/videos \
  -H "Authorization: Bearer $CHINAAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "doubao-seedance-2-5-260628",
    "prompt": "the subject slowly turns toward the camera",
    "images": ["https://example.com/first-frame.jpg"],
    "seconds": "5",
    "metadata": {"resolution": "480p"}
  }'
```

**doubao-seedance-2-5-260628 · reference mode**

```
curl https://api.chinaapi.ai/v1/videos \
  -H "Authorization: Bearer $CHINAAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "doubao-seedance-2-5-260628",
    "prompt": "keep the subject from the reference image",
    "seconds": "5",
    "metadata": {
      "resolution": "480p",
      "ratio": "16:9",
      "content": [
        {
          "type": "image_url",
          "image_url": {"url": "https://example.com/reference.jpg"},
          "role": "reference_image"
        }
      ]
    }
  }'
```

> [!NOTE]
> Tip
>
> An image with no `role` is read as the first frame rather than as a reference: the output follows the aspect ratio of that image, sending `ratio` alongside it is refused with `InvalidParameter.TaskTypeConstraint`, and a `seconds` of 2 is refused there as well, while 5 works. `generate_audio` defaults to true upstream, so the file comes back with an audio track unless you set it to false in `metadata`. Tag every part of `metadata.content` with a `role` to reach the full reference mode — up to 30 images, 10 videos and 10 audio clips, audio-only input, and 30 seconds in one shot — where `ratio` is accepted.
