Autype
Back to blog

Updated October 27, 2026

Reliable Document Jobs: Webhooks, Reconciliation, and Preventing Duplicate Sends

The PDF is ready, but its webhook never arrived. Learn to separate rendering, storage, and dispatch, reconcile uncertain outcomes, and retry safely—with a proposal example and failure tests.

Document AutomationTutorials#Autype#webhooks#document automation#PDF API#reconciliation#idempotency#n8n

Your PDF is ready, but its completion notification never reaches your workflow. Or the connection drops just as the API accepts the request. Rendering again might create a second file and send the same proposal twice. Reliable document automation therefore starts before the retry button: which business request belongs to which job, and what has already happened?

The n8n 3.0 beta announcement on October 27, 2026 puts reliability, stability, and security at the center of workflow operations. It is a useful prompt to review existing PDF pipelines too. This guide is not a migration walkthrough and does not require n8n 3.0. It presents a transferable operating pattern for Autype: process notifications quickly, reconcile uncertain outcomes, and repeat only the step that actually needs repeating.

Three successes worth recording separately

Consider a sales team. Once a proposal is approved, the system should generate a PDF, store it in the company's repository, and send it to the customer once. A green HTTP step is not enough to prove that sequence succeeded.

LayerWhat success meansWhat it does not prove
Request acceptedA render job was createdThe PDF is finished
Document generatedThe job reports COMPLETEDThe file has been stored durably
Proposal deliveredThe sending service confirms dispatchThe customer has read it

Separating these outcomes prevents a common mistake: a failed email step should not automatically trigger document generation again. Give rendering, storage, and dispatch their own receipts. Choosing an integration interface is a different question; see the MCP versus REST API comparison for that decision.

1. Create a small request ledger

Before calling the render API, save a business identifier such as PROP-2026-1042, the approved content revision, and the requested output format. After a successful API response, attach the returned job ID. A later webhook can then be connected to a particular proposal rather than an anonymous execution.

Useful ledger fields include business ID, revision, job type, job ID, last observed status, stored output location, and dispatch receipt. Add timestamps and a short error classification. Do not put API keys or complete personal document contents into general execution logs.

For business-level deduplication, consider proposal plus approved revision plus output format. A changed revision becomes a new request; another trigger for the same revision does not. This is an application design recommendation, not a claim that Autype provides a built-in API idempotency key. If two workers can start concurrently, enforce uniqueness in the underlying store, for example with a database uniqueness constraint. Checking a flag and then writing it in a separate operation is not sufficient protection against that race.

2. Treat webhooks as signals, not your only record

Autype documents jobs for asynchronous operations, with webhooks and polling as the two ways to observe completion. Reusable signed endpoints are configured in Engine → Integrations and are the recommended default. Per-request webhook settings remain available with a different authentication contract.

The operational detail that matters most is delivery behavior: the documentation specifies a single delivery attempt with a ten-second timeout. An unreachable receiver or a non-2xx response does not trigger another webhook delivery. Failed notification delivery does not undo the render job.

Your receiver should therefore authenticate the message, persist it for processing, and respond promptly. Put longer work such as downloading, malware scanning, and email dispatch into a separate worker. Do not acknowledge success before the handoff to your own durable storage has actually completed. Otherwise, a crash between acknowledgment and persistence silently loses the event.

This design does not depend on webhooks being delivered more than once. Deduplication still matters because your own queue, replay tools, or recovery worker may process the same completion again.

3. Verify signed messages before acting on them

For reusable endpoints, Autype describes an Autype-Signature header containing a timestamp and signature. Verification uses HMAC-SHA256 over timestamp.rawBody: the timestamp, a period, and the unchanged request body. Parsing the JSON and serializing it again can change the bytes, so it is not an equivalent input.

Compare signatures using a timing-safe operation and reject stale timestamps according to your replay window. The documentation gives five minutes as a common starting point. Keep the signing secret in secret storage. It is shown once when the endpoint is created and is not returned by list endpoints afterward.

