Guides

Webhooks

Receive batch job completion notifications

For batch jobs longer than a minute, webhooks are cheaper and faster than polling. Thunderbit POSTs to your URL when a job reaches a terminal state.

Configure on submission

{
  "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" }
  }
}

Payload

{
  "id": "batch_abc123",
  "status": "COMPLETED",
  "total": 50,
  "completed": 49,
  "failed": 1,
  "completedAt": "2026-04-26T10:00:00Z"
}

Payloads are intentionally small — pull full results via GET /batch/distill/{id} after receiving the callback.

Signature verification

When secret is set, every delivery includes X-Webhook-Signature: sha256=<hex>. Verify with HMAC-SHA256.

import hmac, hashlib

def verify(raw_body: bytes, signature: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

Never trust an unsigned webhook in production.

Retry behavior

  • Non-2xx → 5 retries with exponential backoff: 10s, 30s, 2m, 10m, 30m
  • Per-delivery timeout: 15s
  • After all retries fail, the job is still complete on our side — your endpoint must be idempotent

This page is being expanded with debugging tips — check back soon.