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

# 通義萬相

> 萬相 3.0、2.7、2.6 影片生成、參考輸入、編輯參數與非同步任務處理。

萬相使用統一的 MixRoute 影片端點。model 保留在頂層，廠商的 input 與 parameters 物件完整放入 metadata。不同版本使用不同輸入協議，請按完整模型 ID 選擇下方參數。

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

## 支援模型

| 模型 ID                                                           | 模式       | 解析度                 | 時長（秒）                |
| --------------------------------------------------------------- | -------- | ------------------- | -------------------- |
| [wan3.0-video](/zh-hant/model-api/alibaba/wan3.0-video)         | 全能參考影片生成 | 480P / 720P / 1080P | 2-30 / -1            |
| [wan2.7-t2v](/zh-hant/model-api/alibaba/wan2.7-t2v)             | 文生影片     | 720P / 1080P        | 2-15                 |
| [wan2.7-i2v](/zh-hant/model-api/alibaba/wan2.7-i2v)             | 圖生影片     | 720P / 1080P        | 2-15                 |
| [wan2.7-r2v](/zh-hant/model-api/alibaba/wan2.7-r2v)             | 參考生影片    | 720P / 1080P        | 2-15（無影片）/ 2-10（有影片） |
| [wan2.7-videoedit](/zh-hant/model-api/alibaba/wan2.7-videoedit) | 影片編輯     | 720P / 1080P        | 2-10                 |
| [wan2.6-t2v](/zh-hant/model-api/alibaba/wan2.6-t2v)             | 文生影片     | 720P / 1080P        | 2-15                 |
| [wan2.6-i2v](/zh-hant/model-api/alibaba/wan2.6-i2v)             | 圖生影片     | 720P / 1080P        | 2-15                 |
| [wan2.6-r2v](/zh-hant/model-api/alibaba/wan2.6-r2v)             | 參考生影片    | 720P / 1080P        | 2-10                 |

模型可用性以賬戶的 [模型列表](/zh-hant/api-reference/endpoint/list-models) 為準，不將未返回的廠商型號或日期快照視為已開通。

## 請求包裝

| 欄位                    | 型別     | 必填 | 說明                            |
| --------------------- | ------ | -- | ----------------------------- |
| `model`               | string | 是  | 完整 MixRoute 模型 ID。            |
| `metadata`            | object | 是  | 除 model 之外的廠商請求體容器。           |
| `metadata.input`      | object | 是  | 原生 input 物件，提示詞和媒體的必填規則取決於型號。 |
| `metadata.parameters` | object | 否  | 原生生成設定，保留欄位名稱與層級。             |

<Info>
  使用 MixRoute Key 與 Authorization: Bearer 認證，無需阿里 Key、業務空間 ID、地域端點或 X-DashScope-Async 請求頭。不要將 input/parameters 放到頂層，也不要將其內容平鋪到 metadata 下。
</Info>

提示詞使用 metadata.input.prompt。相容寫法的優先順序依次為 metadata.input.prompt、metadata.prompt、頂層 prompt，前者存在時優先。提示詞與有效媒體至少提供其一，並繼續滿足所選模型自身的必填規則。

原生欄位保持名稱透傳；上游新增欄位可放在原有 input/parameters 位置，由上游校驗型號與場景約束。這不代表每個欄位都適用於所有型號。

## Wan 3.0

| 欄位                                  | 型別        | 必填  | 說明                                                                                            |
| ----------------------------------- | --------- | --- | --------------------------------------------------------------------------------------------- |
| `metadata.input.prompt`             | string    | 按模式 | 文本提示詞，最多 20000 字元，超出部分截斷；與 media 至少提供其一。                                                      |
| `metadata.input.media`              | object\[] | 按模式 | 媒體項陣列，與 prompt 至少提供其一；組合規則見下方。                                                                |
| `metadata.input.media[].type`       | string    | 按模式 | 每項必填：first\_frame、last\_frame、reference\_image、reference\_video、reference\_audio、file 或 link。 |
| `metadata.input.media[].url`        | string    | 按模式 | 每項必填。公網 HTTP/HTTPS URL；影像另支援 Base64 data URI。原生 OSS 資源須可被路由賬戶訪問。                              |
| `metadata.parameters.resolution`    | string    | 否   | 480P、720P 或 1080P；省略時 MixRoute 顯式填入 1080P。                                                    |
| `metadata.parameters.ratio`         | string    | 否   | adaptive（預設）、16:9、4:3、1:1、3:4 或 9:16；延長影片使用 adaptive。                                         |
| `metadata.parameters.duration`      | integer   | 否   | 預設 5 秒。無影片輸入時為 2-30 秒；有影片輸入時，輸入影片總時長與輸出時長之和不超過 30 秒。-1 為智慧時長。                                 |
| `metadata.parameters.audio`         | boolean   | 否   | 預設 true；false 輸出無音軌影片。                                                                        |
| `metadata.parameters.seed`          | integer   | 否   | -1 或 0-2147483647；-1 或省略時隨機，不保證輸出完全一致。                                                        |
| `metadata.parameters.prompt_extend` | boolean   | 否   | 提示詞智慧改寫，預設 true。                                                                              |
| `metadata.parameters.watermark`     | boolean   | 否   | 新增 AI 水印，預設 false。                                                                            |

