> ## 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.

# 查詢影片任務

> 查詢影片生成任務的狀態和結果

## 簡介

查詢影片任務端點用於透過任務 ID 檢查影片生成任務的狀態和結果。提交任務後，您需要定期輪詢此端點來檢查任務狀態，直到任務完成或失敗。

<Tip>
  建議每 3-5 秒輪詢一次任務狀態，直到狀態變為 `succeeded` 或 `failed`。
</Tip>

## 認證方式

Bearer Token，例如 `Bearer sk-xxxxxxxxxx`

## 路徑參數

<ParamField path="task_id" type="string" required>
  影片生成任務 ID，由提交任務端點返回
</ParamField>

## 任務狀態

| 狀態            | 說明         | 建議操作          |
| ------------- | ---------- | ------------- |
| `queued`      | 任務已排隊，等待處理 | 繼續輪詢          |
| `in_progress` | 任務正在處理中    | 繼續輪詢          |
| `succeeded`   | 任務成功完成     | 下載影片或取得影片 URL |
| `failed`      | 任務失敗       | 檢查錯誤詳情        |

## cURL 範例

```bash theme={null}
curl -X GET "https://api.mixroute.ai/v1/video/generations/video_69095b4ce0048190893a01510c0c98b0" \
  -H "Authorization: Bearer sk-xxxxxxxxxx"
```

## 輪詢範例

### Python 範例

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

def poll_task_status(task_id, api_key, max_wait_time=300):
    """輪詢任務狀態直到完成"""
    url = f"https://api.mixroute.ai/v1/video/generations/{task_id}"
    headers = {"Authorization": f"Bearer {api_key}"}
    
    start_time = time.time()
    while True:
        response = requests.get(url, headers=headers)
        data = response.json()
        status = data.get("status")
        
        print(f"目前狀態：{status}")
        
        if status == "succeeded":
            video_url = data.get("url")
            print(f"✅ 任務完成！影片 URL：{video_url}")
            return video_url
        elif status == "failed":
            error_msg = data.get("error", {}).get("message", "未知錯誤")
            print(f"❌ 任務失敗：{error_msg}")
            return None
        
        # 檢查逾時
        if time.time() - start_time > max_wait_time:
            print("⏰ 等待逾時")
            return None
        
        # 等待 5 秒後再次查詢
        time.sleep(5)
