Webhooks Overview
Learn how to configure webhooks to receive real-time notifications when extractions finish.
A Webhook is an HTTP callback that PerfectParser triggers the moment your document extraction batch or single document completes processing. This removes the need to constantly poll batch status endpoints.
Configuring a Webhook
Dashboard (Integrations page)
- Navigate to your PerfectParser dashboard.
- Click Integrations in the left sidebar.
- Open the Webhooks tab and click Add Webhook.
- Fill in:
- Target URL: Your server's HTTPS endpoint.
- Scope: (Optional) Limit callbacks to a specific Parser. Leave blank for all parsers.
- Custom Verification Header: (Optional) Static secret sent as
X-Webhook-Secret. Useful for Zapier or Make.
Dashboard webhooks fire batch.* events when an extraction batch reaches a terminal state. Copy the auto-generated Signing Secret from the subscription card to verify HMAC signatures.
Programmatic API (POST /v1/webhooks)
Use the Create Webhook Endpoint when managing subscriptions from code. API webhooks subscribe to extraction.* events. An optional static secret is sent as X-Webhook-Secret; a signing_secret is returned once on create for HMAC verification.
After creating a webhook, call POST /v1/webhooks/:id/test to verify your endpoint receives and validates payloads before submitting real extractions.
Event Types
| Event | Source | When it fires |
|---|---|---|
batch.completed | Integrations page | Entire batch finished successfully |
batch.failed | Integrations page | Entire batch failed |
batch.partial | Integrations page | Batch finished with mixed success/failure |
extraction.document_completed | POST /v1/webhooks | A single document reaches completed or failed |
extraction.job_completed | POST /v1/webhooks | All documents in a batch finish processing |
Webhook Verification
PerfectParser includes two validation headers in every callback request:
1. Static Secret Header (X-Webhook-Secret)
If you provide a static secret during webhook configuration (via customHeader in the dashboard or secret in POST /v1/webhooks), it will be sent verbatim in this header.
- Best for: Simple, no-code integrations like Zapier or Make, where you can easily verify header values but cannot run HMAC cryptography.
2. HMAC Signature Header (X-PerfectParser-Signature)
PerfectParser computes a SHA-256 HMAC signature of the raw request payload using the webhook's private signing secret, sent in this header.
- Best for: Custom web servers.
- Note: Programmatic webhooks return
signing_secretonce onPOST /v1/webhooks. Dashboard webhooks reveal the signing secret from Integrations → Webhooks. The optional staticsecretyou pass inPOST /v1/webhooksis sent asX-Webhook-Secret, not used for HMAC.
Webhook payloads include both extraction_id and document_id. If delivery fails, retry by calling GET /v1/extractions/:extraction_id/documents/:document_id.
See Verify Webhooks for timing-safe verification examples in Node.js and Python.
Webhook Payloads
PerfectParser sends an HTTP POST request to your URL. The JSON body depends on the subscribed event type.
Dashboard events (batch.*)
Triggered when an extraction batch reaches a terminal state. Fired once per batch completion.
batch.completed / batch.failed / batch.partial
API events (extraction.*)
Subscribed via POST /v1/webhooks. Use these when you need per-document callbacks or a single job-level summary from the public API.
extraction.document_completed
Triggered when a single document inside an extraction batch reaches a terminal success (completed) or failed (failed) state.
extraction.job_completed
Triggered when all documents inside a submitted extraction batch have completed processing.
Timings, Retries, and Failures
- Timeout: Webhook delivery requests time out after 10 seconds. Your server should respond with a
2xxstatus code immediately and process the payload asynchronously. - Retries: If delivery fails (returns a non-
2xxcode or times out), the log status becomespending_retry. PerfectParser will retry up to 5 times using exponential backoff:- Retry 1: 5 minutes after initial failure
- Retry 2: 10 minutes later
- Retry 3: 20 minutes later
- Retry 4: 40 minutes later
- Retry 5: 80 minutes later