### 媒體型別

| type                         | 數量或用途                           |
| ---------------------------- | ------------------------------- |
| `first_frame` / `last_frame` | 各最多一張，使用首幀或首幀+尾幀，不單獨傳尾幀。        |
| `reference_image`            | 最多 10 張參考圖。                     |
| `reference_video`            | 最多五個影片，每段 1-15 秒，總時長不超過 15 秒。   |
| `reference_audio`            | 最多五個音訊，每段 1-15 秒，總時長不超過 15 秒。   |
| `file`                       | 一個公開文件，不超過 100 MB；分頁格式不超過 50 頁。 |
| `link`                       | 一個無需登入即可訪問的公開網頁。                |

* 首幀/首尾幀組與 reference\_\*、file、link 互斥。與萬相 2.7 I2V 不同，3.0 首尾幀模式不能搭配驅動音訊。
* 參考圖片、影片和音訊可相互組合；file 與 link 二選一，但可與 reference\_\* 組合，仍須滿足各型別數量上限和總計 20 個媒體素材的上限。
* 素材按型別分別計數，在提示詞中用圖1、影片1、音訊1，或 Image 1、Video 1、Audio 1 指代。
* 編輯/延長鬚傳 reference\_video 並在提示詞中說明意圖。延長使用 ratio=adaptive；編輯可用 adaptive 與 duration=-1 保留源構圖並自動選擇時長。輸入影片總時長與輸出時長之和仍須不超過 30 秒。

<Note>
  萬相 3.0 不使用 size、negative\_prompt、template、img\_url、first\_frame\_url、last\_frame\_url、audio\_url。閘道器會清理舊欄位，並可將 audio\_url 轉為 reference\_audio 媒體項；新請求直接使用 input.media。
</Note>

## Wan 2.7

| 欄位                                       | 型別        | 必填  | 說明                                                                                                                  |
| ---------------------------------------- | --------- | --- | ------------------------------------------------------------------------------------------------------------------- |
| `metadata.input.prompt`                  | string    | 按模式 | 最多 5000 字元，超出部分截斷。T2V/R2V 必填；I2V/VideoEdit 提供必需媒體時可省略。                                                              |
| `metadata.input.negative_prompt`         | string    | 否   | 描述不希望出現的內容，最多 500 字元，超出部分截斷。                                                                                        |
| `metadata.input.audio_url`               | string    | 否   | 僅 T2V：驅動音訊 URL，WAV/MP3、2-30 秒、不超過 15 MB；長音訊截斷，短於影片時尾部無聲。                                                            |
| `metadata.input.media`                   | object\[] | 按模式 | I2V、R2V、VideoEdit 必填；各模式使用不同的媒體型別與組合。                                                                               |
| `metadata.input.media[].type`            | string    | 按模式 | 每個媒體項必填，取值須匹配下方的型號規則。                                                                                               |
| `metadata.input.media[].url`             | string    | 按模式 | 每個媒體項必填。公網 HTTP/HTTPS URL；影像另支援 data:image/...;base64,...。原生 OSS 引用須可被路由訪問。                                         |
| `metadata.input.media[].reference_voice` | string    | 否   | 僅 R2V 的 reference\_image/reference\_video：音色參考 URL，WAV/MP3、1-10 秒、不超過 15 MB，優先於參考影片原聲。                              |
| `metadata.parameters.resolution`         | string    | 否   | 720P 或 1080P（預設），注意大小寫。                                                                                             |
| `metadata.parameters.ratio`              | string    | 否   | T2V/R2V/VideoEdit：16:9、9:16、1:1、4:3 或 3:4。T2V/R2V 預設 16:9；R2V 有首幀時忽略 ratio。VideoEdit 省略時跟隨源影片。I2V 跟隨輸入影像/影片，不使用此欄位。 |
| `metadata.parameters.duration`           | integer   | 否   | T2V/I2V 為 2-15 秒，預設 5。R2V 無影片參考時為 2-15 秒，有影片時為 2-10 秒，預設 5。VideoEdit 省略時保留源時長，設定 2-10 時從開頭截斷。                       |
| `metadata.parameters.audio_setting`      | string    | 否   | 僅 VideoEdit：auto（預設）按提示詞決定音訊處理；origin 保留源音訊。                                                                        |
| `metadata.parameters.prompt_extend`      | boolean   | 否   | 提示詞智慧改寫，預設 true。                                                                                                    |
| `metadata.parameters.watermark`          | boolean   | 否   | 新增 AI 水印，預設 false。                                                                                                  |
| `metadata.parameters.seed`               | integer   | 否   | 範圍 0-2147483647，省略則隨機；相同種子不保證完全相同的輸出。                                                                               |

