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

# Wan

> Wan 3.0, 2.7, and 2.6 video generation, reference inputs, editing, and asynchronous task handling.

<link rel="alternate" hrefLang="en" href="https://mixroute.ai/docs/api-reference/endpoint/wan" />

<link rel="alternate" hrefLang="zh-Hans" href="https://mixroute.ai/docs/zh-hans/api-reference/endpoint/wan" />

<link rel="alternate" hrefLang="zh-Hant" href="https://mixroute.ai/docs/zh-hant/api-reference/endpoint/wan" />

<link rel="alternate" hrefLang="ja" href="https://mixroute.ai/docs/ja/api-reference/endpoint/wan" />

<link rel="alternate" hrefLang="x-default" href="https://mixroute.ai/docs/api-reference/endpoint/wan" />

Wan uses one MixRoute video endpoint. Keep model at the root and place the provider input and parameters objects inside metadata. Model versions use different input protocols; choose the exact ID and schema below.

`POST https://api.mixroute.ai/v1/video/generations`

## Models

| Model ID | Mode | Resolution | Duration (seconds) |
| - | - | - | - |
| [wan3.0-video-prime](/docs/model-api/alibaba/wan3.0-video-prime) | High-speed All-in-One | 480P / 720P / 1080P | 2-30 / -1 |
| [wan3.0-video](/docs/model-api/alibaba/wan3.0-video) | All-in-One Video Generation | 480P / 720P / 1080P | 2-30 / -1 |
| [wan2.7-t2v](/docs/model-api/alibaba/wan2.7-t2v) | Text-to-Video | 720P / 1080P | 2-15 |
| [wan2.7-i2v](/docs/model-api/alibaba/wan2.7-i2v) | Image-to-Video | 720P / 1080P | 2-15 |
| [wan2.7-r2v](/docs/model-api/alibaba/wan2.7-r2v) | Reference-to-Video | 720P / 1080P | 2-15 (no video) / 2-10 (with video) |
| [wan2.7-videoedit](/docs/model-api/alibaba/wan2.7-videoedit) | Video Editing | 720P / 1080P | 2-10 |
| [wan2.6-t2v](/docs/model-api/alibaba/wan2.6-t2v) | Text-to-Video | 720P / 1080P | 2-15 |
| [wan2.6-i2v](/docs/model-api/alibaba/wan2.6-i2v) | Image-to-Video | 720P / 1080P | 2-15 |
| [wan2.6-i2v-flash](/docs/model-api/alibaba/wan2.6-i2v-flash) | Fast Image-to-Video | 720P / 1080P | 2-15 |
| [wan2.6-r2v](/docs/model-api/alibaba/wan2.6-r2v) | Reference-to-Video | 720P / 1080P | 2-10 |
| [wan2.6-r2v-flash](/docs/model-api/alibaba/wan2.6-r2v-flash) | Fast Reference-to-Video | 720P / 1080P | 2-10 |

Model availability depends on your account's [model list](/docs/api-reference/endpoint/list-models). A vendor model or dated snapshot not returned by your account should not be assumed available.

## Request Envelope

| Field | Type | Required | Description |
| - | - | - | - |
| `model` | string | Yes | Exact MixRoute model ID. |
| `metadata` | object | Yes | Container for the provider request body, excluding model. |
| `metadata.input` | object | Yes | Native input object. Prompt and media requirements depend on the selected model. |
| `metadata.parameters` | object | No | Native generation settings. Preserve their field names and nesting. |

<Info>
  Authenticate with Authorization: Bearer and your MixRoute key. No Alibaba key, workspace ID, regional endpoint, or X-DashScope-Async header is needed. Do not send input/parameters at the root or flatten their contents directly into metadata.
</Info>

Use metadata.input.prompt for the prompt. Compatibility fallbacks are metadata.prompt, then top-level prompt, in that order; when present, metadata.input.prompt takes precedence. Supply a prompt or valid media input, and obey the selected model's own required-input rules.

Native fields are forwarded without renaming. New provider fields may be supplied in their original input/parameters location; the upstream service validates model-specific combinations. This does not make a field supported by every model.

## Wan 3.0

`wan3.0-video-prime` uses the same input/parameters schema as `wan3.0-video`, with faster generation. The rules in this section apply to both.

