Webhooks
Receive real-time notifications when PDFs are generated.
Overview
Webhooks let you subscribe to events in PDF-API and receive HTTP POST notifications at a URL you specify. This is useful for workflows where you need to process the generated PDF automatically (e.g. send it by email, store it in a CRM, etc.).
Webhooks are available on the Pro plan.
Available events
| Event | Description |
|---|---|
pdf.created | Triggered when a PDF is successfully generated from one of your templates. |
Creating a webhook
- Go to Settings → Webhooks
- Click Create Webhook
- Enter the destination URL
- Optionally select a specific template to filter events (leave empty for all templates)
- Save the webhook
A unique secret key is automatically generated for each webhook. You will need this secret to verify the signature of incoming requests.
Payload format
When an event is triggered, PDF-API sends a POST request to your URL with a JSON payload:
{
"event": "pdf.created",
"timestamp": "2026-03-30T10:00:00.000000Z",
"data": {
"template_id": 123,
"template_name": "Invoice",
"filename": "invoice-001.pdf",
"size": 12345,
"pdf": "JVBERi0xLjQKJeLj..."
}
}The pdf field contains the base64-encoded PDF content. If the PDF was generated with output: "url", the pdf field is omitted.
Request headers
Each webhook request includes the following headers:
Content-Type: application/jsonX-Webhook-Event— the event name (e.g.pdf.created)X-Webhook-Timestamp— ISO-8601 timestampX-Webhook-Signature— HMAC-SHA256 signature for verification
Verifying signatures
Every webhook request is signed with your webhook's secret using HMAC-SHA256. You should always verify the signature to ensure the request is authentic.
The signature is computed over the raw JSON body of the request:
HMAC-SHA256(webhook_secret, request_body)Verification in PHP
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$secret = 'your_webhook_secret';
$expected = hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
$data = json_decode($payload, true);
// Process the webhook...Verification in Node.js
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}Retry policy
If your endpoint is unreachable or returns a non-2xx status code, PDF-API retries the delivery up to 3 times with exponential backoff:
- 1st retry: after 10 seconds
- 2nd retry: after 1 minute
- 3rd retry: after 5 minutes
Each request has a 10-second timeout. After all retries are exhausted, the delivery is marked as failed.
Delivery tracking
You can view the delivery history for each webhook in the dashboard. Each delivery shows:
- HTTP status code returned by your endpoint
- Response body
- Response time (in ms)
- Status:
pending,success, orfailed - Number of attempts
Managing webhooks
- Regenerate secret — generate a new signing secret if the current one is compromised
- Test — send a test payload to verify your endpoint is working
- Delete — remove a webhook to stop receiving notifications
hash_equals in PHP or timingSafeEqual in Node.js) to prevent timing attacks.