### 輸入模式

| 模型                 | 媒體規則                                                                                                                                                           |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `wan2.7-t2v`       | prompt 與可選 input.audio\_url，不使用 media 陣列。                                                                                                                      |
| `wan2.7-i2v`       | 僅使用：first\_frame；first\_frame+driving\_audio；first\_frame+last\_frame；first\_frame+last\_frame+driving\_audio；first\_clip；first\_clip+last\_frame。各 type 最多一次。 |
| `wan2.7-r2v`       | reference\_image/reference\_video 合計 1-5 個，可另配一張 first\_frame。reference\_voice 位於每個參考項內，不是獨立媒體型別。                                                              |
| `wan2.7-videoedit` | 有且只有一個 type=video 的源影片，可另配最多四張 reference\_image。                                                                                                               |

I2V 使用 first\_clip 續寫時，duration 控制包含源片段的最終總時長，不只是新增秒數。R2V 使用圖1/影片1或 Image 1 / Video 1，圖片與影片分別計數。2.7 不再沿用 2.6 T2V/R2V 的 size 或 shot\_type；I2V 輸出比例跟隨源素材，不傳 ratio。

## Wan 2.6

| 欄位                                    | 型別        | 必填  | 說明                                                                              |
| ------------------------------------- | --------- | --- | ------------------------------------------------------------------------------- |
| `metadata.input.prompt`               | string    | 按模式 | 最多 1500 字元，超出部分截斷。T2V/R2V 必填；I2V 有輸入影像時可省略。R2V 用 character1、character2 等引用素材。   |
| `metadata.input.negative_prompt`      | string    | 否   | 反向提示詞，最多 500 字元，超出部分截斷。                                                         |
| `metadata.input.img_url`              | string    | 按模式 | 僅 I2V，必填：首幀圖片 URL 或影像 Base64 data URI。                                          |
| `metadata.input.audio_url`            | string    | 否   | 僅 T2V/I2V：驅動音訊 URL，WAV/MP3、2-30 秒、不超過 15 MB。                                    |
| `metadata.input.reference_urls`       | string\[] | 按模式 | 僅 R2V，必填：1-5 個素材 URL，影像最多五張、影片最多三個，合計不超過五個，每個素材包含一個主體。                          |
| `metadata.input.reference_video_urls` | string\[] | 否   | 已棄用的 R2V 純影片輸入，最多三個影片；優先使用 reference\_urls，不混用兩種格式。                             |
| `metadata.parameters.size`            | string    | 否   | 僅 T2V/R2V：使用下方尺寸表中的 `寬*高`，預設 `1920*1080`。                                       |
| `metadata.parameters.resolution`      | string    | 否   | 僅 I2V：720P 或 1080P（預設），寬高比跟隨首幀影像。                                               |
| `metadata.parameters.duration`        | integer   | 否   | T2V/I2V 為 2-15 秒，R2V 為 2-10 秒，預設 5。                                             |
| `metadata.parameters.prompt_extend`   | boolean   | 否   | 僅 T2V/I2V：提示詞智慧改寫，預設 true；不是 R2V 參數。                                            |
| `metadata.parameters.shot_type`       | string    | 否   | single（預設）或 multi。T2V/I2V 須同時開啟 prompt\_extend 才生效；R2V 直接使用此欄位。優先順序高於提示詞中的鏡頭描述。 |
| `metadata.parameters.watermark`       | boolean   | 否   | 新增 AI 水印，預設 false。                                                              |
| `metadata.parameters.seed`            | integer   | 否   | 範圍 0-2147483647，省略則隨機；相同種子不保證完全相同的輸出。                                           |