```

### JavaScript 範例

```javascript theme={null}
async function pollTaskStatus(taskId, apiKey, maxWaitTime = 300000) {
  const url = `https://api.mixroute.ai/v1/video/generations/${taskId}`;
  const headers = { 'Authorization': `Bearer ${apiKey}` };
  
  const startTime = Date.now();
  
  while (true) {
    const response = await fetch(url, { headers });
    const data = await response.json();
    const status = data.status;
    
    console.log(`目前狀態：${status}`);
    
    if (status === 'succeeded') {
      const videoUrl = data.url;
      console.log(`✅ 任務完成！影片 URL：${videoUrl}`);
      return videoUrl;
    } else if (status === 'failed') {
      const errorMsg = data.error?.message || '未知錯誤';
      console.error(`❌ 任務失敗：${errorMsg}`);
      throw new Error(errorMsg);
    }
    
    // 檢查逾時
    if (Date.now() - startTime > maxWaitTime) {
      throw new Error('等待逾時');
    }
    
    // 等待 5 秒後再次查詢
    await new Promise(resolve => setTimeout(resolve, 5000));
  }
}
```

## 回應範例

### 任務排隊中

```json theme={null}
{
  "task_id": "video_69095b4ce0048190893a01510c0c98b0",
  "status": "queued",
  "format": "mp4"
}
```

### 任務處理中

```json theme={null}
{
  "task_id": "video_69095b4ce0048190893a01510c0c98b0",
  "status": "in_progress",
  "format": "mp4"
}
```

### 任務完成（Veo/Dreamina Seedance）

```json theme={null}
{
  "task_id": "video_69095b4ce0048190893a01510c0c98b0",
  "status": "succeeded",
  "format": "mp4",
  "url": "https://nebula-ads.oss-cn-guangzhou.aliyuncs.com/2025/11/18/abc123/video.mp4"
}
```

<Note>
  Veo在任務成功後，影片 URL 會直接包含在回應中。
</Note>

### 任務完成（Sora 2）

```json theme={null}
{
  "task_id": "video_69095b4ce0048190893a01510c0c98b0",
  "status": "succeeded",
  "format": "mp4"
}
```

<Warning>
  Sora 2 模型不會直接返回影片 URL。您需要呼叫下載影片端點來取得影片資料。
</Warning>

### 任務失敗

```json theme={null}
{
  "task_id": "video_69095b4ce0048190893a01510c0c98b0",
  "status": "failed",
  "format": "mp4",
  "error": {
    "code": 400,
    "message": "提示詞包含不當內容"
  }
}
```

## 回應欄位說明

| 欄位        | 類型     | 說明                     |
| --------- | ------ | ---------------------- |
| `task_id` | string | 任務 ID                  |
| `status`  | string | 任務狀態                   |
| `format`  | string | 影片格式                   |
| `url`     | string | 影片下載 URL（Sora 2 以外的模型） |
| `error`   | object | 錯誤資訊（失敗時返回）            |

## 模型差異

| 模型                | 返回 URL | 備註         |
| ----------------- | ------ | ---------- |
| Sora 2            | ❌      | 需使用下載端點    |
| Veo               | ✅      | 直接返回影片 URL |
| Dreamina Seedance | ✅      | 直接返回影片 URL |

## 注意事項

* 不同模型的回應欄位可能略有差異
* 實作指數退避策略以避免過多請求
* 影片生成通常需要 30 秒到數分鐘，請耐心等待

<RequestExample>
  ```bash cURL theme={null}
  curl --request GET \
    --url https://api.mixroute.ai/v1/video/generations/video_xxx \
    --header 'Authorization: Bearer sk-xxxxxxxxxx'
  ```

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

  url = "https://api.mixroute.ai/v1/video/generations/video_xxx"
  headers = {"Authorization": "Bearer sk-xxxxxxxxxx"}

  response = requests.get(url, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.mixroute.ai/v1/video/generations/video_xxx', {
    headers: {
      'Authorization': 'Bearer sk-xxxxxxxxxx'
    }
  });
  const data = await response.json();
  console.log(data);
  ```

  ```php PHP theme={null}
  <?php
  $client = new GuzzleHttp\Client();
  $response = $client->get('https://api.mixroute.ai/v1/video/generations/video_xxx', [
      'headers' => [
          'Authorization' => 'Bearer sk-xxxxxxxxxx'
      ]
  ]);
  echo $response->getBody();
  ```

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

  import (
      "net/http"
  )

  func main() {
      req, _ := http.NewRequest("GET", "https://api.mixroute.ai/v1/video/generations/video_xxx", nil)
      req.Header.Set("Authorization", "Bearer sk-xxxxxxxxxx")
      http.DefaultClient.Do(req)
  }
  ```

  ```java Java theme={null}
  import java.net.http.*;
  import java.net.URI;

  HttpClient client = HttpClient.newHttpClient();
  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.mixroute.ai/v1/video/generations/video_xxx"))
      .header("Authorization", "Bearer sk-xxxxxxxxxx")
      .GET()
      .build();
  HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
  System.out.println(response.body());
  ```

  ```ruby Ruby theme={null}
  require 'net/http'
  require 'json'

  uri = URI('https://api.mixroute.ai/v1/video/generations/video_xxx')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Get.new(uri)
  request['Authorization'] = 'Bearer sk-xxxxxxxxxx'

  response = http.request(request)
  puts response.body
  ```
</RequestExample>

<ResponseExample>
  ```json Response theme={null}
  {
    "task_id": "video_xxx",
    "status": "succeeded",
    "format": "mp4",
    "url": "https://example.com/video.mp4"
  }
  ```
</ResponseExample>