| Field | Type | Required | Description |
| - | - | - | - |
| `metadata.input.prompt` | string | By mode | Text instruction, at most 20000 characters; excess text is truncated. Required unless media is supplied. |
| `metadata.input.media` | object\[] | By mode | Media items; required unless prompt is supplied. Use the combinations below. |
| `metadata.input.media[].type` | string | By mode | Required per item: first\_frame, last\_frame, reference\_image, reference\_video, reference\_audio, file, or link. |
| `metadata.input.media[].url` | string | By mode | Required per item. Public HTTP/HTTPS URL; supported images may use a Base64 data URI. Native OSS resources must be accessible to the route account. |
| `metadata.parameters.resolution` | string | No | 480P, 720P, or 1080P. MixRoute explicitly fills 1080P when omitted. |
| `metadata.parameters.ratio` | string | No | adaptive (default), 16:9, 4:3, 1:1, 3:4, or 9:16. Use adaptive for extension. |
| `metadata.parameters.duration` | integer | No | Default 5. Without source video: 2-30 seconds. With video: total source-video duration plus generated duration must not exceed 30 seconds. -1 selects duration automatically. |
| `metadata.parameters.audio` | boolean | No | Default true. false produces video without an audio track. |
| `metadata.parameters.seed` | integer | No | -1 or 0-2147483647. -1 or omission selects a random seed; repeatability is not guaranteed. |
| `metadata.parameters.prompt_extend` | boolean | No | Prompt rewriting; default true. |
| `metadata.parameters.watermark` | boolean | No | Add an AI watermark; default false. |

### Media Types

| type | Limit / Usage |
| - | - |
| `first_frame` / `last_frame` | At most one of each; first frame alone or first+last frame. Do not use a last frame alone. |
| `reference_image` | Up to 10 images. |
| `reference_video` | Up to five videos, 1-15 seconds each, at most 15 seconds total. |
| `reference_audio` | Up to five audio clips, 1-15 seconds each, at most 15 seconds total. |
| `file` | One public document, at most 100 MB and 50 pages for paginated formats. |
| `link` | One publicly accessible webpage that does not require login. |

* Frame mode (first\_frame/last\_frame) is mutually exclusive with reference\_\*, file, and link. Unlike Wan 2.7 I2V, Wan 3.0 frame mode cannot include driving audio.
* Reference images, videos, and audio may be combined. file and link are mutually exclusive, but either may accompany reference\_\* media. Respect every per-type limit and the overall limit of 20 media items.
* Refer to media by type-specific order: Image 1, Video 1, Audio 1, or 图1、视频1、音频1.
* Editing/extension require reference\_video and a matching prompt. Use ratio=adaptive for extension; for editing, adaptive and duration=-1 preserve source framing and let the model choose the duration. Input video time plus output time must still fit within 30 seconds.

<Note>
  Wan 3.0 does not use size, negative\_prompt, template, img\_url, first\_frame\_url, last\_frame\_url, or audio\_url. The gateway removes legacy fields and can convert audio\_url to a reference\_audio item. New requests should use input.media directly.
</Note>

## Wan 2.7

| Field | Type | Required | Description |
| - | - | - | - |
| `metadata.input.prompt` | string | By mode | Up to 5000 characters, with excess truncated. Required for T2V/R2V; optional for I2V/VideoEdit when required media is present. |
| `metadata.input.negative_prompt` | string | No | Content to exclude; at most 500 characters, with excess truncated. |
| `metadata.input.audio_url` | string | No | T2V only: driving audio URL, WAV/MP3, 2-30 seconds, at most 15 MB. Long audio is trimmed; a short clip leaves a silent tail. |
| `metadata.input.media` | object\[] | By mode | Required for I2V, R2V, and VideoEdit. Each mode has different item types and combinations. |
| `metadata.input.media[].type` | string | By mode | Required per media item; use the model-specific types below. |
| `metadata.input.media[].url` | string | By mode | Required per media item. Public HTTP/HTTPS URL; image inputs also support data:image/...;base64,... . Accessible native OSS references are supported. |
| `metadata.input.media[].reference_voice` | string | No | R2V reference\_image/reference\_video only: voice-timbre reference URL, WAV/MP3, 1-10 seconds, at most 15 MB. Overrides the reference video voice. |
| `metadata.parameters.resolution` | string | No | 720P or 1080P (default), with exact capitalization. |
| `metadata.parameters.ratio` | string | No | T2V/R2V/VideoEdit: 16:9, 9:16, 1:1, 4:3, or 3:4. T2V/R2V default to 16:9; R2V ignores ratio when a first frame is supplied. VideoEdit follows its source when omitted. I2V follows its image/video input and does not use this setting. |
| `metadata.parameters.duration` | integer | No | T2V/I2V: 2-15 seconds, default 5. R2V: 2-15 without video references, 2-10 with video, default 5. VideoEdit: omit to retain source length; 2-10 trims from the start. |
| `metadata.parameters.audio_setting` | string | No | VideoEdit only: auto (default) lets the prompt guide audio handling; origin preserves source audio. |
| `metadata.parameters.prompt_extend` | boolean | No | Prompt rewriting; default true. |
| `metadata.parameters.watermark` | boolean | No | Add an AI watermark; default false. |
| `metadata.parameters.seed` | integer | No | 0-2147483647; omitted means random. Identical seeds do not guarantee identical output. |