### T2V / R2V 尺寸

| 檔位    | size 取值                                                         |
| ----- | --------------------------------------------------------------- |
| 720P  | `1280*720`, `720*1280`, `960*960`, `1088*832`, `832*1088`       |
| 1080P | `1920*1080`, `1080*1920`, `1440*1440`, `1632*1248`, `1248*1632` |

2.6 R2V 按 reference\_urls 順序用 character1、character2 等引用主體，不使用 2.7 的圖/影片分別編號。參考素材使用公網 HTTP/HTTPS 或可訪問的 OSS URL。此處列出的 2.6 標準型號不套用其他 Flash 型號的 audio=false 開關；舊版特效模板也不是這八個型號的通用能力。

## 媒體限制

| 輸入         | 限制                                                                                                                           |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------- |
| 影像         | JPEG/JPG、無透明通道 PNG、BMP、WebP；寬高各 240-8000 px，不超過 20 MB。3.0/2.7 另要求長短邊比不超過 8:1。                                                |
| 3.0 參考影片   | MP4/MOV，每段 1-15 秒、合計不超過 15 秒；至少 16 fps；寬高各 240-4096 px；長短邊比不超過 8:1；單個不超過 100 MB。                                             |
| 2.7 影片     | MP4/MOV；寬高各 240-4096 px，長短邊比不超過 8:1，不超過 100 MB。first\_clip/VideoEdit 源影片為 2-10 秒，R2V 參考影片為 1-30 秒。                           |
| 2.6 R2V 影片 | reference\_urls 支援 MP4/MOV、1-30 秒、不超過 100 MB；已棄用 reference\_video\_urls 格式的時長為 2-30 秒。                                       |
| 音訊         | WAV/MP3，單個不超過 15 MB。3.0 參考音訊每段 1-15 秒、合計不超過 15；2.7 reference\_voice 為 1-10 秒；T2V 驅動音訊與 I2V driving\_audio 為 2-30 秒。          |
| 3.0 檔案     | docx, doc, xlsx, xls, pptx, ppt, pdf, txt, key, pages, numbers, md; 不超過 100 MB；PDF/Word/PowerPoint/Keynote/Pages 文件不超過 50 頁。 |

優先使用公網 URL。OSS 臨時資源和廠商資產 ID 與上游賬戶、地域有關，須可被當前渠道訪問。讀取第三方 CDN 結果地址時，不要附帶 MixRoute Key。

## 請求示例

設定 MIXROUTE\_API\_KEY，並將 example.com 媒體地址替換為可訪問的源素材。每次 POST 會建立獨立任務，提交超時後不要自動重複提交。

### 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
    }
  }
}'
```

### 首尾幀

```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
    }
  }
}'
```

### 檔案輸入，不傳提示詞

```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
    }
  }
}'
```

## 響應與輪詢

提交返回 MixRoute task\_id（以及 id 別名），不是上游任務 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}`

| 閘道器狀態                  | 上游狀態                              | 處理                             |
| ---------------------- | --------------------------------- | ------------------------------ |
| `NOT_START` / `QUEUED` | `PENDING`                         | 等待並繼續查詢。                       |
| `IN_PROGRESS`          | `RUNNING`                         | 繼續輪詢。                          |
| `SUCCESS`              | `SUCCEEDED`                       | 讀取 data.result\_url。           |
| `FAILURE`              | `FAILED` / `CANCELED` / `UNKNOWN` | 停止，檢查 data.fail\_reason 與上游響應。 |

```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>
  只在 SUCCESS 後讀取 result\_url。失敗時該欄位可能填入失敗原因，不一定是 URL。外層 code="success" 僅代表查詢成功，不代表影片生成成功。
</Warning>

上游完整響應保留在 data.data，可讀取其中的 usage 與 request\_id。UNKNOWN 表示上游任務不存在或已過期，不應一概當作生成失敗。建議每 15 秒查詢一次，限流或臨時錯誤時退避。上游任務查詢和結果連結保留期有限，通常為 24 小時，應及時儲存產物。

## Python 完整流程

```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", {}))
```

最終費用以控制台賬單為準。提交可能預扣額度，預扣與任務完成後的結算可能不同；不要將輸入時長、負數或零時長理解為零費用任務。
