To receive PDF-generation webhooks in Node.js, expose a public POST route, preserve the request body exactly as the provider requires, verify its signature before trusting the event, then validate and handle documented success or failure events. In Express, route-specific express.raw() middleware can preserve the body as a Buffer; the actual signature format, event names, retry behavior, and acknowledgment rules depend on your PDF provider.
What a PDF webhook receiver does
An asynchronous PDF service accepts a job, generates the file outside your request cycle, then sends an HTTP POST to a callback URL you configure. Your application receives that request at a route such as /webhooks/pdf, verifies that it came from the service, records or queues the event, and acknowledges it according to the service’s delivery contract.
A webhook is not the PDF itself in every provider’s design. The event may include a job identifier, a status, a download location, or failure details. Use the provider’s documented schema to determine how to retrieve or store the finished file; do not assume a universal event shape.
Build an Express receiver that preserves the raw body
When a provider signs the request body, verification commonly depends on the original bytes or raw JSON string. Parsing JSON and serializing it again can change whitespace, escaping, or property representation and invalidate the signature. Express documents express.raw() as middleware that places a Buffer in req.body; its accepted content type and body-size limit should be chosen deliberately. See the Express API documentation for express.raw().
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problems#1 Best Overall
This provider-neutral route is an implementation shape, not a ready-made verifier: replace the clearly named verification function and placeholder event names with the selected provider’s supported SDK or documented verification method.
import express from 'express';
const app = express();
app.post('/webhooks/pdf', express.raw({
type: 'application/json',
limit: '1mb'
}), async (req, res) => {
try {
// Implement this with the selected provider's exact SDK/API.
// req.body is the original request body as a Buffer.
const event = await verifyAndParseProviderEvent(req.body, req.headers);
if (!event || typeof event.type !== 'string') {
return res.sendStatus(400);
}
switch (event.type) {
case 'provider.documented.success-event': {
// Validate required fields, persist the job state, and enqueue
// any lengthy PDF download or post-processing.
break;
}
case 'provider.documented.failure-event': {
// Validate the documented failure fields and update job state.
break;
}
default:
// Follow the provider's documented policy for unknown event types.
break;
}
return res.sendStatus(200);
} catch (err) {
// Log safely; do not expose secrets or sensitive payloads in responses.
return res.sendStatus(400);
}
});
app.listen(process.env.PORT || 3000);
The route-specific raw parser must receive the request before a general JSON parser consumes it. One straightforward arrangement is to register this webhook route before app.use(express.json()). Alternatively, configure the application so this path is deliberately excluded from JSON parsing. Do not run both parsers on the webhook request and expect the raw-body verifier to work afterward.
The 1mb limit above is an example application limit, not a provider requirement. Set it to a limit suitable for the provider’s maximum signed payload, and reject unexpectedly large requests rather than allowing unbounded body allocation.
Verify the provider’s signature before acting
Keep the signing secret in server-side configuration, such as an environment variable supplied by your deployment platform. Do not put it in browser code, commit it to source control, or log it. Reject verification failures before performing any backend action based on the event.
Recommended Free Tools
Rank #2
Signature conventions are not interchangeable. Header names, timestamp inclusion, message construction, supported signature versions, digest encoding, tolerance windows, and SDK functions vary. Use the current documentation for the service that sends the webhook; do not transplant another vendor’s HMAC recipe.
OpenAI’s Webhooks API guide states: “While you can receive webhook events from OpenAI and process the results without any verification, you should verify that incoming requests are coming from OpenAI, especially if your webhook will take any kind of action on the backend.” OpenAI’s Node SDK offers client.webhooks.unwrap() to verify and parse a webhook, and expects the raw JSON string. That is an example of OpenAI’s general webhook tooling, not a PDF-generation event contract. Consult the OpenAI Webhooks API guide and OpenAI Node SDK documentation for the current method signature and setup.
PDF-specific documentation illustrates why provider-specific verification matters:
- PDFGate documents an
x-pdfgate-signatureheader, a timestamp and one or morev1signatures, a default five-minute maximum age, and a verifier helper. Check its current documentation and package API before using exact code. - UsePDFMaker documents signed asynchronous conversion callbacks and shows Express raw-body middleware; its documentation warns that parsing JSON first alters the bytes used for signing. See UsePDFMaker’s webhook documentation for its current signature and delivery rules.
- RelayPDF documents timestamp-plus-raw-body HMAC verification and event types including
job.completedandjob.failed. Those event names are RelayPDF’s contract, not a standard shared by every PDF service. See RelayPDF documentation.
Validate and process events safely
A valid signature establishes that a request passed the provider’s authenticity check; it does not guarantee that the payload contains every field your application expects or that its state is appropriate for your workflow. After verification:
Rank #3
- Check the event type against the provider’s documented event list.
- Validate required identifiers and fields before using them in database updates, file retrieval, or business logic.
- Associate the event with a known job when your system initiated the job; do not let an untrusted identifier select arbitrary records or resources.
- Handle completed and failed jobs as distinct states where the provider documents both.
- Use the provider’s documented retrieval or storage mechanism for the generated PDF rather than assuming the callback embeds the file.
RelayPDF, for example, documents job.completed and job.failed. Other providers may use different names, additional lifecycle events, or different fields. Implement only the events and fields in the chosen provider’s current schema.
Choose an acknowledgment and duplicate-delivery strategy
Webhook senders have their own timeout, retry, and response-status rules. The available provider examples do not establish one universal timeout or retry policy, so check the selected service’s delivery documentation before deciding when to return success or failure.
If follow-up work is lengthy—such as downloading a large PDF, storing it in object storage, or notifying another system—verify and validate the event, persist it or enqueue the work, and acknowledge promptly if that provider’s contract allows it. If the provider requires synchronous work or a different response, follow its rule instead.
Where retries can cause duplicate deliveries, make the handler idempotent. Prefer the provider’s documented event or delivery identifier, record whether it has already been processed, and ensure repeated delivery does not create duplicate jobs or repeat irreversible side effects. Retry guarantees, identifier availability, and deduplication semantics are provider-specific; confirm them rather than assuming that every sender retries in the same way.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchRank #4
Compare providers on implementation details
| Documentation example | What it documents | What to confirm for your integration |
|---|---|---|
| OpenAI API / Node SDK | Signing secret and SDK unwrap() verification plus parsing; raw JSON string required. |
It is a general OpenAI webhook example, not a PDF job schema. Confirm the relevant event contract and SDK version. |
| PDFGate | x-pdfgate-signature, timestamp and v1 signature conventions, a default five-minute age check, and a verifier helper. |
Confirm current package/API details, event fields, and delivery behavior in the provider docs. |
| UsePDFMaker | Asynchronous conversion can POST a signed event to a supplied callback URL; raw-body handling matters. | Confirm current signature specification, event schema, and acknowledgment rules. |
| RelayPDF | Endpoint management, job and wallet events, timestamp/raw-body HMAC verification, and job.completed/job.failed. |
Confirm identifiers, PDF retrieval, and current retry/timeout behavior. |
For a production integration, compare the official Node verification support, the exact asynchronous job events and identifiers, the documented timeout/retry contract, and how the PDF is retrieved or stored. A provider’s webhook endpoint-management feature can also affect how you register, rotate, or disable callback destinations.
Troubleshoot common receiver failures
Every signature check fails
- Likely cause: JSON middleware parsed the body first, the wrong secret is configured, or the implementation used another provider’s header or signing formula.
- Fix: Confirm the route receives the original body as a Buffer or required raw string, verify the secret source, and follow the provider’s exact current SDK/API example.
The request body is undefined or not a Buffer
- Likely cause: The route’s parser did not match the incoming content type, or another middleware handled the request first.
- Fix: Check the provider’s actual content type and register the route-specific raw parser before the general JSON parser. Keep the accepted type narrow enough to avoid parsing unrelated requests.
Valid callbacks receive an error response
- Likely cause: The handler assumes a different event name or payload shape, or it rejects an unfamiliar event.
- Fix: Compare the verified event with the provider’s current schema. Decide how to acknowledge unknown event types according to the documented delivery contract, and log a safe event identifier/type for diagnosis.
The provider reports delivery timeouts
- Likely cause: The route waits for slow PDF retrieval or other downstream work before responding.
- Fix: If the provider permits it, persist or enqueue verified work and return the required success response without waiting for long-running processing. Use the provider’s documented timeout and retry instructions.
A job is processed more than once
- Likely cause: The sender retried after a timeout or the endpoint received a duplicate delivery.
- Fix: Apply idempotency using a documented delivery/event ID where available and store a durable processing state before performing non-repeatable side effects.
Large or unexpected payloads exhaust resources
- Likely cause: The route accepts unbounded request sizes or attempts to process an unexpectedly large body synchronously.
- Fix: Set a deliberate raw-body size limit compatible with the provider’s documented payload maximum, reject oversized inputs, and move expensive work out of the request handler when allowed.
Performance, reliability, and cost considerations
The receiver’s main latency cost is often not signature verification but downstream work: database writes, PDF downloads, file conversion, and notifications. Keep the synchronous path focused on verification, input validation, durable recording or enqueueing, and the provider-required response. This improves the chance of meeting the sender’s delivery window, but it does not substitute for checking that provider’s specific timeout and retry guarantees.
Reliability depends on two sides of the integration: the sender’s documented delivery behavior and your own idempotent processing. Record enough operational information to diagnose failures—such as event type, job ID, delivery ID when supplied, verification outcome, and processing state—without writing secrets or unnecessary personal data to logs.
Webhook receipt itself does not establish a universal cost model. PDF generation and delivery charges depend on the selected service’s plan and usage terms, which are not standardized by webhook implementation. Likewise, no cross-provider performance benchmark or common retry guarantee is established here; use the chosen provider’s published terms and your own workload measurements.
Or skip the browser setup
If your task is to capture web pages rather than generate PDFs from application data, ScreenshotNeo is a separate website screenshot API and MCP server, not a PDF-generation webhook provider. Its one-call API can return an image or PDF; cookie/consent banners are accepted like a visitor and more than 60 known consent platforms, newsletter popups, and chat widgets can be removed before capture, with each step configurable. Bot checks, blank pages, failed loads, timeouts, and cache hits cost nothing, and responses identify page verdict and billing status. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for AI agents using Claude, Cursor, or another MCP client. See ScreenshotNeo and the API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo includes 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000. Sign up free for ScreenshotNeo.
Frequently Asked Questions
Can I use `express.json()` on the rest of my application?
Yes. Register the webhook route with its raw-body parser before general JSON middleware, or explicitly exclude that route from JSON parsing.
Are `job.completed` and `job.failed` standard PDF webhook event names?
No. RelayPDF documents those names; other providers define their own event types and payload schemas.
Free tools Windows power users keep installed
One-click scans. No signup required.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

