API Reference / Webhooks

Webhooks

Receive a signed HTTP callback the moment an extraction finishes — no polling required.

Register an endpoint

POST/v1/webhooks

Register a URL and the events you care about. The response includes a signing secret — store it.

cURL · POST /v1/webhooks
POST /v1/webhooks
{
  "url": "https://your-app.com/hooks/docmind",
  "events": ["extraction.completed", "extraction.failed"]
}

{
  "id": "b7e1...",
  "url": "https://your-app.com/hooks/docmind",
  "secret": "whsec_a79d24...",
  "events": ["extraction.completed", "extraction.failed"],
  "status": "active"
}

List with GET /v1/webhooks and remove with DELETE /v1/webhooks/:id. Delivery is retried with backoff on non-2xx responses.

Events

NAMETYPEDESCRIPTION
extraction.completedeventAn extraction finished successfully. data holds the extracted fields.
extraction.failedeventAn extraction could not complete. data holds { error }.

Payload & headers

Each delivery is a POST with two headers and a JSON body:

Delivery
POST /hooks/docmind
X-DocMind-Event: extraction.completed
X-DocMind-Signature: sha256=3f9b2c...

{
  "event": "extraction.completed",
  "id": "2f14eb10-6b1d-4f0e-9a3b-1c7e6d5a8b21",
  "data": {
    "invoice_number": "INV-2026-0481",
    "total_amount": 19872.0
  },
  "created": "2026-06-07T10:41:58Z"
}
NAMETYPEDESCRIPTION
X-DocMind-EventheaderThe event type, e.g. extraction.completed.
X-DocMind-SignatureheaderHMAC-SHA256 of the raw body, formatted sha256=<hex>.

Verify signatures

Always verify the signature before trusting a delivery. Compute an HMAC-SHA256 of the raw request body with your endpoint secret and compare it, constant-time, to the header.

Node.js
import crypto from "crypto";

function verify(secret, rawBody, header) {
  const expected =
    "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header));
}

// Express: use the raw body, not the parsed JSON
app.post("/hooks/docmind", (req, res) => {
  const ok = verify(SECRET, req.rawBody, req.header("X-DocMind-Signature"));
  if (!ok) return res.sendStatus(401);
  res.sendStatus(200);
});
Use the raw bodyCompute the HMAC over the exact bytes received — re-serializing parsed JSON changes whitespace and breaks the signature.