Skip to main content
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:
HeaderDescription
X-DocIntell-SignatureHMAC-SHA256 signature (sha256=...)
X-DocIntell-EventEvent type (e.g., document.processing.completed)
X-DocIntell-TimestampUnix timestamp of event
Content-Typeapplication/json

Retry Policy

DocIntell uses exponential backoff for webhook retries:
AttemptDelay
1stImmediate
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

  1. Verify signatures - Always validate the X-DocIntell-Signature header
  2. Respond quickly - Return a 2xx response within 10 seconds
  3. Process async - Queue webhook processing for heavy operations
  4. Handle duplicates - Use document_id and job_id for idempotency
  5. Rotate secrets - Periodically rotate your webhook signing secret