ガイド

バッチジョブのライフサイクル

同期 vs 非同期、ジョブの状態、部分結果、Webhook

バッチエンドポイント(/batch/distill/batch/extract)は非同期です。ジョブは小さなステートマシンを通って遷移します。状態を理解することで、ポーリングと Webhook のどちらを使うか、部分的な失敗をどう処理するかを判断できます。

同期 vs 非同期

同期(/distill/extract非同期(/batch/distill/batch/extract
リクエストあたり URL 数1最大 100
レスポンスHTTP body に完全な結果ジョブ ID。結果は別途取得
レイテンシ1 リクエスト、1 回の待機サブミット → ポーリングまたは Webhook → 取得
適した用途リアルタイム UX、エージェントツール、アドホック検索スケジュールジョブ、RAG インジェスト、モニタリング
失敗モード1 つの不正 URL で呼び出し全体が失敗1 つの不正 URL はその行が失敗、ジョブは継続
並列度コスト呼び出しごとに 1 スロットバッチ全体で 1 スロット

迷ったときは:単一 URL → 同期、複数 URL や急がない → 非同期。

ジョブの状態

ステータス意味
PENDINGジョブを受領、キューイング済み
PROCESSING少なくとも 1 つの URL を処理中
COMPLETEDすべての URL が終了状態(成功または失敗)に到達
FAILEDジョブレベルの致命的エラー(稀 —— 通常は 1 つの URL が失敗してもジョブ全体は失敗しない)
CANCELLEDDELETE によるユーザー起点のキャンセル

URL の失敗ではジョブは失敗しませんresults[] の各アイテムは独自の status を持ちます:PENDINGPROCESSINGSUCCEEDED、または FAILED。すべての行が終了状態に到達するとジョブは COMPLETED に遷移します。

ポーリング vs Webhook

ジョブサイズ推奨理由
10 URL 未満5〜10 秒ごとにポーリングWebhook の配線コストが見合わない
10〜100 URLWebhook5 分のジョブで約 60 ラウンドトリップを消費
100 URL 超(複数バッチ)Webhook各バッチが完了時に 1 回発火

ペイロード形状、署名検証(HMAC-SHA256)、リトライ動作については Webhook を参照。

部分結果

GET /batch/distill/{id} はジョブが PROCESSING 中でも動作します —— その時点で完了したものを取得できます。完了した行をストリーミング表示するダッシュボードに有用です。

import httpx, time

API = "https://openapi.thunderbit.com/openapi/v1"
H = {"Authorization": "Bearer YOUR_API_KEY"}

job = httpx.post(f"{API}/batch/distill", headers=H,
                 json={"urls": urls}).json()
batch_id = job["data"]["id"]

while True:
    body = httpx.get(f"{API}/batch/distill/{batch_id}", headers=H).json()["data"]
    fresh = [r for r in body["results"] if r["status"] == "SUCCEEDED"]
    yield_to_dashboard(fresh)
    if body["status"] in ("COMPLETED", "FAILED", "CANCELLED"):
        break
    time.sleep(5)

キャンセル

DELETE /batch/distill/{id}(または /batch/extract/{id})は PENDING または PROCESSING のジョブにのみ機能します。一度終了状態になるとそこに留まります。キャンセルされたジョブの中ですでに処理済みの URL は課金対象のままです。完了していなかった処理中の URL は課金されません。