Assume every webhook can arrive more than once. Verify the request, atomically record that you have accepted it, acknowledge only after that record or a durable queue entry exists, and make each business side effect safe to retry. A delivery ID, an event ID, and an idempotency key are not interchangeable: choose the identity that matches the operation you need to protect.
Why webhook duplicates happen
A sender may retry when it does not receive a successful response in time, even if your application already started processing the event. A timeout can leave both sides uncertain: the sender cannot know whether your work completed, and your receiver may not know whether the sender will try again. Shopify explicitly identifies network timeouts and retries as reasons an app may receive the same webhook more than once (Shopify: Verify webhook deliveries).
| # | Preview | Product | Price | |
|---|---|---|---|---|
| 1 |
|
APIs and Webhooks for Beginners: Connect Apps, Automate Tasks, and Build Useful Integrations | $2.99 | Buy on Amazon |
| 2 |
|
Shelly Pro 3EM 3CT 63 Wi-Fi & LAN 3-Phase Smart Energy Meter | $150.99 | Buy on Amazon |
As an Amazon Associate I earn from qualifying purchases.
Design around that uncertainty rather than trying to prevent every repeat delivery. A duplicate should either be recognized as already accepted or processed again without repeating the underlying business effect.
Recommended Free Tools
Choose the right identity for deduplication
Before building a deduplication check, decide what “the same” means for the operation. A delivery ID identifies a delivery attempt or message; an event ID may correlate deliveries representing the same underlying action; a business key identifies the operation your system must not repeat, such as applying a particular payment or order change. The sender’s semantics matter, so do not assume that every redelivery keeps the same identifier or that distinct subscriptions use distinct event IDs.
#1 Best Overall
Shopify documents two different identifiers: X-Shopify-Webhook-Id identifies a delivery, while X-Shopify-Event-Id can correlate separate deliveries caused by the same merchant action, including deliveries across subscriptions. GitHub’s X-GitHub-Delivery identifies a delivery, and a requested redelivery retains its original value. See the providers’ guidance for the exact scope of each identifier: Shopify and GitHub.
- Use a delivery ID when the goal is to avoid handling the same provider delivery twice.
- Use an event ID when the provider documents that it represents the underlying event across deliveries and that matches your business rule.
- Use a business-level key when separate events or subscriptions could still trigger the same logical operation. Define its scope carefully so legitimate distinct operations are not suppressed.
Build a receiver that can safely accept repeats
- Verify authenticity before changing business state. Follow the sender’s signing instructions. For Shopify HMAC verification, preserve the raw request body and verify it before parsing JSON; parsing changes the bytes used for verification (Shopify verification guidance).
- Claim the chosen identity atomically. Store a durable processing record in a database or equivalent durable system, protected by a unique constraint or atomic claim. An in-memory “seen it” set can disappear on restart and cannot reliably arbitrate simultaneous deliveries.
- Persist enough state to recover. Track whether work is accepted, processing, completed, or failed, along with the identity and any information needed to resume. If the worker crashes, this record should let the system distinguish unfinished work from an operation already completed.
- Acknowledge after durable acceptance. Return success only after the record is committed or a durable queue has accepted the job. If the work may outlast the provider’s response deadline, enqueue it and let a worker process it asynchronously. The deadline is provider-specific.
- Make the business effect repeat-safe. A handler-level dedupe record does not protect a downstream call if the process crashes after that call succeeds but before completion is recorded. Use the downstream service’s idempotency feature where available, and reuse the same key and request parameters when retrying the same logical operation.
- Record the outcome. Mark completion only when the intended effect has succeeded. Record failures and enough diagnostic context to decide whether to retry, repair, or escalate.
The durable claim and processing states are implementation guidance for handling documented repeat deliveries and failures, not a universal schema prescribed by every webhook provider. Choose transaction boundaries and recovery behavior to fit your storage system and side effects.
Use downstream idempotency for retried API calls
Webhook deduplication and API idempotency solve related but different problems. The former controls what your receiver does with incoming deliveries; the latter controls what a downstream API does when your application retries a request after an uncertain result.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated 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 matchStripe documents idempotency keys for safely retrying API requests. It stores and replays the first result for a key, checks that repeated requests use consistent parameters, and may prune a key once it is at least 24 hours old. After a key has been pruned, reusing it can create a new request rather than replay the old result. Those rules are Stripe-specific, not a general webhook standard; see Stripe’s idempotent requests documentation and Stripe’s error guidance. Shopify likewise documents that idempotency mechanics depend on the API, so do not assume one token format or retention period across its APIs (Shopify: Idempotent requests).
Rank #2
- The Shelly Pro 3EM 3CT 63 is a next-gen DIN rail-mountable energy meter for single or three-phase installations, featuring a 63A, 3-phase current transformer for non-contact measurements. It supports 4-quadrant measurement, optical pulse indication of energy usage, and is photovoltaic-ready. *It doesn't have a built-in relay; contactor control requires a Shelly Pro Addon attached to the device.
- Professional Smart Meter - Shelly Pro 3EM-3CT63 is a professional smart meter that reports accumulated energy, voltage, current, active, and apparent power per phase in real time. It stores data for up to 60 days in 1-minute intervals and includes a real-time clock to maintain accurate time if the SNTP server connection is lost.
- Ideal for business energy measurement - In commercial buildings, it helps monitor energy usage across floors or departments allowing accurate cost allocation and identification of energy wastage. In manufacturing plants it tracks energy consumption of heavy machinery, optimizing usage to reduce operational costs. For store owners it monitors energy usage of systems like lighting, HVAC § refrigeration, helping to identify inefficiencies § reduce energy bills while supporting sustainable practices
- Shelly Customer Service - Shelly is one of the fastest-growing Smart Home brands in the world with devices, providing solutions for the automation of private homes, buildings and businesses. We provide our customers with professional support and a 5 years device warranty.
- Shelly Smart Control App will help you control your Shelly devices remotely and will send notifications for all automated events in your home. You can easily configure devices and manage their settings individually, or you can create personalized scenes by combining Shelly devices to trigger certain actions in your home automation.
Use one stable key for retries of the same logical downstream operation, with the same parameters. Do not generate a fresh key for each retry: that would make each attempt look like a new operation to the API.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Provider rules differ: check the sender you actually use
The following figures and behaviors are from the providers’ current documentation as accessed on October 4, 2026. Retry schedules, deadlines, headers, and API behavior can change; verify the current documentation for the provider and API surface you integrate.
| Provider | Retry or response guidance | Identifiers and redelivery | Verification or idempotency detail |
|---|---|---|---|
| Shopify | The webhook delivery guidance says failed or unanswered deliveries are retried 8 times over the next 4 hours. This schedule is Shopify-specific (source). | X-Shopify-Webhook-Id identifies a delivery; X-Shopify-Event-Id can correlate deliveries from the same merchant action, including across subscriptions (source). |
For HMAC verification, retain the raw body before JSON parsing. Shopify’s idempotency mechanics vary by API (verification; API idempotency). |
| GitHub | GitHub recommends responding with 2XX within 10 seconds; it suggests queueing slow work for background processing. This is not a universal webhook deadline (source). | X-GitHub-Delivery helps identify deliveries; a requested redelivery retains the original value (source). |
The cited best-practices guidance does not state a downstream API idempotency-key retention period. |
| Stripe | The cited idempotency and error documentation does not establish a webhook retry schedule or webhook response deadline. | The cited API idempotency documentation concerns API requests, not a blanket identity rule for webhook events (source). | Stripe may prune an idempotency key once it is at least 24 hours old; a reused pruned key can result in a new request. This is Stripe API behavior, not a general retention rule (source). |
Recover from failures instead of relying only on provider retries
Provider redelivery is useful, but it is not a complete recovery system: retries may stop, and a successful acknowledgment can occur before business processing finishes. Keep an internal record of accepted work and its outcome, monitor jobs that remain incomplete, and distinguish transient failures from permanent ones so retries do not become an unbounded loop.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
- If the request fails verification, do not apply its business changes. Investigate signing configuration or malformed requests separately from processing retries.
- If durable acceptance fails, do not acknowledge success; allow the sender’s documented delivery behavior to apply and alert on the storage or queue failure.
- If a worker fails after acceptance, retry or resume from the stored state. Before repeating an external side effect, use the downstream idempotency mechanism when available or reconcile whether the prior attempt succeeded.
- If deliveries are missed or exhausted, inspect provider delivery attempts and responses, then use supported redelivery controls after service recovery. GitHub recommends redelivering missed deliveries after recovery; Stripe troubleshooting points operators to delivery-attempt status and responses (GitHub; Stripe).
For every integration, document the provider’s retry exhaustion behavior, acknowledgment deadline, identifier semantics, replay controls, signing requirements, and any downstream key scope or retention that affects recovery. Those details determine where your own queue, alerts, and reconciliation procedures must take over.
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.




