Gidsen

Batchjob-levenscyclus

Sync vs async, jobstatussen, partiële resultaten en webhooks

Batch-Endpoints (/batch/distill, /batch/extract) zijn asynchroon. Een job doorloopt een kleine state machine; de statussen begrijpen helpt je te kiezen tussen polling en Webhooks, en hoe je met partiële mislukkingen omgaat.

Sync vs async

Sync (/distill, /extract)Async (/batch/distill, /batch/extract)
URL's per request1tot 100
ResponseVolledig resultaat in HTTP-bodyJob-ID; resultaten apart opgehaald
LatencyEén request, één wachttijdIndienen → polling of Webhook → ophalen
Beste voorRealtime UX, agent-tooling, ad-hoc lookupsGeplande jobs, RAG-ingestie, monitoring
FaalmodusEén slechte URL laat de aanroep mislukkenEén slechte URL laat zijn rij mislukken, job gaat door
Concurrency-kostenEén slot per aanroepEén slot voor de hele batch

Bij twijfel: enkele URL → sync; veel URL's of geen haast → async.

Jobstatussen

StatusBetekenis
PENDINGJob geaccepteerd, in wachtrij
PROCESSINGMinstens één URL wordt verwerkt
COMPLETEDAlle URL's hebben een eindstatus bereikt (succes of mislukking)
FAILEDFatale fout op job-niveau (zeldzaam — meestal mislukt één URL, niet de hele job)
CANCELLEDDoor gebruiker geïnitieerde annulering via DELETE

Een mislukte URL laat de job niet mislukken. Elk item in results[] heeft zijn eigen status: PENDING, PROCESSING, SUCCEEDED of FAILED. De job gaat naar COMPLETED zodra elke rij een eindstatus bereikt.

Polling vs Webhooks

JobgrootteAanbevolenWaarom
< 10 URL'sPoll elke 5–10 sWebhook-overhead is de bedrading niet waard
10–100 URL'sWebhookPolling verbruikt ~60 round-trips bij een job van 5 minuten
> 100 URL's (meerdere batches)WebhookElke batch vuurt eenmaal bij voltooiing

Zie Webhooks voor payload-vorm, handtekeningverificatie (HMAC-SHA256) en retry-gedrag.

Partiële resultaten

GET /batch/distill/{id} werkt terwijl de job nog PROCESSING is — je krijgt wat tot dusver klaar is. Handig voor dashboards die rijen streamen zodra ze klaar zijn.

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)

Annulering

DELETE /batch/distill/{id} (of /batch/extract/{id}) werkt alleen op PENDING- of PROCESSING-jobs. Zodra een job een eindstatus bereikt, blijft hij daar. Reeds verwerkte URL's in een geannuleerde job blijven factureerbaar; in-flight URL's die nog niet klaar waren niet.