One lead, two webhook deliveries: prevent duplicate follow-up
Design a Make webhook workflow that recognizes repeated submissions, records uncertain outcomes and tests recovery before it sends a second customer message.
This sheet contains partner links. A purchase through one earns Runbook a commission at no additional cost to you. How we make money.
Your form delivered the same lead twice. The CRM still shows one contact, so the test looks successful. Then the customer receives two welcome messages.
Contact matching and event deduplication solve different problems. Matching asks whether this person already exists. Deduplication asks whether you already acted on this particular submission. You need both when a repeated delivery can trigger customer-facing work.
This is a documentation-based design and acceptance-test plan, checked October 4, 2026. It is not a claim that we ran this workflow in a production account. Build it against a test destination first.
Give every submission an identity
Start with the form provider's stable submission ID. Preserve it when the sender retries. Prefix it with the form or source so two systems cannot accidentally reuse the same key.
Use website-quote:submission-123 as a test example. Do not use the email address alone: one person may legitimately submit a new request next month. Do not create a fresh random ID on every delivery, because that makes each retry look new.
The same problem appears in payment systems. Stripe's webhook documentation explicitly warns that events can arrive more than once and recommends recording processed event IDs. That establishes the failure pattern; it does not mean every form provider has Stripe's retry rules. Check your sender's rules separately.
If the source has no stable ID, solve that at the source or agree a documented business rule before automating follow-up. A guessed timestamp-and-email key can either miss duplicates or suppress a real inquiry.
Build the event register
Use a durable store that survives workflow restarts. For a small, single-scenario prototype, Make's Data stores provide records with keys. Keep sensitive lead details in the CRM where possible; the event register mainly needs identifiers and status.
| Field | Purpose |
|---|---|
event_key | Stable identity for this submission |
payload_fingerprint | Detects changed content arriving under the same key |
state | processing, completed, failed, or needs_review |
crm_record_id | Identifies the contact already written |
followup_state | not_started, confirmed_sent, or uncertain |
provider_message_id | Reconciles a message with the sending system |
updated_at | Helps find stuck runs |
The fingerprint should cover the fields that define the action. If an existing event key arrives with materially different details, stop and investigate rather than silently overwriting the original request.
Process one event at a time
Make's webhook guide says instant webhook runs process in parallel by default. In scenario settings, its current documented control is Process data in order. Enable it for this small single-scenario design so a second run does not overtake the first.
Then wire this sequence:
- Receive and authenticate the request using the sender's supported method.
- Validate required fields and derive the stable event key.
- Look up the register before changing the CRM or sending anything.
- Stop a completed duplicate. Route an uncertain or still-processing event to review.
- Record a new event as
processing, then write or update the CRM record. - Perform the permitted follow-up once, recording the provider's result.
- Mark the event
completedonly after the required actions have confirmed outcomes.
This ordering setting protects this scenario's runs. It is not a global lock across other scenarios, imports or services. If several workers can act on the same event, use a store with an atomic unique-key claim and transactional state handling. A separate “check then insert” across concurrent workers can race.
For the receiving layer, start with our Make webhook setup. Keep permissions for follow-up separate from the event key; a unique submission is not permission to send every kind of message.
Treat a timeout as an unknown result
The awkward case is a successful send followed by a network timeout. Your workflow sees an error, but the customer may already have the message.
If the destination supports idempotency keys, use the same stable action key for a retry and follow that provider's retention rules. Stripe documents this behavior for its own API; other APIs require their own verified implementation.
If the messaging destination offers neither idempotent sends nor a reliable lookup, set followup_state to uncertain. Alert the operator and reconcile with the provider before resending. Do not automatically restart the entire workflow. The CRM write and the message send have separate outcomes.
Run this acceptance test before enabling messages
Use an internal test inbox or a logging destination. These are expected results to verify, not reported test results.
| Test input or failure | Expected observable outcome |
|---|---|
| New valid submission | One event record and one intended action |
| Same submission delivered twice | One customer-facing action total |
| Same person, new submission ID | New inquiry handled under your business rules |
| Same key, changed payload | Review required; no silent second send |
| Failure before the CRM write | Visible failed state; controlled retry possible |
| Timeout after the destination accepted a message | Uncertain state; no blind resend |
| Two near-simultaneous deliveries | One effect, including under the concurrency setup you actually use |
For rollback, disable the customer-facing action and keep receiving into a safe queue or log. Preserve event records for the source's retry and replay window; do not clear them simply to make a test run green.
You can extend the lead-to-CRM build after these checks pass. The success condition is one intended business action per submission, plus a recoverable record when the outcome is uncertain.
About Runbook
AI tools and automation builds for marketers. What to use, how to wire it, and the workflow to copy this week. How we work
GET THE NEXT DISPATCH
Run the next build before your competitors read about it.
One short email when an AI tool or automation actually changes the work, with the build to copy.
No send unless there is a build worth running.
// keep_reading
Related builds

Make webhook setup: capture leads in 45 minutes
Follow this Make webhook setup to catch website leads instantly, validate each submission, block bad requests, and test the handoff safely.

n8n vs Make: which automation tool fits your business?
n8n vs Make compared on cost, setup, maintenance, and one real lead-routing build. Choose the right automation tool before moving your workflows.

Zapier alternatives for automation in 2026
Zapier is easiest to start, but Make, n8n and GoHighLevel can be cheaper or cleaner for the right automation job.