### Input Modes

| Model | Media Rules |
| - | - |
| `wan2.7-t2v` | prompt plus optional input.audio\_url; no media array. |
| `wan2.7-i2v` | first\_frame; first\_frame+driving\_audio; first\_frame+last\_frame; first\_frame+last\_frame+driving\_audio; first\_clip; or first\_clip+last\_frame. Each type appears at most once. |
| `wan2.7-r2v` | 1-5 reference\_image/reference\_video items total, optionally one first\_frame. reference\_voice belongs to each reference item, not a separate media type. |
| `wan2.7-videoedit` | Exactly one video item (type=video), optionally up to four reference\_image items. |

For I2V continuation with first\_clip, duration controls the final total length including the source clip, not just the added seconds. For R2V, use Image 1 / Video 1 references, counting images and videos separately. Wan 2.7 uses resolution/ratio rather than the Wan 2.6 T2V/R2V size field; shot\_type is no longer used. I2V output follows the source aspect ratio and omits ratio.

## Wan 2.6

| Field | Type | Required | Description |
| - | - | - | - |
| `metadata.input.prompt` | string | By mode | At most 1500 characters, with excess truncated. Required for T2V/R2V; optional for I2V with a source image. R2V references use character1, character2, etc. |
| `metadata.input.negative_prompt` | string | No | Content to exclude; at most 500 characters, with excess truncated. |
| `metadata.input.img_url` | string | By mode | I2V only, required: first-frame image URL or image Base64 data URI. |
| `metadata.input.audio_url` | string | No | T2V/I2V only: driving audio URL, WAV/MP3, 2-30 seconds, at most 15 MB. |
| `metadata.input.reference_urls` | string\[] | By mode | R2V only, required: 1-5 source URLs, at most five images and three videos, with at most five total. Each source identifies one subject. |
| `metadata.input.reference_video_urls` | string\[] | No | Deprecated R2V video-only input, at most three videos. Prefer reference\_urls; do not mix both formats. |
| `metadata.parameters.size` | string | No | T2V/R2V only: `width*height` from the size table; default `1920*1080`. |
| `metadata.parameters.resolution` | string | No | I2V only: 720P or 1080P (default). The aspect ratio follows the first-frame image. |
| `metadata.parameters.duration` | integer | No | T2V/I2V and I2V Flash: 2-15 seconds; R2V and R2V Flash: 2-10 seconds. Default 5. |
| `metadata.parameters.prompt_extend` | boolean | No | T2V/I2V only: prompt rewriting, default true. Not an R2V setting. |
| `metadata.parameters.shot_type` | string | No | single (default) or multi. For T2V/I2V, effective only when prompt\_extend=true. R2V uses this field directly. Takes precedence over shot instructions in the prompt. |
| `metadata.parameters.audio` | boolean | No | I2V Flash / R2V Flash only: true (default) generates audio, false produces silent output. I2V Flash: false overrides input.audio\_url. Not a standard 2.6 model switch. |
| `metadata.parameters.watermark` | boolean | No | Add an AI watermark; default false. |
| `metadata.parameters.seed` | integer | No | 0-2147483647; omitted means random. Identical seeds do not guarantee identical output. |

### T2V / R2V Sizes

| Tier | Allowed size Values |
| - | - |
| 720P | `1280*720`, `720*1280`, `960*960`, `1088*832`, `832*1088` |
| 1080P | `1920*1080`, `1080*1920`, `1440*1440`, `1632*1248`, `1248*1632` |

