> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apimart.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Wan3.0 Video Generation

>  - Alibaba Cloud Wanxiang 3.0 all-in-one reference video model
- Text-to-video / first frame / first+last frame / multi-modal reference / file or link reference
- Resolution 480P / 720P / 1080P, duration 2–30 seconds, or `-1` for model-chosen length
- Supports images, video, audio, documents, and public web pages as references 

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.apimart.ai/v1/videos/generations \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '{
      "model": "wan3.0-video",
      "prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
      "resolution": "720P",
      "size": "16:9",
      "duration": 5
    }'
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.apimart.ai/v1/videos/generations"

  payload = {
      "model": "wan3.0-video",
      "prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
      "resolution": "720P",
      "size": "16:9",
      "duration": 5,
  }

  headers = {
      "Authorization": "Bearer <token>",
      "Content-Type": "application/json",
  }

  response = requests.post(url, json=payload, headers=headers)

  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const url = "https://api.apimart.ai/v1/videos/generations";

  const payload = {
    model: "wan3.0-video",
    prompt: "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
    resolution: "720P",
    size: "16:9",
    duration: 5,
  };

  const headers = {
    Authorization: "Bearer <token>",
    "Content-Type": "application/json",
  };

  fetch(url, {
    method: "POST",
    headers: headers,
    body: JSON.stringify(payload),
  })
    .then((response) => response.json())
    .then((data) => console.log(data))
    .catch((error) => console.error("Error:", error));
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "io/ioutil"
      "net/http"
  )

  func main() {
      url := "https://api.apimart.ai/v1/videos/generations"

      payload := map[string]interface{}{
          "model":      "wan3.0-video",
          "prompt":     "A kitten runs across a moonlit rooftop",
          "resolution": "720P",
          "size":       "16:9",
          "duration":   5,
      }

      jsonData, _ := json.Marshal(payload)
      req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
      req.Header.Set("Authorization", "Bearer <token>")
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          panic(err)
      }
      defer resp.Body.Close()

      body, _ := ioutil.ReadAll(resp.Body)
      fmt.Println(string(body))
  }
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "code": 200,
    "data": [
      {
        "status": "submitted",
        "task_id": "task_01J9HA7JPQ9A0Z6JZ3V8M9W6PZ"
      }
    ]
  }
  ```

  ```json 400 theme={null}
  {
    "error": {
      "code": 400,
      "message": "Invalid request parameters",
      "type": "invalid_request_error"
    }
  }
  ```

  ```json 401 theme={null}
  {
    "error": {
      "code": 401,
      "message": "Authentication failed, please check your API key",
      "type": "authentication_error"
    }
  }
  ```

  ```json 402 theme={null}
  {
    "error": {
      "code": 402,
      "message": "Insufficient account balance, please top up and try again",
      "type": "payment_required"
    }
  }
  ```

  ```json 429 theme={null}
  {
    "error": {
      "code": 429,
      "message": "Too many requests, please try again later",
      "type": "rate_limit_error"
    }
  }
  ```
</ResponseExample>

## Authorization

<ParamField header="Authorization" type="string" required>
  All endpoints require Bearer Token authentication

  Get your API Key from the [API Key Management Page](https://apimart.ai/keys):

  ```
  Authorization: Bearer YOUR_API_KEY
  ```
</ParamField>

## Generation Modes

Model name is fixed to **`wan3.0-video`**. Modes are selected by request fields:

| Mode                  | Typical inputs                                                                     |
| --------------------- | ---------------------------------------------------------------------------------- |
| Text-to-video         | `prompt` only                                                                      |
| First-frame video     | one item in `image_urls` (frame family)                                            |
| First + last frame    | two items in `image_urls`, or `image_with_roles` with `first_frame` / `last_frame` |
| Reference video       | reference images / videos / audio; prompt may use “图1 / 视频1 / 音频1” style labels    |
| File / page reference | `file_url` or `link_url` (`prompt` optional)                                       |

## Request Parameters

### Basics

<ParamField body="model" type="string" required>
  Fixed value: `wan3.0-video`
</ParamField>

<ParamField body="prompt" type="string">
  Text description. **Required unless** media fields are provided (at least one of prompt or media).

  * Max **20,000** characters; overflow is truncated automatically (no error)
  * In reference mode, use “图N / 视频N / 音频N” to address assets; indices follow order **within each media type**
</ParamField>

<ParamField body="resolution" type="string" default="1080P">
  Output resolution (case-insensitive)

  * `480P`
  * `720P`
  * `1080P` (**default**, highest price)

  <Warning>
    Omitting `resolution` bills at **1080P**. Pass `480P` or `720P` explicitly when cost matters.
  </Warning>
</ParamField>

<ParamField body="size" type="string" default="adaptive">
  Aspect ratio. `aspect_ratio` is also accepted.

  * `adaptive` (default)
  * `16:9` / `4:3` / `1:1` / `3:4` / `9:16`
</ParamField>

<ParamField body="duration" type="integer" default="5">
  Duration in seconds:

  * `2`–`30`: fixed output length (default `5`)
  * `-1`: **model decides** the duration

  <Note>
    With reference video input, total input video duration + output duration must be ≤ 30 seconds. When `duration` is `-1`, the model chooses the length, which must still satisfy this constraint.
  </Note>
</ParamField>

<ParamField body="audio" type="boolean" default="true">
  Whether the output includes an audio track. Default `true`. **Price is the same with or without audio.**
</ParamField>

<ParamField body="seed" type="integer">
  Random seed in `[0, 2147483647]`
</ParamField>

<ParamField body="watermark" type="boolean" default="false">
  Whether to add a watermark. Default `false`
</ParamField>

<ParamField body="generation_type" type="string">
  How bare `image_urls` are classified:

  * `frame` — first/last frame family
  * `reference` — reference family

  If omitted, classification is automatic (see mutual exclusion rules).
</ParamField>

### Media inputs

<ParamField body="image_urls" type="string[]">
  Image URL array. Role assignment follows mutual exclusion rules.

  Public URL or Base64 (`data:image/png;base64,...`).
</ParamField>

<ParamField body="image_with_roles" type="object[]">
  Images with explicit roles. Each item:

  * `url`: image address
  * `role`: `first_frame` / `last_frame` / `reference_image` (common aliases accepted)
</ParamField>

<ParamField body="video_urls" type="string[]">
  Reference videos, up to **5** clips; each 1–15s, **total ≤ 15s**
</ParamField>

<ParamField body="audio_urls" type="string[]">
  Reference audio, up to **5** clips; each 1–15s, **total ≤ 15s**
</ParamField>

<ParamField body="audio_url" type="string">
  Single reference audio (single-value form of `audio_urls`)
</ParamField>

<ParamField body="file_url" type="string">
  Reference document URL, at most **1**. **Cannot be combined with `link_url`.**

  Formats include docx / doc / xlsx / xls / pptx / ppt / pdf / txt / key / pages / numbers / md, ≤100MB, ≤50 pages.
</ParamField>

<ParamField body="link_url" type="string">
  Public web page URL, at most **1**. Login-free pages only. **Cannot be combined with `file_url`.**
</ParamField>

## Mutual Exclusion of Media Families

Media belongs to one of two families and **must not be mixed** (validated before submit → 400, no task, no charge):

| Family               | Members                                                                 | Meaning                                |
| -------------------- | ----------------------------------------------------------------------- | -------------------------------------- |
| **Frame family**     | `first_frame`, `last_frame`                                             | Strict first / last frame of the video |
| **Reference family** | `reference_image`, `reference_video`, `reference_audio`, `file`, `link` | Model interprets content freely        |

### How bare `image_urls` are assigned

1. If `generation_type` is set → use it (`frame` / `reference`)
2. Else if the request already has reference-family inputs (`video_urls` / `audio_urls` / `audio_url` / `file_url` / `link_url`) → treat as `reference_image`
3. Else → frame family: first item `first_frame`, second `last_frame` (same as `wan2.7`)

Use `image_with_roles` when you need explicit control.

### Media limits and formats

| Type               | Limits                                                                            |
| ------------------ | --------------------------------------------------------------------------------- |
| First / last frame | ≤ 1 each                                                                          |
| Reference images   | ≤ 10                                                                              |
| Reference video    | ≤ 5 clips, 1–15s each, total ≤15s; mp4/mov; edge 240–4096 px, aspect ≤8:1, ≤100MB |
| Reference audio    | ≤ 5 clips, 1–15s each, total ≤15s; wav/mp3; ≤15MB                                 |
| Images             | JPEG/JPG/PNG (no alpha) / BMP / WEBP; edge 240–8000 px, aspect ≤8:1, ≤20MB        |
| Documents          | ≤100MB, ≤50 pages                                                                 |
| Web pages          | Public, login-free URLs                                                           |

## Request Examples

### Text-to-video

```json theme={null}
{
  "model": "wan3.0-video",
  "prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
  "resolution": "720P",
  "size": "16:9",
  "duration": 5
}
```

### First-frame video

```json theme={null}
{
  "model": "wan3.0-video",
  "prompt": "The person in the frame starts freestyle rapping, camera slowly pushes in",
  "image_urls": ["https://example.com/first.png"],
  "resolution": "720P",
  "duration": 5
}
```

### First + last frame

```json theme={null}
{
  "model": "wan3.0-video",
  "prompt": "Smile gradually becomes laughter, background light shifts from cool to warm",
  "image_urls": [
    "https://example.com/first.png",
    "https://example.com/last.jpg"
  ],
  "duration": 5
}
```

Or with `image_with_roles`:

```json theme={null}
{
  "model": "wan3.0-video",
  "prompt": "Smile gradually becomes laughter",
  "image_with_roles": [
    {"url": "https://example.com/first.png", "role": "first_frame"},
    {"url": "https://example.com/last.jpg", "role": "last_frame"}
  ],
  "duration": 5
}
```

### Multi-modal reference

```json theme={null}
{
  "model": "wan3.0-video",
  "prompt": "视频1抱着图1，在图3的椅子上弹奏一支舒缓的乡村民谣，并说道：\"今天的阳光真好。\"",
  "generation_type": "reference",
  "image_urls": [
    "https://example.com/object1.jpg",
    "https://example.com/object2.png",
    "https://example.com/chair.png"
  ],
  "video_urls": ["https://example.com/role.mp4"],
  "resolution": "480P",
  "duration": 5
}
```

> With `video_urls` present, bare `image_urls` auto-classify as reference images; setting `generation_type: "reference"` is clearer.

### File reference video

`prompt` may be omitted; generation is driven by the document:

```json theme={null}
{
  "model": "wan3.0-video",
  "file_url": "https://example.com/glass.pptx",
  "resolution": "480P",
  "duration": 10
}
```

### Web page reference video

```json theme={null}
{
  "model": "wan3.0-video",
  "prompt": "Turn this article into a short educational video",
  "link_url": "https://example.com/article/123",
  "duration": 15
}
```

## Billing

**Per second × resolution** (aligned with official list price). Audio on/off does not change price:

| Resolution | Unit price    | 5s    | 30s    |
| ---------- | ------------- | ----- | ------ |
| 480P       | **¥0.30** / s | ¥1.50 | ¥9.00  |
| 720P       | **¥0.60** / s | ¥3.00 | ¥18.00 |
| 1080P      | **¥1.20** / s | ¥6.00 | ¥36.00 |

* Default is **1080P** (most expensive); pass `480P` / `720P` when cost-sensitive
* Billable seconds: for `2`–`30`, use the requested `duration`; for `-1`, use the **actual** output seconds
* `audio: true/false` does **not** affect price

## Limits and Notes

| Item             | Notes                                                           |
| ---------------- | --------------------------------------------------------------- |
| Duration         | Integer `2`–`30`, or `-1` (model decides length)                |
| With video input | Input video total duration + output duration ≤ 30s              |
| Latency          | Typically 1–5 minutes; longer for long clips                    |
| Result URL       | Mirrored to the platform CDN after success for long-term access |
| Prompt           | ≤20,000 characters; overflow truncated                          |

## Common Errors

All are **sync 400** (no task, no charge):

| Case                                | What to do                                                                  |
| ----------------------------------- | --------------------------------------------------------------------------- |
| Mixing frame and reference families | Pick one family via `generation_type`, or set roles with `image_with_roles` |
| Both `file_url` and `link_url`      | Choose one                                                                  |
| Invalid `duration`                  | Only `2`–`30` or `-1`                                                       |
| Unsupported resolution (e.g. 4K)    | Only `480P` / `720P` / `1080P`                                              |
| More than 10 reference images       | Reduce to ≤10                                                               |
| Empty `prompt` and empty media      | Provide at least one                                                        |

## Response

<ResponseField name="code" type="integer">
  Status code; 200 on success
</ResponseField>

<ResponseField name="data" type="array">
  Response data array

  <Expandable title="Array elements">
    <ResponseField name="status" type="string">
      Task status; `submitted` on create
    </ResponseField>

    <ResponseField name="task_id" type="string">
      Task ID for polling
    </ResponseField>
  </Expandable>
</ResponseField>

<Note>
  **Query results**

  Video generation is async. Poll [Get Task Status](/en/api-reference/tasks/status) or `GET /v1/videos/generations/{task_id}`.

  Recommended interval 5–10 seconds; generation typically takes 1–5 minutes. On success, use URLs in `result.videos`.
</Note>
