ガイド
Webhook
バッチジョブの完了通知を受け取る
1 分を超えるバッチジョブでは、Webhook はポーリングよりも安価で高速です。Thunderbit はジョブが終了状態に達したときに、あなたの URL に POST します。
送信時の設定
{
"urls": ["https://example.com/page1"],
"webhook": {
"url": "https://your-server.com/api/webhook/distill",
"secret": "whsec_your_secret_key",
"headers": { "X-Custom-Auth": "your-token" }
}
}webhook.headers フィールドはカスタムヘッダーのマップを受け付けますが、このフィールドは将来用に予約されており、現在サーバーから送信されていません。検証は下記のヘッダーのみを前提にしてください。
リクエストヘッダー
すべての配信に以下の 4 つのヘッダーが含まれます:
| Header | Value |
|---|---|
Content-Type | application/json |
X-Webhook-Event | batch.completed |
X-Webhook-Timestamp | Unix エポック(ミリ秒) |
X-Webhook-Signature | sha256=<base64-encoded HMAC-SHA256> |
ペイロード
{
"id": "batch_a1b2c3d4...",
"jobType": "batch_distill",
"status": "COMPLETED",
"total": 50,
"completed": 49,
"failed": 1,
"creditsUsed": 100,
"createdAt": "2026-04-26T10:00:00Z",
"completedAt": "2026-04-26T10:05:23Z"
}jobTypeはbatch_distillまたはbatch_extract。statusはCOMPLETED、FAILED、CANCELLEDのいずれか。
ペイロードは意図的に小さく保たれています。コールバックを受け取った後、GET /batch/distill/{id}(または /batch/extract/{id})で完全な結果を取得してください。
署名検証
secret が設定されている場合、すべての配信に X-Webhook-Signature ヘッダーが付与されます。
- アルゴリズム:HMAC-SHA256
- 署名対象文字列:
<X-Webhook-Timestamp>.<raw-json-body>(リテラルの.を挟む) - 出力形式:
sha256=<base64-encoded-hash>(Base64、hex ではありません)
生 のリクエストバイトで検証してください(JSON を再シリアライズしないこと)。比較は定数時間で行います。
import hmac, hashlib, base64
def verify(raw_body: bytes, timestamp: str, signature: str, secret: str) -> bool:
base = f"{timestamp}.{raw_body.decode('utf-8')}".encode('utf-8')
digest = hmac.new(secret.encode('utf-8'), base, hashlib.sha256).digest()
expected = "sha256=" + base64.b64encode(digest).decode('ascii')
return hmac.compare_digest(expected, signature)リプレイ攻撃対策
|now - X-Webhook-Timestamp| > 60000(60 秒のウィンドウ)の場合、リクエストを拒否してください。タイムスタンプは Unix エポックの ミリ秒 です。本番環境で署名のない webhook を決して信頼しないでください。
リトライ動作
- 1 回あたりのタイムアウト:30 秒
- 最大リトライ回数:3
- バックオフ:指数バックオフ、開始 1 秒、上限 10 秒
- エンドツーエンドの合計ウィンドウ:約 120 秒
すべてのリトライが失敗しても、ジョブは弊社側では完了済みです。受信エンドポイントは冪等にしてください(id を重複排除キーとして使用)。