Wan 2.6 R2V uses character1, character2, etc., in reference\_urls order, rather than the Wan 2.7 Image/Video labels. Its references require public HTTP/HTTPS or accessible OSS URLs. Standard Wan 2.6 models do not expose audio=false; use I2V Flash or R2V Flash for silent output. Legacy effect templates are not a common capability of these models.

Flash variants retain their corresponding I2V/R2V input protocol. I2V Flash uses input.img\_url and parameters.resolution; R2V Flash uses input.reference\_urls and parameters.size. For I2V Flash driving audio, use WAV/MP3, 3-30 seconds, at most 15 MB.

## Media Constraints

| Input | Constraints |
| - | - |
| Images | JPEG/JPG, PNG without transparency, BMP, WebP; 240-8000 px per edge, at most 20 MB. Wan 3.0/2.7 additionally limit the long/short ratio to 8:1. |
| Wan 3.0 reference video | MP4/MOV; 1-15 seconds each, total at most 15 seconds; at least 16 fps; 240-4096 px per edge; ratio up to 8:1; at most 100 MB per file. |
| Wan 2.7 video | MP4/MOV; 240-4096 px per edge, ratio up to 8:1, at most 100 MB. first\_clip/VideoEdit source: 2-10 seconds. R2V reference: 1-30 seconds. |
| Wan 2.6 R2V video | reference\_urls: MP4/MOV, 1-30 seconds, at most 100 MB. The deprecated reference\_video\_urls format requires 2-30 seconds. |
| Audio | WAV/MP3, at most 15 MB each. Wan 3.0 reference audio: 1-15 seconds, total at most 15. Wan 2.7 reference\_voice: 1-10 seconds. T2V driving audio / I2V driving\_audio: 2-30 seconds. |
| Wan 3.0 files | docx, doc, xlsx, xls, pptx, ppt, pdf, txt, key, pages, numbers, md; at most 100 MB. PDF/Word/PowerPoint/Keynote/Pages documents: at most 50 pages. |

Use public URLs for portable requests. OSS temporary links and provider asset IDs are scoped to the upstream account/region and must be accessible to the selected channel. Do not send your MixRoute key when fetching a third-party CDN result URL.

## Request Examples

### Wan 3.0 Video Prime

```bash theme={null}
curl --request POST "https://api.mixroute.ai/v1/video/generations" \
  --header "Authorization: Bearer $MIXROUTE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "model": "wan3.0-video-prime",
  "metadata": {
    "input": {
      "prompt": "A red ceramic mug slowly rotates on a white tabletop."
    },
    "parameters": {
      "resolution": "480P",
      "duration": 2,
      "audio": false
    }
  }
}'
```

Set MIXROUTE\_API\_KEY and replace example.com media URLs with accessible source files. Each POST creates a separate task; do not automatically repeat a timed-out submission.

### Wan 3.0 Video

```bash theme={null}
curl --request POST "https://api.mixroute.ai/v1/video/generations" \
  --header "Authorization: Bearer $MIXROUTE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "model": "wan3.0-video",
  "metadata": {
    "input": {
      "prompt": "A red ceramic mug slowly rotates on a white tabletop. Static camera, soft studio lighting."
    },
    "parameters": {
      "resolution": "480P",
      "ratio": "16:9",
      "duration": 2,
      "audio": false,
      "prompt_extend": false,
      "watermark": false
    }
  }
}'
```

### Wan 2.7 T2V

```bash theme={null}
curl --request POST "https://api.mixroute.ai/v1/video/generations" \
  --header "Authorization: Bearer $MIXROUTE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "model": "wan2.7-t2v",
  "metadata": {
    "input": {
      "prompt": "A red ceramic mug slowly rotates on a white tabletop. Static camera, soft studio lighting."
    },
    "parameters": {
      "resolution": "720P",
      "ratio": "9:16",
      "duration": 2,
      "prompt_extend": false,
      "watermark": false
    }
  }
}'
```

### Wan 2.7 I2V

```bash theme={null}
curl --request POST "https://api.mixroute.ai/v1/video/generations" \
  --header "Authorization: Bearer $MIXROUTE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "model": "wan2.7-i2v",
  "metadata": {
    "input": {
      "prompt": "A red ceramic mug slowly rotates on a white tabletop. Static camera, soft studio lighting.",
      "media": [
        {
          "type": "first_frame",
          "url": "https://example.com/reference.png"
        }
      ]
    },
    "parameters": {
      "resolution": "720P",
      "duration": 2,
      "prompt_extend": false,
      "watermark": false
    }
  }
}'
```

### Wan 2.7 R2V

