Skip to main content
Webhooks eliminate the need for polling — your server gets an HTTP callback the moment a processing event fires.

Event Types

If you omit the events field when creating a webhook, it defaults to all supported events.

Requirements

  • HTTPS required: Webhook URLs must use HTTPS. HTTP URLs are rejected.
  • API version: Webhook endpoints require the v2 API (/v2/webhooks/).
  • Limit: Up to 50 active webhook subscriptions per organization.

How It Works

  1. Create a webhook with your HTTPS endpoint URL
  2. Save the secret from the creation response (it is only returned once)
  3. When processing completes or fails, your endpoint receives a POST request
  4. Verify the request signature using the secret

Payload Structure

Every webhook delivery sends a JSON POST request with this structure:
For extraction.failed, the payload looks the same but with status: "error" and processed_at: null:

Delivery Headers

Each webhook request includes these headers:

Signature Verification

Webhook payloads are signed using HMAC-SHA256. To verify a delivery:
  1. Read the raw request body (the JSON string exactly as received)
  2. Compute HMAC-SHA256(secret, body) using the secret from webhook creation
  3. Compare the result with the value after sha256= in the X-Webhook-Signature header
Always use a constant-time comparison (hmac.compare_digest) to prevent timing attacks. Never use == to compare signatures.

Retry Policy

If all 3 attempts fail, the delivery is dropped and logged on our side. Webhook failures do not affect processing itself — delivery is best-effort.
To avoid missed events during outages, we recommend periodically listing your files with GET /v2/workflows/{workflow_id}/files/ and checking for any with status: "processed" or status: "error" that you haven’t handled.

Webhook Secret

When you create a webhook, the API returns a secret field (a 64-character hex string). This secret is only included in the creation response and is excluded from list responses. Store it securely.

Endpoints