メインコンテンツへスキップ
動画 / 画像 / 音声などの非同期生成タスクを送信する際に、コールバックURLを指定できます。タスクが完了(成功または失敗)すると、結果をあなたのURLに能動的にPOSTするため、ずっとポーリングして問い合わせる必要はありません。

クイックスタート

タスク送信時に、リクエストボディに webhook フィールドを追加します:
curl -X POST https://あなたの接続ドメイン/v1/images/generations \
  -H "Authorization: Bearer あなたのAPIKey" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "a red apple on a table",
    "size": "1024x1024",
    "webhook": "https://your-server.com"
  }'
タスク完了後、あなたのURL + /callback に POST リクエストを送信します。
動画・音声などその他の非同期タスクのエンドポイントも同様で、いずれもリクエストボディに webhook フィールドを追加します。

URLのルール

指定する webhook は**ベースURL(base)**であり、その後ろに自動的に /callback を連結します:
あなたの webhook実際にPOSTする先
https://your-server.comhttps://your-server.com/callback
https://your-server.com/apihttps://your-server.com/api/callback
https://your-server.com/api/https://your-server.com/api/callback
そのため、サーバー側で POST .../callback を受け取るエンドポイントを用意する必要があります。

受信する内容

プッシュされる内容は**「タスクステータスの取得」エンドポイントが返すものと完全に同じ**です。同じ解析ロジックで処理できます。
{
  "id": "task_01KV7FXR8BEYS1BWHJCT3JMCJ5",
  "status": "completed",
  "progress": 100,
  "created": 1781589029,
  "completed": 1781589058,
  "actual_time": 29,
  "cost": 0.006,
  "credits_cost": 0.06,
  "result": {
    "images": [{ "url": ["https://.../result.png"], "expires_at": 1781675458 }]
  }
}
動画タスクの結果は result.videos、音声は result.audios にあります。
タスクが終了状態completed / failed)に達したときのみプッシュします。処理中はプッシュしません。

リトライと重複排除(重要)

  • リトライ: サーバー側が約10秒以内に 2xx を返さない、または 5xx を返した場合、自動的に最大 3回 リトライします。間隔は約 10秒、30秒、60秒 です。3回とも失敗すると諦めます(約2分以内に終了)。
  • リトライしないケース: エンドポイントが 4xx を返した場合(URL / リクエストに問題があると見なす)、リトライせずに直ちに諦めます。
  • 重複排除: 通常、1つのタスクは1回のみプッシュされます。ただし極端なケース(送信後・確認前に当方で再起動が発生した場合など)では、重複プッシュを受信する可能性があります。重複処理を避けるため、必ず id(task_id)で冪等に重複排除 してください。
受信エンドポイントの推奨事項:
1

できるだけ早く 2xx を返す

まず受け取ってキューに入れ、その後で非同期に処理してください。処理完了まで当方を待たせないでください。
2

id で重複排除する

id(task_id)を冪等キーとして使用し、重複処理を回避してください。
3

署名を設定・検証する

本番環境では、コールバックリクエストの送信元を検証し、偽造されたリクエストを拒否してください。

コールバックURLの要件

セキュリティのため、コールバックURLは次を満たす必要があります:
要件説明
公開アクセス可能内部 / ローカルアドレス(127.0.0.110.x192.168.x など)は不可(拒否されます)
プロトコルhttp または httpshttps 推奨)
ポート標準ポート(80 / 443)を使用。非標準ポートはブロックされる可能性があります
ドメイン当方自身のサービスドメインを指してはいけません
要件を満たさないURLは直ちに破棄されます(プッシュもリトライもされません)。

よくある質問

1つずつ確認してください:
  1. タスクは本当に完了しましたか? タスク詳細を確認し、statuscompleted / failed になっていますか(処理中はプッシュしません)?
  2. あなたのURLは公開アクセス可能ですか? 当方からあなたの /callback に到達できますか?
  3. ポートは標準ポート(80 / 443)ですか? 非標準ポートはセキュリティポリシーでブロックされる可能性があります。
  4. あなたの /callback速やかに 2xx を返しましたか? 4xx を返すと直ちに諦めます。
  5. https を使っていますか? 証明書は有効ですか?
一部のモデルは一度に複数枚の画像を生成するため、images[].url は配列になることがあります。配列として処理してください。
resultexpires_at(Unixタイムスタンプ)が含まれる場合、そのリンクの有効期限を示します。速やかに保存し直してください。
いいえ。タスクが最終的に成功または失敗したときに1回だけプッシュします。

最小の受信側サンプル

Python
from http.server import BaseHTTPRequestHandler, HTTPServer
import json

class H(BaseHTTPRequestHandler):
    def do_POST(self):
        n = int(self.headers.get("Content-Length") or 0)
        body = self.rfile.read(n)
        data = json.loads(body)
        print("タスクコールバックを受信:", data["id"], data["status"])
        # TODO: id で重複排除し、署名を検証してから処理する
        self.send_response(200); self.end_headers()
        self.wfile.write(b'{"ok":true}')

HTTPServer(("0.0.0.0", 443), H).serve_forever()
受信後はできるだけ早く 200 を返し、処理ロジックはバックグラウンドで非同期に実行してください。