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

## クイックスタート

ネイティブ画像エンドポイントはデフォルトで同期です。Boolean の `async` を `true` にするとバックグラウンドタスクになります。例では `qwen-image-2.0` を使用します。

<CodeGroup>
  ```bash タスク作成 theme={null}
  curl -X POST https://aihubmix.com/ai/v1/images/generations \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "qwen-image-2.0",
      "prompt": "A flower shop with delicate windows, warm sunlight streaming in",
      "n": 1,
      "size": "1024x1024",
      "async": true
    }'
  ```

  ```json 作成レスポンス theme={null}
  {
    "id": "task_01K0ABCDEF",
    "object": "image",
    "model": "qwen-image-2.0",
    "status": "in_progress",
    "output": [],
    "error": null,
    "created_at": 1784707200,
    "completed_at": null,
    "expires_at": null
  }
  ```

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

  ```bash 結果ダウンロード theme={null}
  curl "{content_url}" \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    --output result.png
  ```
</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-task">
  画像タスクを作成する方法
</h2>

<h3 id="create-sync-image">
  同期画像
</h3>

`async` を省略するか `false` に設定すると、API は生成が完了するまで待機し、タスクオブジェクトを返します。

```bash theme={null}
curl -X POST https://aihubmix.com/ai/v1/images/generations \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen-image-2.0",
    "prompt": "A flower shop with delicate windows, warm sunlight streaming in",
    "n": 1,
    "size": "1024x1024",
    "response_format": "url"
  }'
```

同期画像タスクもタスクレコードとして保存されます。クライアント接続が中断した場合や作成レスポンスを失った場合は、`GET /ai/v1/images` で該当タスクを検索できます。

<h3 id="create-async-image">
  非同期画像
</h3>

`async` をブール値 `true` に設定すると、API はすぐにタスクオブジェクトを返し、生成処理はバックグラウンドで続行されます。

```bash theme={null}
curl -X POST https://aihubmix.com/ai/v1/images/generations \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen-image-2.0",
    "prompt": "A flower shop with delicate windows, warm sunlight streaming in",
    "n": 2,
    "size": "1024x1024",
    "async": true
  }'
```

非同期画像タスクは `GET /ai/v1/images/{id}` で照会します。完了後は、各 `output` 項目の `content_url` を直接リクエストしてください。この URL には、該当画像の `result_id` が含まれています。

<Note>
  画像リクエストの `async` はブール値でなければなりません。`webhook_url` と
  `webhook_events_filter` は `async: true`
  と組み合わせた場合にのみ使用できます。
</Note>

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

| フィールド                   | 型             | 必須  | 説明                                                   |
| ----------------------- | ------------- | --- | ---------------------------------------------------- |
| `model`                 | string        | はい  | モデル名                                                 |
| `prompt`                | string        | はい  | 画像の説明。空にはできない                                        |
| `n`                     | integer/null  | いいえ | 画像数。最小値は `1`、デフォルトは `1`                              |
| `size`                  | string/null   | いいえ | `{width}x{height}`。例：`1024x1024`                     |
| `aspect_ratio`          | string/null   | いいえ | アスペクト比。`size` とのいずれか一方を指定                            |
| `seed`                  | integer/null  | いいえ | 乱数シード                                                |
| `negative_prompt`       | string/null   | いいえ | ネガティブプロンプト                                           |
| `image`                 | string/object | いいえ | 1 枚の入力画像。URL、Data URI、Base64、または `{url}` オブジェクトを指定可能 |
| `images`                | array/null    | いいえ | 複数の入力画像                                              |
| `mask`                  | string/object | いいえ | 画像編集用マスク                                             |
| `output_format`         | string/null   | いいえ | `png`、`jpeg`、または `webp`。デフォルトは `png`                 |
| `response_format`       | string/null   | いいえ | `url` または `b64_json`。デフォルトは `url`                    |
| `async`                 | boolean       | いいえ | `true` に設定すると非同期で実行                                  |
| `webhook_url`           | string        | いいえ | HTTPS コールバック URL。最大 512 文字                           |
| `webhook_events_filter` | string\[]     | いいえ | `completed`、`failed`、`cancelled` の空でないサブセット          |
| `extra`                 | object/null   | いいえ | モデル固有の拡張パラメータ                                        |

