A webhook is just an automatic message we send the instant something happens to one of your leads — someone registers, books a call, RSVPs, attends a webinar, becomes a client. Instead of you checking the portal, your tools find out on their own and can act immediately.
What people actually use this for: adding every new lead to their CRM automatically · texting or emailing someone the second they book · starting a follow-up sequence when a lead doesn't attend · alerting the team in Slack when a lead converts.
You don't need a developer for this. If you can use Zapier or Make, you can set this up. There's a developer reference at the bottom, but you can safely ignore it.
How it works, in one line
You give us a web address, we send lead events to it. That address usually comes from Zapier or Make — they hand you one to paste.
Step 1 — Get an address to send to
Pick whichever tool you already use. Each gives you a URL to copy.
Zapier — create a new Zap and choose the trigger Webhooks by Zapier → Catch Hook. Zapier shows you a "Custom Webhook URL." Copy it. (Heads up: Webhooks by Zapier needs a paid Zapier plan.)
Make — create a scenario, add the Webhooks module → Custom webhook → Add, give it a name, and copy the address it generates.
GoHighLevel — create a workflow with the Inbound Webhook trigger and copy its URL.
n8n — add a Webhook node and copy its Production URL.
The address must start with https.
Step 2 — Tell us where to send
In your portal, go to Account → Webhooks and use Add an endpoint:
Paste the address you just copied.
Tick the events you want (start with just one or two — you can change this later).
Click Create endpoint.
Copy your signing secret somewhere safe. It's shown once. You only need it if a developer is verifying our messages — if you're using Zapier or Make, you can ignore it.
Step 3 — Send a test and see the data
This is the step people skip, and it's the one that makes everything else easy.
In Zapier or Make, put the webhook step into "listening" mode, then come back to the portal, open Recent deliveries, and click Resend on any past event. Your tool will catch it and show you every field we send. From there you just drag those fields wherever you want them — into your CRM, an email, a Slack message.
If nothing has happened yet and the list is empty, tick lead.created and wait for your next registration.
Step 4 — Build the rest of your automation
Once your tool has caught one event, add whatever comes next: create the contact in your CRM, send a notification, start a sequence. Turn it on and you're done.
What you can be notified about
Event | When it fires |
| A new lead comes in |
| The lead books a consultation |
| The lead becomes a client (includes the deal value) |
| Your team rates the lead's quality |
| The lead is qualified, confirmed, or declined for an event |
| The lead responds to an RSVP (confirmed or declined) |
| The lead attends (or partially attends) a webinar |
| The lead registered for a webinar but did not attend |
| New enrichment data becomes available for the lead |
| The lead opts out of SMS |
Tip: only tick what you'll actually use. It keeps your automations cheaper and easier to follow.
What's in each message
Every event includes the lead's name, email, phone, which event they registered for, and the date — plus their form answers and Catchlight data when we have it. In Zapier or Make these show up as fields you can pick from a list; you don't need to read the format below unless you want to.
A few worth knowing:
custom_fields — the lead's own answers from your registration form, exactly as submitted.
catchlight — their Catchlight profile (score, income and asset ranges), when available.
conversion_value — on
lead.converted, what the client is worth.Anything that doesn't apply to a lead yet comes through empty.
Managing your endpoints
Reveal / Copy / Rotate the signing secret any time. Rotating breaks the old one immediately, so update your receiver right after.
Disable / Enable to pause and resume delivery — useful while you're rebuilding an automation.
Delete an endpoint you no longer need.
Recent deliveries shows what we've sent, whether it worked, and a Resend button.
If something isn't working
Nothing is arriving — check the address starts with
httpsand was pasted in full, and that the endpoint isn't disabled. Then hit Resend and watch your tool.It says pending — normal for a minute or two. Click Refresh.
It says failed — your receiver didn't accept it. In Zapier/Make, make sure the webhook step is turned on and the Zap/scenario is published.
It stopped working — an endpoint that keeps failing is switched off automatically. Fix the receiver, then re-enable it here.
The same event arrived twice — that can happen when we retry. Your tool should treat a repeat of the same event id as a duplicate.
Good to know
Addresses must be HTTPS. Private or internal addresses are blocked.
You only ever receive your own company's lead events.
Keep your signing secret private.
Want to send data to us instead — booked calls, conversions, attendance? See Sending Us Your Conversion Data.
Developer reference
Everything below is optional. If you're using Zapier or Make, you can stop here.
The payload
Every webhook is a JSON POST with the same envelope; data holds the lead:
{ "id": "evt_a013abbeecfd44cb8...", "type": "lead.created", "occurred_at": "2026-07-19T03:22:43Z", "company_id": "CID-XXXXXX", "data": { "lead_id": "785138da-f81c-4579-a63c-c2d591d31f20", "name": "Jane Sample", "first_name": "Jane", "last_name": "Sample", "email": "[email protected]", "phone": "(555) 123-4567", "event_type": "webinar", "event_title": "Taxes In Retirement", "event_date": "2027-05-25", "event_time": "6:00 PM", "event_topic": "Taxes In Retirement", "created_at": "2026-07-19T03:22:43Z", "registration_outcome": null, "call_scheduled_at": null, "converted_at": null, "conversion_value": null, "quality_rating": null, "sms_opted_out_at": null, "ac_tags": ["Webinar: Elder Law", "Web Elder Law 07.27.26"], "enrichment": {}, "catchlight": { "catchlight_score": "47", "income_range": "$250,000 - $499,999", "investable_assets": "$1,000,000 - $3,499,999" }, "custom_fields": { "what_is_your_biggest_concern_for_retirement": "Running out of money" } }}
ac_tags lists the tag names on that lead's ActiveCampaign contact — your event tags (e.g. Web Elder Law 07.27.26) and any other tags on the record (Webinar: Elder Law, SMS Follow Up). It is always an array: [] means we haven't read tags for that lead yet, or the contact has none. Tag names come through exactly as they are spelled in ActiveCampaign.
lead.rsvp also includes rsvp_status and rsvp_response_at. lead.webinar_attended and lead.webinar_no_show both include an attendance object (whether they attended, a status such as "completed", "left early" or "did not attend", and the session).
Headers
Header | Value |
| Unique event id (matches |
| Unique id for this delivery attempt — use it to ignore duplicates |
|
|
|
|
|
|
Verifying the signature
X-EDM-Signature is sha256= followed by the HMAC-SHA256 of the raw request body, keyed with the endpoint's signing secret, hex-encoded. Compute it and compare. Hash the raw body exactly as received — don't parse and re-serialize the JSON first, or it won't match.
// Node.jsconst crypto = require('crypto');const expected = 'sha256=' + crypto.createHmac('sha256', SECRET) .update(rawBody) .digest('hex');// compare `expected` to the X-EDM-Signature header
Retries
Reply with a 2xx. If you don't, we retry with increasing delays, up to 6 attempts.
Because of retries the same event can arrive twice — dedupe on
X-EDM-Deliveryor the body'sid.Persistently failing endpoints are disabled automatically; re-enable in the portal.
Resend replays the original saved payload.
Need a hand? Start a chat from the portal — tell us which tool you're connecting and we'll walk you through it.



