dOCR
Guides

Webhooks

Receive signed events when extractions complete or fail.

Webhooks let your backend react to extractions without polling. Configure endpoints in the dashboard under Developers → Webhooks.

Events

EventWhen
extraction.completedAn extraction finished successfully.
extraction.failedAn extraction failed.
screenshot.completedA screenshot render finished successfully.
screenshot.failedA screenshot render failed.

Payload

dOCR sends a POST with a JSON body. Every event shares the same envelope — an event name, an event-specific data object, and a timestamp.

extraction.completed
{
  "event": "extraction.completed",
  "data": {
    "extractionId": "6a382443304f240b189f228a",
    "documentType": "Invoice",
    "output": { "documentType": "Invoice", "fields": {  } }
  },
  "timestamp": "2026-06-21T17:50:00.000Z"
}

Screenshot renders fire when an async request finishes (see the Screenshots guide):

screenshot.completed
{
  "event": "screenshot.completed",
  "data": {
    "screenshotId": "6a382443304f240b189f228a",
    "url": "https://res.cloudinary.com/docr/image/upload/screenshot-6a382443.png",
    "format": "png"
  },
  "timestamp": "2026-06-25T17:50:02.100Z"
}

A failed render sends screenshot.failed with the id and an error message instead of a url.

Verifying signatures

Every delivery includes an X-docr-Signature header — an HMAC-SHA256 of the raw request body using your webhook's signing secret. Always verify it before trusting a payload.

Verify (Node.js)
import crypto from "node:crypto";

function verify(rawBody: string, signature: string, secret: string) {
  const expected =
    "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
Verify (Python)
import hmac, hashlib

def verify(raw_body: bytes, signature: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(signature, expected)

Delivery & retries

Failed deliveries are retried with backoff. You can inspect recent deliveries and send a test event from the dashboard.

On this page