Webhook delivery handling
Acknowledge a webhook after you can recover it
Keep the receiver short, but do not return success before accepted work is durable. Separate delivery receipt from the business effect that follows.
In this article
The dangerous gap is small
A receiver verifies a webhook, starts an unawaited background task and returns success. The process exits before the task is stored anywhere. The provider believes delivery succeeded, while the application has no record to process.
The response should mean something precise. For an asynchronous receiver, it normally means the verified event has been accepted into a durable path, not that every downstream action is complete.
If durable acceptance fails, use the provider's documented response and retry behaviour rather than claiming success. Providers differ in their retry policies, so a receiver also needs an appropriate recovery or reconciliation route.
Verify the provider's contract
Use the supported signature verification mechanism with the request representation it expects. Stripe, for example, requires the unmodified raw request body for signature verification.
Verification establishes the request's authenticity under that mechanism. The application must still check event type, account context and the business operation it is willing to perform.
- Incoming requestBound size and verify the provider signature
- Durable receiptStore event identity, scope and processing state
- AcknowledgementConfirm accepted delivery using provider semantics
- Worker outcomeApply the effect and record completion or recovery state
Expect duplicates and delayed delivery
A provider may retry because it did not receive the acknowledgement even though the receiver stored the event. Use the provider's event or delivery identity according to its contract, scoped to the relevant source and account.
Deduplicating receipt is not enough if the worker can perform an external effect and crash before recording completion. Protect the business operation at its own boundary through transactional state, idempotent requests or reconciliation as appropriate.
Keep transport identity distinct from business identity. Two different events can describe changes to the same resource, and those changes may each require processing.
Decide how ordering works
Do not assume arrival order equals business order unless the provider explicitly guarantees it for the relevant scope. A delayed older event can otherwise overwrite a newer state.
Choose whether the worker applies a versioned transition or uses the event as a signal to fetch current authoritative state. The latter suits some projections but cannot recreate history that the current resource no longer exposes.
Make failures recoverable
Record rejected, unsupported and failed processing states with bounded diagnostics. Keep sensitive payloads protected and retain only what the recovery policy requires.
Test crashes at receipt and effect boundaries. The design is dependable when every acknowledged event has a recoverable path and every repeated attempt preserves the intended business outcome. A fast successful HTTP response alone establishes neither property.
Primary sources
Stripe: webhook handlingGitHub: webhook best practicesReferences checked 11 September 2026.