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

# 影片生成 API

> 依照符合您工作類型的供應商流程，選擇 CometAPI 的影片路由，支援 Seedance、HappyHorse、Sora 2、Veo 3、Wan、xAI、Vidu、Omni、Kling 與 Runway 工作流程。

依照符合您任務類型的供應商工作流程，使用 CometAPI 影片模型文件。大多數影片端點都會建立非同步任務，因此請儲存任務 ID，並使用輪詢來擷取結果。只有在模型專屬頁面有記錄支援 callback 時，才加入 callback。

## 選擇影片 API

<CardGroup cols={2}>
  <Card title="建立 Seedance 影片" icon="sparkles" href="/api/video/seedance/create">
    建立 Seedance 影片任務。
  </Card>

  <Card title="建立 HappyHorse 影片" icon="sparkles" href="/api/video/happyhorse/create">
    建立 HappyHorse 文字轉影片任務。
  </Card>

  <Card title="建立 Sora 2 影片" icon="film" href="/api/video/sora-2/create">
    建立 Sora 2 影片任務。
  </Card>

  <Card title="擷取 Sora 2 影片" icon="refresh" href="/api/video/sora-2/retrieve">
    查詢 Sora 影片任務。
  </Card>

  <Card title="建立 Veo 3 影片" icon="film" href="/api/video/veo3/create">
    建立 Veo 影片任務。
  </Card>

  <Card title="建立 Wan 影片" icon="sparkles" href="/api/video/wan/create">
    建立 Wan 文字轉影片任務。
  </Card>

  <Card title="建立 xAI 影片" icon="film" href="/api/video/xai/video-generation">
    產生 xAI 影片任務。
  </Card>

  <Card title="建立 Vidu 影片" icon="sparkles" href="/api/video/vidu/create">
    建立 Vidu 文字轉影片任務。
  </Card>

  <Card title="建立 Omni 影片（Beta）" icon="sparkles" href="/api/video/omni/create">
    建立測試版 Omni 影片任務。
  </Card>

  <Card title="建立 Kling 文字轉影片任務" icon="film" href="/api/video/kling/text-to-video">
    從文字 Prompt 產生 Kling 影片。
  </Card>

  <Card title="建立 Runway 圖片轉影片任務" icon="film" href="/api/video/runway/official-format/runway-images-raw-video">
    從圖片產生 Runway 影片。
  </Card>
</CardGroup>

## 建立並輪詢影片任務

