Webhook Intake
Outcome: submissions creating rows within seconds, with duplicate protection, validation at the boundary, and a tested failure path.
- Surface
- Sync GTM app
- Level
- Advanced
- Uses
- Webhooks
- Credits
- 0
- Prerequisite
- Lesson 02's source inventory
Why webhooks rather than a sync
A scheduled sync introduces its own delay on top of everything else. A fifteen-minute sync means the average lead waits seven and a half minutes before your pipeline even starts — before enrichment, scoring, routing or a rep.
A webhook fires on submission. The row exists in seconds.
Given that the whole point of this course is speed to lead, that difference is not a detail.
Reference: Webhooks.
Mapping the payload
Capture the whole payload first
Before mapping anything, receive one real submission and look at it. Forms send more than the visible fields — hidden fields, UTMs, page context, sometimes a submission ID.
Map the core
Email, source, timestamp. These are required and the row should be rejected without an email.
Map the optional fields you have
Name, company, phone, message, UTMs.
Store the raw payload
Always. Fields get added upstream without anyone telling you.
Idempotency
Webhooks retry. A delivery that times out on your side may have succeeded, and the sender will send it again.
Without protection, one submission becomes three rows, three enrichments and possibly three follow-up emails to the same person.
| Approach | How |
|---|---|
| Submission ID | Best, where the source provides one. Dedupe on it. |
| Email + timestamp window | Same email within a few minutes is one submission |
| Email + form + rounded timestamp | Workable composite key |
Duplicate follow-up emails to the same person within minutes are visible and embarrassing in a way duplicate rows are not. Build idempotency before you connect the follow-up in lesson 08 — not after the first incident.
Validate at the boundary
Reject or quarantine before the row enters the pipeline.
| Check | Action on failure |
|---|---|
| Email present and syntactically valid | Reject, log |
| Email is not disposable | Quarantine |
| Not an obvious bot submission — all fields identical, nonsense strings | Quarantine |
| Not already suppressed or unsubscribed | Route to existing-contact path, not the new-lead path |
| Source is recognized | Quarantine unknown sources rather than dropping them |
Quarantine rather than delete. A quarantined row can be reviewed; a deleted one cannot, and a legitimate lead misclassified as a bot is a real cost.
Test properly
Send a real submission
Fill in the form yourself. Confirm the row appears and every field mapped.
Send a malformed one
Missing email, empty payload. Confirm it is rejected cleanly rather than creating a broken row.
Send the same one twice
Confirm idempotency holds.
Simulate a failure
Temporarily break the endpoint and confirm the source retries and the retry is handled.
Check the timing
From submission to row created. That number is the first line of your speed-to-lead budget.
Do this now
Create the endpoint and capture one raw payload
Map core and optional fields
Keeping the raw payload.
Build the idempotency key
Submission ID where available.
Add boundary validation
With quarantine rather than delete.
Run all five tests
Record the intake latency
Add an alert on zero submissions
Per source, over a period where you would expect some.
Check your work
- A real submission creates a correctly mapped row
- A malformed payload is rejected without creating a broken row
- A repeated delivery does not create a second row
- Quarantine exists and is reviewable
- You have measured intake latency
Where this breaks
A webhook that starts failing produces no error anyone sees — leads simply stop arriving, and the pipeline reports a quiet period rather than an outage. Because inbound volume is naturally variable, this can go unnoticed for days. Alert on zero submissions from any source that normally produces some, and treat the alert as a page rather than a note.
Further automation
Chain the webhook straight into enrichment so the row is complete before anyone looks at it. The whole value of second-level intake is lost if the enrichment then waits for a batch — lesson 04 runs on arrival, not on a schedule.
Next lesson
04 — Enrich on arrival, turning an email into a full profile in seconds.
Reference for this lesson: Webhooks, Import, API keys, Actions.