PPDFInvoiceAPI
DOCS/ Webhooks

ADVANCED

Webhooks

Register an HTTPS endpoint and receive signed events from your renders. Available on Starter and up.

Setting up

Webhooks are available on Starter and higher. Register anhttps:// endpoint inDashboard → Settings. You get a signing secret (whsec_…, shown once) and can send a signed testPOST from the dashboard to verify your receiver works before you rely on it.

The payload

Deliveries are a single JSON POST. The event type is in thex-webhook-event header and the body, and the signature is inx-webhook-signature:

POST /your-webhook HTTP/1.1
content-type: application/json
user-agent: PDFInvoiceAPI-Webhooks/1.0
x-webhook-event: render.succeeded
x-webhook-signature: sha256=4f3c...hex

{
  "id": "evt_aB3...",
  "type": "render.succeeded",
  "created": 1718900000,
  "data": { }
}

Verifying signatures

The x-webhook-signature header issha256=<hex>, where the hex is theHMAC-SHA256 of the raw request body keyed with your endpoint secret. Recompute it over the exact bytes you received and compare with a constant-time check:

import { createHmac, timingSafeEqual } from "node:crypto";

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

// rawBody MUST be the exact bytes received — don't re-serialize the JSON.

Limitations

Delivery today is best-effort: one attempt per event, a short timeout, and no durable retry queue — so treat webhooks as a notification, not a guaranteed ledger. Automatic delivery on every render is rolling out; the dashboard test event and the signing scheme above are live now. Always keep the synchronous response fromPOST /v1/render as your source of truth.