テーマ
言語

Webhooks とメディアジョブのライフサイクル

mediaWebhookUrl を登録し、ジョブ完了時に POST を受信して GET /api/media/jobs/{id} をポーリングし、エラーコードを処理して、課金と冪等性の制限を理解します。

非同期メディアジョブの操作ガイド: webhook の登録、ステータス、ポーリング、エラーコード、課金、冪等性の制限 — すべてコード内の現在の実装に厳密に準拠しています。

ジョブのライフサイクル

  1. POST /api/media/generate — 成功時は 202 と { ok: true, jobId, status: "processing" }。queued / running という個別のステータスは API にはありません。ジョブが完了するまで、クライアントには processing が表示されます。
  2. 上流は内部ステージ(waiting、generating)を経由することがありますが、これらは公開 API には反映されません。ポーリング中、ジョブは processing のままです。
  3. 終端ステータス: success(resultUrls あり、成功時に課金)または fail(課金なし)。
  4. 完了は一度だけ記録されます: 上流のコールバック経由、または GET /api/media/jobs/{id} での遅延ポーリング時です。

ポーリング:GET /api/media/jobs/{id}

GEThttps://getvibeapi.com/api/media/jobs/{id}
パラメータータイプ説明
statusstringsubmitting | processing | success | fail. submitting + media_submission_uncertain is non-terminal; within about 10–15 minutes such a submission is closed as fail (media_submission_not_started) without a charge — create a new task.
resultUrlsstring[]署名付き URL /api/media/file/{id}/{idx}?sig=…(API キー不要)。
priceRubnumberUSDでの課金金額(失敗時または完了前は0)。
failMsgstring | null失敗時、または非終端の media_submission_uncertain の場合に安全なメッセージを返します。
errorCodestring | nullエラーコード (media_generation_failed) または非終端の media_submission_uncertain。
retryGuidancestring | nullmedia_submission_uncertain の場合: 同じ jobId を後でポーリングし、重複を自動的に作成しないための安全な指示です。
# 2. poll the job until it is ready
curl https://getvibeapi.com/api/media/jobs/JOB_ID \
  -H "Authorization: Bearer $GETVIBE_API_KEY"
# → {"status":"success","resultUrls":["https://..."],"priceRub":...}
推奨ポーリング間隔: 3~5 秒、最大 30 秒の指数バックオフを併用します。クライアント側のタイムアウトはアプリケーションの SLA に従ってください(動画生成には数分かかることがあります)。

Webhook の登録

GEThttps://getvibeapi.com/api/webhooks
PATCHhttps://getvibeapi.com/api/webhooks

アカウントごとに 1 つの URL: mediaWebhookUrl。ダッシュボード → Webhooks で設定するか、API から アカウントセッション(ログイン後の Cookie)を使って設定します。エンドポイント は sk-pv-… を受け付けません。認証済みセッションのみです。

# Example (a dashboard session is required, not an API key)
curl -X PATCH https://getvibeapi.com/api/webhooks \
  -H "Content-Type: application/json" \
  -b "session=YOUR_SESSION" \
  -d '{"mediaWebhookUrl":"https://example.com/webhooks/media"}'

# Clear the URL
curl -X PATCH https://getvibeapi.com/api/webhooks \
  -H "Content-Type: application/json" \
  -b "session=YOUR_SESSION" \
  -d '{"mediaWebhookUrl":null}'
URLの要件
パラメータータイプ説明
mediaWebhookUrlHTTPS URL公開HTTPSアドレスです。プライベートアドレス、ループバックアドレス、および当社独自のドメインは拒否されます(SSRF保護)。また、配信の前に毎回アドレスが再確認されます。空の文字列またはnullを指定するとリセットされます。
balanceWebhookUrlHTTPS URL残高不足用の別のwebhookです(media用ではありません)。同じアカウントシークレットで署名され、x-pv-event: balance.lowが使用されます。しきい値はbalanceWebhookThresholdRubです。

ジョブ完了時の Webhook 配信

ジョブが終端ステータスに達すると、GetVibe は 1 つの論理イベントを作成し、POST を介して登録済みの mediaWebhookUrl に配信します。配信には上限があります: サービスは合計最大 5 回試行します。同じペイロードが複数回届く場合があります。

