指南

批次任務生命週期

同步 vs 非同步、任務狀態、部分結果與 Webhook

批次端點(/batch/distill/batch/extract)是非同步的。任務會走過一個小型狀態機;理解這些狀態能幫你決定該用輪詢還是 Webhook,以及如何處理部分失敗。

同步 vs 非同步

同步(/distill/extract非同步(/batch/distill/batch/extract
單次請求 URL 數1最多 100
回應完整結果在 HTTP body任務 ID;結果另外取
延遲一次請求、一次等待提交 → 輪詢或 Webhook → 抓取
適用即時 UX、Agent 工具、臨時查詢排程任務、RAG 灌庫、監控
失敗模式一個 URL 壞了整個呼叫就壞一個 URL 壞了該列才壞,任務繼續
併發成本每次呼叫佔一格整批佔一格

不確定就:單一 URL → 同步;多個 URL 或不急 → 非同步。

任務狀態

Status意義
PENDING任務已接受、已入佇列
PROCESSING至少有一個 URL 正在處理
COMPLETED所有 URL 都到了終態(成功或失敗)
FAILED任務級致命錯誤(罕見 —— 通常是某個 URL 失敗,而非整個任務)
CANCELLED使用者透過 DELETE 主動取消

某個 URL 失敗 不會 讓任務失敗。results[] 中每一項都有自己的 statusPENDINGPROCESSINGSUCCEEDEDFAILED。當每一列都到了終態,任務才會進入 COMPLETED

輪詢 vs Webhook

任務規模建議原因
< 10 URL每 5–10 秒輪詢一次Webhook 的接線成本不划算
10–100 URLWebhook一個 5 分鐘任務輪詢會燒掉約 60 個來回
> 100 URL(多個批次)Webhook每批完成時各觸發一次

Payload 形狀、簽章驗證(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})只能對 PENDINGPROCESSING 的任務生效。任務一旦進入終態就不會再變。已取消任務中已處理完的 URL 仍會計費;尚未處理完的 URL 不計費。