Webhooks provide real-time notifications for document lifecycle events, eliminating the need for polling. Configure your webhook endpoints once and receive notifications for all subscribed events automatically.
How Webhooks Work
Webhooks are signed with HMAC-SHA256. Always verify the X-DocIntell-Signature header before processing.
Quick Start
1. Create Webhook Endpoint
from flask import Flask, request
import hmac, hashlib
app = Flask(__name__)
WEBHOOK_SECRET = "whsec_your_secret"
@app.route("/webhooks/docintel", methods=["POST"])
def handle_webhook():
# Verify signature
signature = request.headers.get("X-DocIntell-Signature")
payload = request.get_data()
expected = "sha256=" + hmac.new(
WEBHOOK_SECRET.encode(), payload, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
return {"error": "Invalid signature"}, 401
event = request.get_json()
if event["event"] == "document.processing.completed":
# Document extraction completed successfully
process_document(event["data"]["document_id"])
elif event["event"] == "document.processing.failed":
# Document extraction failed
handle_failure(event["data"]["document_id"], event["data"]["error_message"])
elif event["event"] == "document.uploaded":
# Document uploaded and queued for processing
log_upload(event["data"]["document_id"])
return {"status": "ok"}, 200
2. Register Webhook
curl -X POST https://api.docintell.com/v1/webhooks \
-H "Authorization: Bearer dk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/docintel",
"events": ["document.processing.completed", "document.processing.failed"]
}'
The response includes a signing_secret - store it securely, as it won’t be shown again:
{
"webhook_config_id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://yourapp.com/webhooks/docintel",
"signing_secret": "whsec_abcdefghijklmnopqrstuvwxyz1234567890ABC",
"events": ["document.processing.completed", "document.processing.failed"],
"is_active": true
}
Event Types
document.uploaded
Fired when a document is successfully uploaded and queued for processing.
{
"event": "document.uploaded",
"timestamp": "2025-12-03T10:30:00Z",
"data": {
"document_id": "660e8400-e29b-41d4-a716-446655440001",
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"tenant_id": "770e8400-e29b-41d4-a716-446655440002",
"status": "queued"
}
}
document.processing.completed
Fired when document extraction completes successfully.
{
"event": "document.processing.completed",
"timestamp": "2025-12-03T10:30:47Z",
"data": {
"document_id": "660e8400-e29b-41d4-a716-446655440001",
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"tenant_id": "770e8400-e29b-41d4-a716-446655440002",
"status": "completed",
"processing_time_seconds": 45.2,
"page_count": 12,
"ir_version": "v001"
}
}
document.processing.failed
Fired when document extraction fails.
{
"event": "document.processing.failed",
"timestamp": "2025-12-03T10:31:00Z",
"data": {
"document_id": "660e8400-e29b-41d4-a716-446655440001",
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"tenant_id": "770e8400-e29b-41d4-a716-446655440002",
"status": "failed",
"error_message": "File is corrupted or password protected"
}
}
Managing Webhooks
List Webhooks
curl https://api.docintell.com/v1/webhooks \
-H "Authorization: Bearer dk_live_YOUR_API_KEY"
Update Webhook
curl -X PATCH https://api.docintell.com/v1/webhooks/{webhook_id} \
-H "Authorization: Bearer dk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": ["document.processing.completed"],
"is_active": false
}'
Rotate Secret
curl -X POST https://api.docintell.com/v1/webhooks/{webhook_id}/rotate \
-H "Authorization: Bearer dk_live_YOUR_API_KEY"
Delete Webhook
curl -X DELETE https://api.docintell.com/v1/webhooks/{webhook_id} \
-H "Authorization: Bearer dk_live_YOUR_API_KEY"
Security
All webhooks include HMAC-SHA256 signatures in the X-DocIntell-Signature header. Always verify signatures to ensure authenticity.
Headers included with every webhook:
| Header | Description |
|---|
X-DocIntell-Signature | HMAC-SHA256 signature (sha256=...) |
X-DocIntell-Event | Event type (e.g., document.processing.completed) |
X-DocIntell-Timestamp | Unix timestamp of event |
Content-Type | application/json |
Retry Policy
DocIntell uses exponential backoff for webhook retries:
| Attempt | Delay |
|---|
| 1st | Immediate |
| 2nd | ~1 second |
| 3rd | ~2 seconds |
| 4th | ~4 seconds |
| 5th | ~8 seconds |
After 5 failed attempts (or a 4xx client error), delivery is marked as failed and moved to the Dead Letter Queue for manual review.
Best Practices
- Verify signatures - Always validate the
X-DocIntell-Signature header
- Respond quickly - Return a 2xx response within 10 seconds
- Process async - Queue webhook processing for heavy operations
- Handle duplicates - Use
document_id and job_id for idempotency
- Rotate secrets - Periodically rotate your webhook signing secret