# API Webhook Reliability: Handle Retries Without Duplicates

> Design reliable API webhooks with signature checks, durable receipt records, idempotent processing, retry handling and reconciliation evidence.

- URL: https://weaveward.com/blog/api-webhook-reliability
- Published: 2024-04-23
- Updated: 2026-10-12
- Category: Business Systems
- Tags: webhooks, idempotency, system integration
- Author: Weaveward Team

Webhooks let one system notify another when something happens, such as a payment completing or an order changing. Their simplicity can hide an important reliability problem: the sender may retry a notification, the receiver may fail after doing part of the work, and events may arrive in an unexpected order.

[Stripe's webhook documentation](https://docs.stripe.com/webhooks) explicitly discusses duplicate deliveries and ordering. [Cloudflare Queues](https://developers.cloudflare.com/queues/reference/delivery-guarantees/) similarly documents at-least-once delivery. These are reasons to design for repeated processing, rather than assume that a successful network request makes an entire business operation occur exactly once.

## Authenticate and record receipt first

Verify the sender's signature using its documented procedure, including the correct raw request bytes where required. Apply a body limit and reject events that the integration does not support. A secret URL alone is a weak basis for accepting financial or inventory updates.

Persist an inbox record with a stable event identifier, source, event type, receipt time and processing state. Acknowledge only after the event is durably accepted. If the database write fails, the sender should receive a failure response so its retry mechanism can operate.

## Make the business effect idempotent

Idempotency means applying the same intended operation again does not create another business effect. A unique event ID can prevent repeated handling of one delivery, but some providers can create different event objects about the same underlying transition. Decide which business key identifies the effect you want to perform.

For a hypothetical payment-to-order integration, use the payment reference and transition type to guard the creation of a paid-order record. Store that guard and the resulting update in one transaction where possible. Writing the guard before the order update, without an atomic boundary, can incorrectly mark incomplete work as finished.

## Worked example: a timeout after payment processing

An event reports that payment P-104 is complete. The receiver creates the order's fulfillment request, but its response is lost. The provider sends the event again. Without a guard, the warehouse could receive two pick requests for the same paid order.

With an inbox and a unique fulfillment key, the second worker sees that the effect already exists. It returns success without issuing another pick request. If the original worker crashed before the transaction completed, the retry can safely perform the remaining operation.

An external fulfillment API complicates this boundary. Use the provider's idempotency mechanism where available, and keep an outbound-operation record. If a timeout leaves the result uncertain, reconcile by the business key instead of blindly repeating an irreversible action.

## Handle ordering and recovery explicitly

A refund event can arrive before the local system has processed an earlier payment event. Compare the current source state or use supported object versions rather than infer sequence solely from arrival time. Define transitions that are allowed and those that need reconciliation.

Separate receipt from expensive processing when traffic justifies it. A durable queue can absorb bursts, but requires retry policies, dead-letter handling and an owner for failed items. Display pending, failed and reconciled counts rather than a single green integration badge.

## Test failure paths before launch

Send the same event twice, process two copies concurrently and interrupt the worker between each persistence step. Test an invalid signature, an unsupported event and a provider outage. Confirm that replay tools preserve the same idempotency boundaries as normal processing.

Finally, compare source totals with local totals on a schedule. Webhooks are a notification mechanism, while reconciliation is the evidence that the resulting business state is complete and correct.

## Primary references

- [Stripe: Webhook delivery and handling](https://docs.stripe.com/webhooks)
- [Cloudflare Queues: Delivery guarantees](https://developers.cloudflare.com/queues/reference/delivery-guarantees/)

## Related reading

- [Business API integration planning](/blog/api-integration-guide)
- [Multi-warehouse inventory synchronization](/blog/multi-warehouse-inventory-sync)

Plan dependable integrations with our [business systems service](/services/business-systems).