```bash theme={null}
curl --request POST "https://api.mixroute.ai/v1/video/generations" \
  --header "Authorization: Bearer $MIXROUTE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "model": "wan2.7-r2v",
  "metadata": {
    "input": {
      "prompt": "Image 1 slowly rotates on a white tabletop. Static camera, soft studio lighting.",
      "media": [
        {
          "type": "reference_image",
          "url": "https://example.com/reference.png"
        }
      ]
    },
    "parameters": {
      "resolution": "720P",
      "ratio": "1:1",
      "duration": 2,
      "watermark": false
    }
  }
}'
```

### Wan 2.7 VideoEdit

```bash theme={null}
curl --request POST "https://api.mixroute.ai/v1/video/generations" \
  --header "Authorization: Bearer $MIXROUTE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "model": "wan2.7-videoedit",
  "metadata": {
    "input": {
      "prompt": "Change the mug color to blue while preserving the original motion and white tabletop.",
      "media": [
        {
          "type": "video",
          "url": "https://example.com/source.mp4"
        }
      ]
    },
    "parameters": {
      "resolution": "720P",
      "duration": 2,
      "watermark": false
    }
  }
}'
```

### Wan 2.6 T2V

```bash theme={null}
curl --request POST "https://api.mixroute.ai/v1/video/generations" \
  --header "Authorization: Bearer $MIXROUTE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "model": "wan2.6-t2v",
  "metadata": {
    "input": {
      "prompt": "A red ceramic mug slowly rotates on a white tabletop. Static camera, soft studio lighting."
    },
    "parameters": {
      "size": "1280*720",
      "duration": 2,
      "prompt_extend": false,
      "watermark": false
    }
  }
}'
```

### Wan 2.6 I2V

```bash theme={null}
curl --request POST "https://api.mixroute.ai/v1/video/generations" \
  --header "Authorization: Bearer $MIXROUTE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "model": "wan2.6-i2v",
  "metadata": {
    "input": {
      "prompt": "A red ceramic mug slowly rotates on a white tabletop. Static camera, soft studio lighting.",
      "img_url": "https://example.com/reference.png"
    },
    "parameters": {
      "resolution": "720P",
      "duration": 2,
      "prompt_extend": false,
      "watermark": false
    }
  }
}'
```

### Wan 2.6 R2V

```bash theme={null}
curl --request POST "https://api.mixroute.ai/v1/video/generations" \
  --header "Authorization: Bearer $MIXROUTE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "model": "wan2.6-r2v",
  "metadata": {
    "input": {
      "prompt": "character1 slowly rotates on a white tabletop. Static camera, soft studio lighting.",
      "reference_urls": [
        "https://example.com/reference.png"
      ]
    },
    "parameters": {
      "size": "1280*720",
      "duration": 2,
      "watermark": false
    }
  }
}'
```

### First and Last Frames

```bash theme={null}
curl --request POST "https://api.mixroute.ai/v1/video/generations" \
  --header "Authorization: Bearer $MIXROUTE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "model": "wan2.7-i2v",
  "metadata": {
    "input": {
      "prompt": "A closed gift box slowly opens, revealing a red ceramic mug.",
      "media": [
        {
          "type": "first_frame",
          "url": "https://example.com/first.png"
        },
        {
          "type": "last_frame",
          "url": "https://example.com/last.png"
        }
      ]
    },
    "parameters": {
      "resolution": "720P",
      "duration": 5
    }
  }
}'
```

### File Input Without a Prompt

```bash theme={null}
curl --request POST "https://api.mixroute.ai/v1/video/generations" \
  --header "Authorization: Bearer $MIXROUTE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "model": "wan3.0-video",
  "metadata": {
    "input": {
      "media": [
        {
          "type": "file",
          "url": "https://example.com/product.pptx"
        }
      ]
    },
    "parameters": {
      "resolution": "480P",
      "duration": 5
    }
  }
}'
```

## Responses and Polling

Submission returns a MixRoute task\_id (and id alias). This is not the upstream task ID.

```json theme={null}
{
  "id": "TASK_ID",
  "task_id": "TASK_ID",
  "object": "video",
  "model": "wan3.0-video",
  "status": "queued"
}
```

`GET https://api.mixroute.ai/v1/video/generations/{task_id}`

