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

# 動画生成

> AIHubMix ネイティブ動画プロトコルで非同期タスクを作成し、状態照会と動画ダウンロードを行います。

<Note>
  [モデル Schema API](/jp/api/async-tasks#model-schema)
</Note>

## クイックスタート

動画生成は常に非同期です。例では `wan2.6-t2v` と秒単位の整数 `duration` を使用します。

<CodeGroup>
  ```bash タスク作成 theme={null}
  curl -X POST https://aihubmix.com/ai/v1/videos \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "wan2.6-t2v",
      "prompt": "Ocean waves crashing on rocky cliffs at sunset",
      "duration": 5,
      "size": "1280x720"
    }'
  ```

  ```json 作成レスポンス theme={null}
  {
    "id": "task_01K0ABCDEF",
    "object": "video",
    "model": "wan2.6-t2v",
    "status": "in_progress",
    "output": [],
    "error": null,
    "created_at": 1784707200,
    "completed_at": null,
    "expires_at": null
  }
  ```

  ```bash タスク照会 theme={null}
  curl https://aihubmix.com/ai/v1/videos/{id} \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY"
  ```

  ```bash 結果ダウンロード theme={null}
  curl https://aihubmix.com/ai/v1/videos/{id}/content \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    --output result.mp4
  ```
</CodeGroup>

<h2 id="model-schema">
  非同期メディアモデルを見つけて Schema を取得する方法
</h2>

ディスカバリーは 2 段階です。まず、公開モデルカタログから非同期 API に対応する画像生成または動画生成モデルを取得します。次に、モデルの `model_id` を使って、そのエンドポイントのリクエスト Schema を取得します。

<h3 id="async-media-model-list">
  非同期 API 対応モデルの一覧を取得する
</h3>

モデルカタログは Playground と同じデータソースを使用します。画像生成モデルには `type=image_generation`、動画生成モデルには `type=video` を指定します。`schema_checked=true` を追加すると、リクエスト Schema が公開され、確認済みのモデルだけが返されます。

```bash theme={null}
# 画像生成モデル
curl "https://aihubmix.com/api/v1/models?type=image_generation&schema_checked=true&sort_by=order"

# 動画生成モデル
curl "https://aihubmix.com/api/v1/models?type=video&schema_checked=true&sort_by=order"
```

どちらも同じ API を使用します。現在、`type` フィルターは 1 つの値を受け付けるため、モデルタイプごとにリクエストしてください。

レスポンスの形は `{success, message, data}` です。非同期メディア連携に関連する `data` のフィールドは次のとおりです。

| フィールド                     | 説明                                                   |
| ------------------------- | ---------------------------------------------------- |
| `data[].model_id`         | 生成リクエストと後続の Schema リクエストで使用するモデル ID                  |
| `data[].model_name`       | モデルの表示名                                              |
| `data[].types`            | カンマ区切りのモデルタイプ。`image_generation` と `llm` の両方を含む場合がある |
| `data[].input_modalities` | カンマ区切りの入力モダリティ                                       |
| `data[].schema_checked`   | `true` の場合、リクエスト Schema が公開され確認済み                    |

```json theme={null}
{
  "success": true,
  "message": "",
  "data": [
    {
      "model_id": "qwen-image-2.0",
      "model_name": "Qwen Image 2.0",
      "types": "image_generation",
      "input_modalities": "text,image",
      "schema_checked": true
    }
  ]
}
```

<h3 id="single-model-schema">
  1 つのモデルのリクエスト Schema を取得する
</h3>

対応するフィールド、列挙値、数値範囲はモデルごとに異なります。画像または動画のリクエストを送信する前に、次の公開 API で対象モデルの利用可能なエンドポイントとリクエスト JSON Schema を取得してください。

```bash theme={null}
# 画像生成モデル
curl "https://aihubmix.com/call/schema/models/qwen-image-2.0/endpoints"

# 動画生成モデル
curl "https://aihubmix.com/call/schema/models/wan2.6-t2v/endpoints"
```

レスポンスの `modality` は `image` または `video` です。`endpoints` 配列の各項目が、利用可能な呼び出しプロトコルを示します。

| フィールド                        | 説明                                            |
| ---------------------------- | --------------------------------------------- |
| `default_endpoint`           | モデルのデフォルトエンドポイント識別子                           |
| `endpoints[].endpoint`       | エンドポイント識別子                                    |
| `endpoints[].method`         | `POST` などの HTTP メソッド                          |
| `endpoints[].path`           | 実際のリクエストパス                                    |
| `endpoints[].content_types`  | エンドポイントが受け付けるコンテンツタイプ                         |
| `endpoints[].lifecycle`      | 同期または非同期モード、ポーリングパス、ステータス値                    |
| `endpoints[].request.schema` | 必須フィールドと値の制約を含む、そのモデルとエンドポイントの完全な JSON Schema |

同じモデルで `/ai/v1` エンドポイントと OpenAI 互換の `/v1` エンドポイントが返される場合があります。OpenAI 互換エンドポイントは最新モデルにまだ対応していない可能性があるため、`/ai/v1` エンドポイントを優先してください。非同期タスク API では、`path` が `/ai/v1/images/generations` または `/ai/v1/videos` の項目を選び、その `request.schema` を使用してください。`endpoints` 配列内の位置には依存しないでください。

次のコマンドで、各非同期タスクエンドポイントのリクエスト Schema を直接抽出できます。

```bash theme={null}
# 画像生成
curl -s "https://aihubmix.com/call/schema/models/qwen-image-2.0/endpoints" \
  | jq '.endpoints[] | select(.path == "/ai/v1/images/generations") | .request.schema'

# 動画生成
curl -s "https://aihubmix.com/call/schema/models/wan2.6-t2v/endpoints" \
  | jq '.endpoints[] | select(.path == "/ai/v1/videos") | .request.schema'
```

モデルが存在しない、または公開可能なエンドポイントがない場合は `404 model_not_found` が返されます。エンドポイントデータを一時的に取得できない場合は `500 endpoints_unavailable` が返されます。

***

<h2 id="create-async-video">
  動画タスクを作成する方法
</h2>

動画リクエストは常に非同期であり、`Prefer: wait` を使用して同期待機に変更することはできません。標準プロトコルでは、整数の `duration` で秒数を指定します。

```bash theme={null}
curl -X POST https://aihubmix.com/ai/v1/videos \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wan2.6-t2v",
    "prompt": "Ocean waves crashing on rocky cliffs at sunset",
    "duration": 5,
    "size": "1280x720"
  }'
```

<h3 id="video-parameters">
  動画の標準フィールド
</h3>

| フィールド                   | 型            | 必須  | 説明                                                         |
| ----------------------- | ------------ | --- | ---------------------------------------------------------- |
| `model`                 | string       | はい  | モデル名                                                       |
| `prompt`                | string       | はい  | 動画の説明。空にはできない                                              |
| `duration`              | integer/null | いいえ | 動画の長さ（秒）。具体的な範囲はモデルによって異なる                                 |
| `aspect_ratio`          | string/null  | いいえ | アスペクト比。プロトコルのデフォルト値は `16:9`                                |
| `resolution`            | string/null  | いいえ | `480p`、`720p`、`1080p`、`1K`、`2K`、または `4K`                   |
| `size`                  | string/null  | いいえ | `{width}x{height}`。`resolution` と `aspect_ratio` の代わりに指定可能 |
| `seed`                  | integer/null | いいえ | 乱数シード                                                      |
| `input_references`      | array/null   | いいえ | 画像、動画、または音声の参照素材                                           |
| `frame_images`          | array/null   | いいえ | 最初または最後のフレーム画像                                             |
| `generate_audio`        | boolean/null | いいえ | 音声トラックを生成するかどうか                                            |
| `webhook_url`           | string       | いいえ | HTTPS コールバック URL。最大 512 文字                                 |
| `webhook_events_filter` | string\[]    | いいえ | `completed`、`failed`、`cancelled` の空でないサブセット                |
| `extra`                 | object/null  | いいえ | モデル固有の拡張パラメータ                                              |

`input_references` 項目の構造：

```json theme={null}
{
  "type": "image_url",
  "url": "https://example.com/reference.png"
}
```

`type` には `image_url`、`video_url`、`audio_url` のいずれかを指定できます。

`frame_images` 項目の構造：

```json theme={null}
{
  "frame_type": "first_frame",
  "image_url": {
    "url": "https://example.com/first-frame.png"
  }
}
```

`frame_type` には `first_frame` または `last_frame` を指定できます。

***

<h2 id="task-object">
  メディアタスクオブジェクト
</h2>

画像と動画の専用 API は、次の構造を返します。

```json theme={null}
{
  "id": "task_01K0ABCDEF",
  "object": "video",
  "model": "wan2.6-t2v",
  "status": "completed",
  "output": [
    {
      "index": 0,
      "type": "file",
      "b64_json": null,
      "content_url": "https://aihubmix.com/ai/v1/videos/task_01K0ABCDEF/content"
    }
  ],
  "error": null,
  "created_at": 1784707200,
  "completed_at": 1784707320,
  "expires_at": null
}
```

| フィールド          | 型            | 説明                                               |
| -------------- | ------------ | ------------------------------------------------ |
| `id`           | string       | プラットフォームのタスク ID                                  |
| `object`       | string       | `image` または `video`                              |
| `model`        | string       | モデル名                                             |
| `status`       | string       | 現在のタスクステータス                                      |
| `output`       | array        | 生成済みの結果。結果がまだない場合は空配列                            |
| `error`        | object/null  | 失敗情報。`code`、`message`、`upstream_detail` を含む場合がある |
| `created_at`   | integer      | 作成時刻（Unix 秒）                                     |
| `completed_at` | integer/null | 最終ステータスになった時刻（Unix 秒）                            |
| `expires_at`   | null         | メディア専用 API では現在 `null` を返す                       |

メディアの `output` 項目：

| フィールド         | 型           | 説明                  |
| ------------- | ----------- | ------------------- |
| `index`       | integer     | 結果の順番。`0` から始まる     |
| `type`        | string      | 現在は `file`          |
| `content_url` | string/null | 結果のダウンロード URL       |
| `b64_json`    | string/null | Base64 エンコードされた画像結果 |

<h3 id="task-status">
  ステータスの説明
</h3>

| ステータス         | 終了済みか | 説明                         |
| ------------- | ----- | -------------------------- |
| `pending`     | いいえ   | プラットフォームがタスクを受け付け、実行を待っている |
| `in_progress` | いいえ   | タスクを実行中                    |
| `completed`   | はい    | タスクが完了し、`output` を読み取り可能   |
| `failed`      | はい    | タスクが失敗。理由は `error` を参照     |
| `cancelled`   | はい    | タスクがキャンセルされた               |

クライアントは、ステータスが `completed`、`failed`、`cancelled` のいずれかになるまで、15 秒ごとに照会できます。15 秒はクライアント側の推奨ポーリング間隔であり、サーバープロトコルの制限ではありません。

***

<h2 id="query-tasks">
  メディアタスクを照会する方法
</h2>

<h3 id="query-task-detail">
  メディア詳細の照会
</h3>

```bash theme={null}
# 画像
curl https://aihubmix.com/ai/v1/images/{task_id} \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"

# 動画
curl https://aihubmix.com/ai/v1/videos/{task_id} \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

メディア詳細 API は更新後のタスクステータスを返す場合があるため、メディアのポーリングには該当する画像または動画の詳細 API を使用してください。

<h3 id="query-task-list">
  メディア一覧の照会
</h3>

作成レスポンスを失った場合は、該当するメディア一覧からタスク ID を取得できます。

```bash theme={null}
curl "https://aihubmix.com/ai/v1/videos?limit=20&order=desc" \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

| パラメータ   | 型       | デフォルト値 | 説明                                |
| ------- | ------- | ------ | --------------------------------- |
| `after` | string  | -      | ページングカーソル。前ページの `next_after` を使用  |
| `limit` | integer | `20`   | 1 ページあたりの件数。最大 `100`              |
| `order` | string  | `desc` | `asc` を渡すと昇順、それ以外の値は `desc` として処理 |

```json theme={null}
{
  "object": "list",
  "data": [
    {
      "id": "task_01K0ABCDEF",
      "object": "video",
      "model": "wan2.6-t2v",
      "status": "in_progress",
      "output": [],
      "error": null,
      "created_at": 1784707200,
      "completed_at": null,
      "expires_at": null
    }
  ],
  "has_more": true,
  "next_after": "task_01K0ABCDEF"
}
```

メディア一覧は照会時点のタスクスナップショットを返し、タスクステータスを能動的に更新することはありません。

***

<h2 id="unified-tasks">
  統一タスク API を使用する方法
</h2>

統一タスク API では、次の条件で絞り込めます。

```bash theme={null}
curl "https://aihubmix.com/ai/v1/tasks?object=video&status=in_progress&limit=20&order=desc" \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

| パラメータ    | 型       | デフォルト値 | 説明                                                           |
| -------- | ------- | ------ | ------------------------------------------------------------ |
| `object` | string  | -      | `llm`、`image`、または `video`                                    |
| `status` | string  | -      | `pending`、`in_progress`、`completed`、`failed`、または `cancelled` |
| `model`  | string  | -      | モデル名で完全一致検索                                                  |
| `after`  | string  | -      | ページングカーソル                                                    |
| `limit`  | integer | `20`   | `1` から `100` の範囲                                             |
| `order`  | string  | `desc` | `asc` または `desc`                                             |

統一タスクの詳細：

```bash theme={null}
curl https://aihubmix.com/ai/v1/tasks/{task_id} \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

メディアタスクの統一 `output` 項目：

```json theme={null}
{
  "index": 0,
  "result_id": "result_01K0XYZ",
  "type": "file",
  "content_type": "video/mp4",
  "content_url": "https://aihubmix.com/ai/v1/tasks/task_01K0ABCDEF/content"
}
```

単一成果物の場合は `/ai/v1/tasks/{id}/content` を直接リクエストします。複数成果物のタスクでは `/ai/v1/tasks/{id}/content/{result_id}` をリクエストする必要があり、結果 ID を指定しない場合は `400 result_id_required` が返されます。

<Note>
  統一タスクの一覧、詳細、コンテンツ API は、タスク作成時の Bearer Token
  ごとに分離されています。同じアカウントの別の API Key
  からは、このタスクを読み取れません。
</Note>

***

<h2 id="get-task-results">
  メディア結果をダウンロードする方法
</h2>

<h3 id="single-artifact">
  動画のダウンロード
</h3>

```bash theme={null}
curl https://aihubmix.com/ai/v1/videos/{task_id}/content \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  --output result.mp4
```

<Warning>
  結果には有効期限があり、ダウンロード回数が制限される場合があります。期限切れの場合は
  `410 artifact_expired`、ダウンロード回数の上限を超えた場合は `429
      too_many_downloads` が返されます。
</Warning>

***

<h2 id="webhooks">
  Webhook を使用する方法
</h2>

非同期画像と動画は、タスク単位の Webhook に対応しています。

```bash theme={null}
curl -X POST https://aihubmix.com/ai/v1/videos \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wan2.6-t2v",
    "prompt": "A tranquil garden at sunrise",
    "duration": 5,
    "size": "1280x720",
    "webhook_url": "https://example.com/webhooks/aihubmix",
    "webhook_events_filter": ["completed", "failed"]
  }'
```

`webhook_url` は最大 512 文字で、ローカルホスト、プライベートネットワーク、その他の制限対象アドレスを指定することはできません。`webhook_events_filter` を省略すると、プラットフォームは `completed`、`failed`、`cancelled` を配信します。明示的に渡す場合、配列は空にできず、重複も許可されません。また、`webhook_url` と一緒に使用する必要があります。

リクエストで `webhook_url` を渡さなかった場合、非同期画像と動画ではアカウントに設定されたデフォルトのコールバック URL が使用されます。アカウントのデフォルト URL が無効な場合は無視され、タスクの作成は妨げられません。

<h3 id="webhook-payload">
  コールバックリクエスト
</h3>

```json theme={null}
{
  "event_id": "evt_01K0ABCDEF",
  "event_type": "completed",
  "created_at": "2026-08-12T12:00:00Z",
  "data": {
    "task_id": "task_01K0ABCDEF",
    "status": "completed",
    "model": "wan2.6-t2v",
    "results": [
      {
        "url": "https://aihubmix.com/ai/v1/tasks/task_01K0ABCDEF/content"
      }
    ]
  }
}
```

| フィールド                | 説明                                   |
| -------------------- | ------------------------------------ |
| `event_id`           | コールバックイベント ID。重複排除に使用                |
| `event_type`         | `completed`、`failed`、または `cancelled` |
| `created_at`         | RFC 3339 形式のイベント時刻                   |
| `data.task_id`       | プラットフォームのタスク ID                      |
| `data.status`        | 現在の最終ステータス                           |
| `data.model`         | モデル名                                 |
| `data.results[].url` | 完了時に返される場合がある結果のダウンロード URL           |
| `data.error`         | 失敗時に返される場合があるエラー情報                   |

`results` は結果がアーカイブ済みの場合にのみ含まれ、ダウンロードには引き続き Bearer Token が必要です。

<h3 id="webhook-retry">
  リトライと重複排除
</h3>

プラットフォームは少なくとも 1 回の配信を行うため、同じイベントが複数回届く場合があります。

* HTTP `2xx` は受信成功を示します。
* HTTP `5xx`、ネットワークエラー、タイムアウトの場合は再試行します。
* HTTP `3xx` と `4xx` の場合は再試行しません。
* 配信は最大 6 回で、再試行間隔は順に 1、4、16、64、256 秒です。

受信側は `event_id` を保存し、同じイベントを再度受信した場合はそのまま `2xx` を返してください。

<Warning>
  タスク単位の Webhook
  自体には、独立した署名キーが含まれません。署名検証が必要な場合は、アカウント単位の
  Webhook
  サブスクリプションを設定し、結果の確認手段としてタスク詳細の照会も維持してください。
</Warning>

***

<h2 id="error-codes">
  エラーレスポンスとエラーコード
</h2>

```json theme={null}
{
  "error": {
    "message": "Task not found.",
    "type": "invalid_request_error",
    "code": "task_not_found",
    "tid": "req_01K0ABCDEF"
  }
}
```

| HTTP ステータスコード | エラーコード                          | 説明                                             |
| ------------- | ------------------------------- | ---------------------------------------------- |
| 400           | `invalid_request`               | パラメータの型または値が正しくない                              |
| 400           | `result_id_required`            | 統一タスクに複数の結果があるが、ダウンロード時に `result_id` が指定されていない |
| 400           | `webhook_invalid`               | Webhook URL が不正、またはフィルターに URL が指定されていない        |
| 400           | `webhook_events_filter_invalid` | Webhook イベント一覧が不正                              |
| 401           | `authentication_failed`         | API Key が指定されていない、または無効                        |
| 403           | `async_not_enabled`             | アカウントで非同期タスク機能が有効になっていない                       |
| 404           | `task_not_found`                | タスクまたはページングカーソルが存在しない                          |
| 404           | `result_not_found`              | 結果が存在しない、または現在ダウンロードできない                       |
| 410           | `artifact_expired`              | 結果の有効期限が切れている                                  |
| 413           | `request_too_large`             | リクエストボディが 32 MiB を超えている                        |
| 429           | `too_many_downloads`            | 結果のダウンロード回数の上限を超えている                           |
| 503           | `async_unavailable`             | 非同期画像サービスが一時的に利用できない                           |

`error.tid` はリクエストのトレース ID です。テクニカルサポートへ調査を依頼する際は、あわせて提示してください。

***

## 完全な例

タスクを作成し、ポーリングして MP4 をダウンロードします。

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

  import requests

  base_url = "https://aihubmix.com"
  headers = {
      "Authorization": f"Bearer {os.environ['AIHUBMIX_API_KEY']}",
      "Content-Type": "application/json",
  }

  response = requests.post(
      f"{base_url}/ai/v1/videos",
      headers=headers,
      json={
          "model": "wan2.6-t2v",
          "prompt": "A cat playing jazz on a piano",
          "duration": 5,
          "size": "1280x720",
      },
      timeout=60,
  )
  response.raise_for_status()
  task = response.json()

  while task["status"] not in {"completed", "failed", "cancelled"}:
      time.sleep(15)
      response = requests.get(
          f"{base_url}/ai/v1/videos/{task['id']}",
          headers=headers,
          timeout=30,
      )
      response.raise_for_status()
      task = response.json()

  if task["status"] == "completed":
      result = requests.get(
          f"{base_url}/ai/v1/videos/{task['id']}/content",
          headers=headers,
          timeout=120,
      )
      result.raise_for_status()
      with open("result.mp4", "wb") as file:
          file.write(result.content)
  else:
      raise RuntimeError(task.get("error") or task["status"])
  ```

  ```typescript TypeScript theme={null}
  import { writeFile } from "node:fs/promises";

  const baseUrl = "https://aihubmix.com";
  const headers = {
    Authorization: `Bearer ${process.env.AIHUBMIX_API_KEY}`,
    "Content-Type": "application/json",
  };

  const created = await fetch(`${baseUrl}/ai/v1/videos`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      model: "wan2.6-t2v",
      prompt: "A cat playing jazz on a piano",
      duration: 5,
      size: "1280x720",
    }),
  });
  if (!created.ok) throw new Error(await created.text());
  let task = await created.json();

  const finished = new Set(["completed", "failed", "cancelled"]);
  while (!finished.has(task.status)) {
    await new Promise((resolve) => setTimeout(resolve, 15_000));
    const polled = await fetch(`${baseUrl}/ai/v1/videos/${task.id}`, { headers });
    if (!polled.ok) throw new Error(await polled.text());
    task = await polled.json();
  }

  if (task.status === "completed") {
    const result = await fetch(`${baseUrl}/ai/v1/videos/${task.id}/content`, {
      headers,
    });
    if (!result.ok) throw new Error(await result.text());
    await writeFile("result.mp4", Buffer.from(await result.arrayBuffer()));
  } else {
    throw new Error(JSON.stringify(task.error ?? task.status));
  }
  ```
</CodeGroup>
