Skip to content
AutomationTutorial

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.

RunbookOctober 4, 20265 min read
~/runbook $ cat make-com.md[tutorial]
>_// Automation
45 lines · automation.md0x613b

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.

FieldPurpose
event_keyStable identity for this submission
payload_fingerprintDetects changed content arriving under the same key
stateprocessing, completed, failed, or needs_review
crm_record_idIdentifies the contact already written
followup_statenot_started, confirmed_sent, or uncertain
provider_message_idReconciles a message with the sending system
updated_atHelps 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:

  1. Receive and authenticate the request using the sender's supported method.
  2. Validate required fields and derive the stable event key.
  3. Look up the register before changing the CRM or sending anything.
  4. Stop a completed duplicate. Route an uncertain or still-processing event to review.
  5. Record a new event as processing, then write or update the CRM record.
  6. Perform the permitted follow-up once, recording the provider's result.
  7. Mark the event completed only 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 failureExpected observable outcome
New valid submissionOne event record and one intended action
Same submission delivered twiceOne customer-facing action total
Same person, new submission IDNew inquiry handled under your business rules
Same key, changed payloadReview required; no silent second send
Failure before the CRM writeVisible failed state; controlled retry possible
Timeout after the destination accepted a messageUncertain state; no blind resend
Two near-simultaneous deliveriesOne 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