***

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

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

```json theme={null}
{
  "id": "task_01K0ABCDEF",
  "object": "image",
  "model": "qwen-image-2.0",
  "status": "completed",
  "output": [
    {
      "index": 0,
      "type": "file",
      "b64_json": null,
      "content_url": "https://aihubmix.com/ai/v1/images/task_01K0ABCDEF/content/result_01K0XYZ"
    }
  ],
  "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/images/{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/images?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": "image",
      "model": "qwen-image-2.0",
      "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=image&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": "image/png",
  "content_url": "https://aihubmix.com/ai/v1/tasks/task_01K0ABCDEF/content/result_01K0XYZ"
}
```

単一成果物の場合は `/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="multiple-artifacts">
  画像のダウンロード
</h3>

画像の完了後、メディアタスクオブジェクトの `output[].content_url` を項目ごとにリクエストします。

```bash theme={null}
curl "{content_url}" \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  --output result.png
```

画像メディアのダウンロードパスは `/ai/v1/images/{id}/content/{result_id}` です。メディアタスクオブジェクトでは `result_id` が個別に公開されないため、クライアントは `content_url` をそのまま使用できます。

`b64_json` が空でない場合は、このフィールドを直接 Base64 デコードできます。

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

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

```bash theme={null}
curl -X POST https://aihubmix.com/ai/v1/images/generations \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen-image-2.0",
    "prompt": "A tranquil garden at sunrise",
    "n": 1,
    "async": true,
    "size": "1024x1024",
    "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": "qwen-image-2.0",
    "results": [
      {
        "url": "https://aihubmix.com/ai/v1/tasks/task_01K0ABCDEF/content/result_01K0XYZ"
      }
    ]
  }
}
```

| フィールド                | 説明                                   |
| -------------------- | ------------------------------------ |
| `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 です。テクニカルサポートへ調査を依頼する際は、あわせて提示してください。

***

## 完全な例

非同期タスクを作成し、ポーリングして、返された画像をすべて保存します。

<CodeGroup>
  ```python Python theme={null}
  import base64
  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/images/generations",
      headers=headers,
      json={
          "model": "qwen-image-2.0",
          "prompt": "A flower shop with delicate windows, warm sunlight streaming in",
          "n": 1,
          "size": "1024x1024",
          "async": True,
      },
      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/images/{task['id']}",
          headers=headers,
          timeout=30,
      )
      response.raise_for_status()
      task = response.json()

  if task["status"] != "completed":
      raise RuntimeError(task.get("error") or task["status"])

  for output in task["output"]:
      filename = f"result-{output['index']}.png"
      if output.get("b64_json"):
          content = base64.b64decode(output["b64_json"])
      else:
          result = requests.get(output["content_url"], headers=headers, timeout=120)
          result.raise_for_status()
          content = result.content
      with open(filename, "wb") as file:
          file.write(content)
  ```

  ```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/images/generations`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      model: "qwen-image-2.0",
      prompt: "A flower shop with delicate windows, warm sunlight streaming in",
      n: 1,
      size: "1024x1024",
      async: true,
    }),
  });
  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/images/${task.id}`, { headers });
    if (!polled.ok) throw new Error(await polled.text());
    task = await polled.json();
  }

  if (task.status !== "completed") {
    throw new Error(JSON.stringify(task.error ?? task.status));
  }

  for (const output of task.output) {
    let content;
    if (output.b64_json) {
      content = Buffer.from(output.b64_json, "base64");
    } else {
      const result = await fetch(output.content_url, { headers });
      if (!result.ok) throw new Error(await result.text());
      content = Buffer.from(await result.arrayBuffer());
    }
    await writeFile(`result-${output.index}.png`, content);
  }
  ```
</CodeGroup>