| Gateway Status | Upstream Status | Action |
| - | - | - |
| `NOT_START` / `QUEUED` | `PENDING` | Wait and query again. |
| `IN_PROGRESS` | `RUNNING` | Continue polling. |
| `SUCCESS` | `SUCCEEDED` | Read data.result\_url. |
| `FAILURE` | `FAILED` / `CANCELED` / `UNKNOWN` | Stop; inspect data.fail\_reason and the upstream response. |

```json theme={null}
{
  "code": "success",
  "message": "",
  "data": {
    "task_id": "TASK_ID",
    "status": "SUCCESS",
    "progress": "100%",
    "result_url": "https://example.com/generated.mp4",
    "fail_reason": "",
    "data": {
      "request_id": "UPSTREAM_REQUEST_ID",
      "output": {
        "task_id": "UPSTREAM_TASK_ID",
        "task_status": "SUCCEEDED",
        "video_url": "https://example.com/generated.mp4"
      },
      "usage": {
        "output_video_duration": 2,
        "SR": 480,
        "video_count": 1
      }
    }
  }
}
```

<Warning>
  Read result\_url only after SUCCESS. On failure the gateway may place the failure text in result\_url, so it is not necessarily a URL. The code="success" envelope only means the query succeeded, not that the generation succeeded.
</Warning>

The complete upstream result is retained at data.data; read usage and request\_id there. UNKNOWN means the upstream task is missing or expired, not necessarily a generation error. Poll about every 15 seconds and back off on rate limits/transient errors. Upstream task lookup and result links have limited retention, typically 24 hours; save completed output promptly.

## Python Workflow

```python theme={null}
import os
import time
from urllib.parse import quote, urlparse
import requests

BASE_URL = "https://api.mixroute.ai"

def create_video(session, payload):
    response = session.post(BASE_URL + "/v1/video/generations", json=payload, timeout=120)
    response.raise_for_status()
    result = response.json()
    task_id = result.get("task_id") or result.get("id")
    if not task_id:
        raise RuntimeError(result.get("message") or result)
    return task_id

def wait_for_video(session, task_id, timeout_seconds=1200):
    url = BASE_URL + "/v1/video/generations/" + quote(task_id, safe="")
    deadline = time.monotonic() + timeout_seconds
    delay = 15
    while time.monotonic() < deadline:
        remaining = deadline - time.monotonic()
        if remaining <= 0:
            break
        try:
            response = session.get(url, timeout=min(30, remaining))
        except (requests.Timeout, requests.ConnectionError):
            delay = min(delay * 2, 60)
        else:
            if response.status_code in (429, 500, 502, 503, 504):
                delay = min(delay * 2, 60)
            else:
                response.raise_for_status()
                result = response.json()
                if result.get("code") not in (None, 0, 200, "0", "200", "success"):
                    raise RuntimeError(result.get("message") or result)
                task = result.get("data") or {}
                status = str(task.get("status", "")).upper()
                if status == "SUCCESS":
                    video_url = task.get("result_url", "")
                    parsed = urlparse(video_url)
                    if parsed.scheme not in ("http", "https") or not parsed.netloc:
                        raise RuntimeError("Successful task has no valid video URL")
                    return task
                if status in {"FAILURE", "FAILED", "EXPIRED", "CANCELED", "CANCELLED"}:
                    raise RuntimeError(task.get("fail_reason") or task)
                if status not in {"QUEUED", "NOT_START", "PENDING", "IN_PROGRESS", "RUNNING"}:
                    raise RuntimeError("Unknown task status: " + status)
                delay = 15
        remaining = deadline - time.monotonic()
        if remaining <= 0:
            break
        time.sleep(min(delay, remaining))
    raise TimeoutError("Video task is still pending; keep its task ID and query it later")

if __name__ == "__main__":
    payload = {
        "model": "wan3.0-video",
        "metadata": {
            "input": {"prompt": "A red ceramic mug slowly rotates on a white tabletop."},
            "parameters": {"resolution": "480P", "ratio": "16:9", "duration": 2, "audio": False},
        },
    }
    with requests.Session() as session:
        session.headers["Authorization"] = "Bearer " + os.environ["MIXROUTE_API_KEY"]
        task_id = create_video(session, payload)
        print("task_id:", task_id, flush=True)
        task = wait_for_video(session, task_id)
        print(task["result_url"])
        print(task.get("data", {}).get("usage", {}))
```

Use the console bill for final charges. Submission can reserve quota before completion; request estimates and final settlement may differ. Do not treat input/negative/zero duration values as a way to obtain a zero-cost task.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.