Skip to main content
This guide walks through setting up webhooks to receive real-time notifications for document lifecycle events.

Step 1: Create Your Endpoint

Create an HTTPS endpoint that accepts POST requests:
from flask import Flask, request
import hmac
import hashlib

app = Flask(__name__)
WEBHOOK_SECRET = "whsec_your_secret_here"

@app.route("/webhooks/docintel", methods=["POST"])
def handle_webhook():
    # 1. 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

    # 2. Process event
    event = request.get_json()

    if event["event"] == "document.processing.completed":
        document_id = event["data"]["document_id"]
        # Queue for async processing
        process_completed_document.delay(document_id)
    elif event["event"] == "document.processing.failed":
        document_id = event["data"]["document_id"]
        error = event["data"]["error_message"]
        handle_failure.delay(document_id, error)

    return {"status": "ok"}, 200

Step 2: Register Your 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"]
  }'
Save the signing_secret from the response - it’s only shown once!

Event Types Reference

EventDescription
document.uploadedDocument uploaded and queued for processing
document.processing.completedExtraction completed successfully
document.processing.failedExtraction failed with error

Step 3: Test Your Webhook

Upload a document and verify your endpoint receives the notification:
curl -X POST https://api.docintell.com/v1/documents \
  -H "Authorization: Bearer dk_live_YOUR_API_KEY" \
  -F "file=@test.pdf"

Security Checklist

Always verify the X-DocIntell-Signature header
Use constant-time comparison (hmac.compare_digest)
Store the signing secret securely (not in code)
Only accept HTTPS connections
Respond quickly (< 10 seconds) and process async

Troubleshooting

  • Verify your URL is publicly accessible
  • Check that you’re using HTTPS
  • Ensure your firewall allows incoming requests
  • Confirm your webhook is active (check via GET /v1/webhooks)
  • Use the raw request body, not parsed JSON
  • Ensure you’re using the correct secret
  • Check for encoding issues
  • The header is X-DocIntell-Signature (not X-DocIntell)
  • Use the document_id and job_id from the payload to deduplicate
  • Store processed event IDs temporarily in Redis or database
  • DocIntell guarantees at-least-once delivery