That signature contract does not automatically apply to per-request webhooks. For those, verify the configured custom header or Basic Auth instead. Keep the two authentication modes distinct. A believable-looking job.completed payload without valid authentication must never be enough to send a customer document.

4. Reconcile missing notifications using the job ID

A scheduled reconciliation task looks for open ledger entries that have exceeded their expected processing time. It checks the known job rather than immediately creating another render request. The documented relative status paths depend on the job type:

Job typeStatus lookupAction after success
RenderGET /render/{jobId}Retrieve and store the output
Bulk renderGET /bulk-render/{bulkJobId}Check counts and individual results
ToolsGET /tools/jobs/{jobId}Handle the file or business result

Resolve these paths against the Developer API base configured in your integration. A tools result does not necessarily contain a downloadable file, another reason to persist the job type. The API documentation explains the different response shapes.

A connection failure before you receive a job ID creates a different problem: you do not know whether the creation request was accepted. Mark that request as uncertain and reconcile it against available history. If no reliable association is possible, escalate the case. Blindly repeating creation is not a defensible duplicate-prevention strategy.

5. Store the file before declaring the request complete

A download link is not an archive. Autype documents a one-hour retention window for render output files. Signed download URLs have their own expiry and do not extend the output file's lifetime. Download completed outputs promptly into your intended repository.

Check the download response, expected file type, and that the file is not empty. Store it at a deterministic destination for the proposal and revision. Record the storage receipt and optionally a checksum in the ledger. Only then should the request count as archived.

If a link expires while the output file still exists, another status lookup may provide a usable link. Once the output has been cleaned up, the documentation says a new render is required. Treat that as deliberate recovery, not a free extension of link lifetime. For larger input sets, the bulk generation guide covers preparation of the underlying records.

6. Retry the failed step, not the entire chain

ObservationAppropriate next actionDangerous shortcut
No webhook, known job IDLook up job statusCreate another render
Stored file, failed emailResume dispatch separatelyGenerate the PDF again
Completion processed againRecognize the stored stateSend another email
API returns 429Back off and bound requestsRetry in a tight loop
Creation outcome uncertainReconcile history or escalateGuess success or failure

Dispatch deduplication belongs in your application. Even an authenticated webhook does not guarantee exactly-once email delivery. A timeout at the sending provider can create another uncertain outcome. Use its message ID, status lookup, or idempotency facility where available, and keep the dispatch receipt separate from the render receipt.

Avoid treating every error as transient. Invalid document content needs correction, while an expired file may require a deliberate regeneration decision. A retry policy should state both which errors qualify and when automatic recovery stops.

An acceptance test with four deliberate failures

Before going live, test more than the happy path. Temporarily make the webhook receiver unavailable: reconciliation should still discover the completed proposal. Process a stored event twice: no second dispatch should follow. Interrupt a file download: the ledger must not report successful archiving. Finally, simulate a sending failure after storage succeeds: only dispatch should resume.

Track open requests without progress, time to durable storage, and uncertain outcomes. Set warning thresholds comfortably inside the documented file retention window. Do not let an overnight reconciliation schedule discover a missing download after the output is already gone.

The most reliable document workflow is not the one with the most retries. It is the one that can explain what has happened after an interruption, locate the evidence, and choose the smallest safe next action.

Sources

Autype: Webhooks & Job Status — https://docs.autype.com/api-reference/webhooks.md — accessed October 27, 2026.

Autype: Rate Limits & Quotas — https://docs.autype.com/api-reference/rate-limits.md — accessed October 27, 2026.

n8n: Introducing n8n 3.0 — https://blog.n8n.io/introducing-n8n-v3/ — published and accessed October 27, 2026. Context for the reliability focus, not a template for the workflow design.

Ready to automate your documents?

Start creating business documents with Autype. No credit card required.