使用來自[Models 頁面](/zh-Hant/overview/models)或[模型目錄](https://www.cometapi.com/models/)的支援影片 model ID。以下範例會先透過 `POST /v1/videos` 建立影片任務，然後輪詢回傳的 task ID，直到任務進入終止狀態。

<Note>
  這些範例使用佔位符 `your-video-model-id`。在執行請求之前，請將其替換為來自 [Models 頁面](/zh-Hant/overview/models)或[模型目錄](https://www.cometapi.com/models/)的可用影片 model ID。
</Note>

<Tip>
  開啟 [建立 Seedance 影片](/api/video/seedance/create) 和 [取得 Seedance 影片](/api/video/seedance/query)，即可使用 API playground 與端點 schema。
</Tip>

<CodeGroup>
  ```python Python theme={null}
  import os
  import time
  import requests

  headers = {"Authorization": "Bearer " + os.environ["COMETAPI_KEY"]}

  create_response = requests.post(
      "https://api.cometapi.com/v1/videos",
      headers=headers,
      data={
          "model": "your-video-model-id",
          "prompt": "A calm camera move across a desk with a paper airplane",
      },
      timeout=30,
  )
  create_response.raise_for_status()
  task = create_response.json()
  task_id = task["id"]

  terminal_statuses = {"completed", "failed", "error"}

  while True:
      poll_response = requests.get(
          f"https://api.cometapi.com/v1/videos/{task_id}",
          headers=headers,
          timeout=30,
      )
      poll_response.raise_for_status()
      result = poll_response.json()
      print(result["status"], result.get("progress"))

      if result["status"] in terminal_statuses:
          print(result.get("video_url"))
          break

      time.sleep(10)
  ```

  ```javascript Node.js theme={null}
  const form = new FormData();
  form.append("model", "your-video-model-id");
  form.append("prompt", "A calm camera move across a desk with a paper airplane");

  const createResponse = await fetch("https://api.cometapi.com/v1/videos", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.COMETAPI_KEY}`,
    },
    body: form,
  });

  if (!createResponse.ok) {
    throw new Error(await createResponse.text());
  }

  const task = await createResponse.json();
  const terminalStatuses = new Set(["completed", "failed", "error"]);

  while (true) {
    const pollResponse = await fetch(
      `https://api.cometapi.com/v1/videos/${task.id}`,
      {
        headers: {
          Authorization: `Bearer ${process.env.COMETAPI_KEY}`,
        },
      },
    );

    if (!pollResponse.ok) {
      throw new Error(await pollResponse.text());
    }

    const result = await pollResponse.json();
    console.log(result.status, result.progress);

    if (terminalStatuses.has(result.status)) {
      console.log(result.video_url);
      break;
    }

    await new Promise((resolve) => setTimeout(resolve, 10_000));
  }
  ```

  ```bash cURL theme={null}
  curl https://api.cometapi.com/v1/videos \
    -H "Authorization: Bearer $COMETAPI_KEY" \
    -F "model=your-video-model-id" \
    -F "prompt=A calm camera move across a desk with a paper airplane"

  curl https://api.cometapi.com/v1/videos/task_example \
    -H "Authorization: Bearer $COMETAPI_KEY"
  ```
</CodeGroup>

## 回應範例

成功的建立回應可能如下所示。在開始輪詢之前，請先儲存 task ID：

```json theme={null}
{
  "id": "task_example",
  "task_id": "task_example",
  "object": "video",
  "model": "your-video-model-id",
  "status": "queued",
  "progress": 0,
  "created_at": 1779872000
}
```

成功的輪詢回應可能如下所示。已完成的回應可以包含 `video_url`；某些供應商格式會使用 model 專屬的結果欄位，或在該路由有文件說明時使用影片內容路由：

```json theme={null}
{
  "id": "task_example",
  "object": "video",
  "model": "your-video-model-id",
  "status": "completed",
  "progress": 100,
  "completed_at": 1779872300,
  "video_url": "https://example.com/generated-video.mp4"
}
```

## 範例 model 記錄

<Info>
  此範例模型目錄回應展示了 `/api/models` 的封裝格式，以及一筆影片模型記錄的結構。這不是完整的模型清單。
</Info>

```bash cURL theme={null}
curl https://api.cometapi.com/api/models
```

```json theme={null}
{
  "success": true,
  "page": 1,
  "page_size": 20,
  "total": 302,
  "data": [
    {
      "created": 1767529753,
      "id": "your-video-model-id",
      "code": "your-video-model-id",
      "provider": "ExampleProvider",
      "provider_code": "example",
      "name": "Example video model",
      "model_type": "video",
      "features": [
        "text-to-video"
      ],
      "endpoints": "{\n  \"seedance\": {\n    \"path\": \"/v1/videos\",\n    \"method\": \"POST\"\n  }\n}",
      "pricing": {
        "currency": "USD / M Tokens",
        "input": null,
        "output": null,
        "per_request": null,
        "per_second": 0.024
      }
    }
  ]
}
```

## 常見錯誤

<AccordionGroup>
  <Accordion title="Missing task ID">
    在你的作業處理常式返回之前，先儲存建立回應中的 ID。
  </Accordion>

  <Accordion title="Polling too fast">
    在狀態檢查之間加入延遲與退避機制。
  </Accordion>

  <Accordion title="Unsupported duration or size">
    請使用所選影片端點文件中記載的 duration 與 resolution 欄位。
  </Accordion>

  <Accordion title="Missing video_url">
    將 `video_url` 視為可選欄位，並在可用時回退至模型特定的結果欄位或 content 路由。
  </Accordion>

  <Accordion title="Callback not received">
    以輪詢作為事實來源，並確認你的 callback URL 可接受 POST 請求。
  </Accordion>
</AccordionGroup>

## 錯誤碼與重試策略

<AccordionGroup>
  <Accordion title="400">
    在修正 prompt、檔案、duration 或 size 欄位之前，請勿重試。
  </Accordion>

  <Accordion title="401">
    在 API key 存在且有效之前，請勿重試。
  </Accordion>

  <Accordion title="404">
    重試前請檢查 task ID、base URL、path 和 model ID。
  </Accordion>

  <Accordion title="413">
    重試前請先縮減上傳大小。
  </Accordion>

  <Accordion title="429">
    使用指數退避重試，並降低建立請求或輪詢的並行數。
  </Accordion>

  <Accordion title="500 or 503">
    以退避機制重試任務建立；除非任務進入最終錯誤狀態，否則請持續輪詢既有任務。
  </Accordion>
</AccordionGroup>

<Tip>
  如需實作模式，請參閱 [錯誤碼與重試策略](/zh-Hant/guides/error-codes-and-retry-strategy)、[速率限制與並行處理](/zh-Hant/guides/rate-limits-and-concurrency)，以及 [影片生成的 Webhook 與輪詢](/zh-Hant/guides/webhook-and-polling-for-video-generation)。
</Tip>

## 定價與模型目錄

<CardGroup cols={3}>
  <Card title="Models page" icon="list" href="/overview/models">
    了解 CometAPI 如何在文件中公開 model ID。
  </Card>

  <Card title="Model directory" icon="puzzle-piece" href="https://www.cometapi.com/models/">
    瀏覽可用模型及其功能。
  </Card>

  <Card title="Pricing" icon="tag" href="https://www.cometapi.com/pricing/">
    在呼叫模型之前先查看定價。
  </Card>
</CardGroup>