// POST to your mediaWebhookUrl when a job finishes
{
  "jobId": "...",
  "status": "success",            // or "fail"
  "model": "veo-3.1",
  "kind": "video",                // image | video | audio | music | 3d
  "resultUrls": ["https://getvibeapi.com/api/media/file/..."],
  "failMsg": null,
  "createdAt": "2026-06-17T10:00:00.000Z"
}
配信の動作 (コードどおり)
パラメータータイプ説明
Signature / auth—すべての配信はStandard Webhooksを使用して署名されます。署名にはwebhook-id、webhook-timestamp、webhook-signatureヘッダー(v1、base64 HMAC-SHA256の「id.timestamp.body」)が使用されます。アカウントシークレットはダッシュボード → Webhooksに表示され、GET /api/media/webhook-secretによってAPIキーにaccountSecretとして返されます。リクエストごとのwebhook_urlへの配信は、そのキーのシークレット(secretフィールド)で署名されます。署名が正しくない場合、またはtimestampが5分を超えて古い場合は、リクエストを拒否してください。
Retriesoutbox合計最大 5 回の試行。失敗後の間隔は 1、2、4、8 分です。試行を使い切ると、イベントは FAILED に移行し、自動配信は行われなくなります。状態のソースは引き続き GET /api/media/jobs/{id} によるポーリングです。
Receiver deduprequiredjobId + status のペアで重複を排除し、ハンドラーを冪等にしてください。Webhook を状態の唯一の情報源として使用しないでください。
Content-Typeapplication/jsonボディは、jobId、status、model、kind、resultUrls、failMsg、createdAtのフィールドを持つJSONです。

POST /api/media/generate のエラー

HTTPタイミング課金再試行
202ジョブを受け付けました(ok: true, jobId)いいえ (成功後のみ)—
400無効なJSON / リクエストボディいいえリクエストを修正する
401API キーが欠落しているか無効ですいいえAuthorizationを確認
402残高不足(受付時)いいえ残高をチャージする
422不明なモデル、無効な opts、ファサードからの ok: falseいいえFix model/opts
502media_submit_failed — 上流が利用できませんいいえバックオフ付き再試行
503priceUnavailable、ルーティングガード、VIDEO_DISABLED、価格なしのveoいいえ別のモデル / 後で

ポーリングエラーと最終的な失敗

HTTP / ステータス意味課金
404ジョブが見つからないか、他者の jobId ですいいえ
processingジョブはまだ実行中ですいいえ
success完了、resultUrls が設定されましたはい — 応答の priceRub
fail生成に失敗しましたNo (priceRub = 0)

請求と冪等性

  • 成功時に1回だけ課金されます。 finalizeJob では、遷移 processing → success|fail はアトミックです。コールバックやポーリングを繰り返しても、2回目の課金は発生しません。
  • fail — 無料。 fail ステータスでは引き落としは行われません。
  • 受付時の見積もり。 作成時に見積もりが保存されていた場合、成功時にはまさにその額が課金されます(実際の上流での計測額を超えることはありません)。
  • 冪等性の作成 — ヘッダーによる指定。 ヘッダーなしで /api/media/generate に POST を繰り返すと、新しいジョブが作成され、成功時に新たな課金が発生します。Idempotency-Key を送信してください(最大255 ASCII文字)。同じキーと同じボディで24時間以内に再試行すると、新しいジョブを作成せずに同じ jobId が返されます。同じキーでボディが異なる場合は 422、最初のリクエストがまだ処理中の場合は 409 です。有料生成の jobId は GET /v1/generations でも表示されます(job_id フィールド)。
  • Webhook は最大 5 回の試行に制限されます。 論理イベントは終端遷移ごとに 1 つ作成されますが、配信の試行は繰り返されることがあります。5 回失敗すると、イベントのステータスは FAILED になります。クライアントのハンドラーは jobId + status のペアを重複排除する必要があります。
関連項目: Media generation、Media model catalog、Errors and limits(/v1 でよくある 401/402/429 コード)。
GetVibe API メディア Webhook — ステータス、エラー、課金 | GetVibe API