Custom Webhook (Developers)
Technical reference for receiving SNG Lead Recovery webhooks in your own system — or for mapping fields precisely in any automation platform.
Available from version 1.1.0
Integrations are available in SNG Lead Recovery 1.1.0 and newer.
Request
| Property | Value |
|---|---|
| Method | POST |
| URL | Your Webhook URL (https:// only), or the per-location URL for the lead's location |
| Content-Type | application/json |
| User-Agent | SNG-Lead-Recovery/{version} |
| Timeout | 10 seconds |
Headers
| Header | Value |
|---|---|
X-SNG-Event |
The event name, e.g. lead.abandoned |
X-SNG-Signature |
Only when a Signing Secret is set: sha256= + HMAC-SHA256 of the raw body (see Verifying Requests) |
Events
| Event | Sent when |
|---|---|
lead.abandoned |
A lead is marked Abandoned. Sent once per lead automatically. |
lead.completed |
The visitor finished the signup on their own. |
lead.recovered |
The visitor finished the signup after using their resume link. |
test |
An admin clicked Save & Send Test. Contains sample data with lead ID LR-000000. |
Each event can be switched off under Send Events in the settings (except test).
Payload
A flat JSON object:
| Field | Type | Description |
|---|---|---|
event |
string | Event name (see above) |
lead_id |
string | Unique Lead Recovery ID, e.g. LR-000012 |
status |
string | abandoned, completed, recovered, in_progress, or archived |
first_name |
string | First name from the onboarding form (may be empty) |
last_name |
string | Last name from the onboarding form (may be empty) |
name |
string | Full name (may be empty) |
email |
string | Email address, lowercased and trimmed (may be empty) |
phone |
string | Phone in E.164 format, e.g. +15555550123. Empty unless the visitor gave marketing consent. |
sms_consent |
boolean | Whether the visitor checked the marketing permission box |
zip_code |
string | ZIP code from the onboarding form |
step |
integer | Form step the visitor reached |
progress |
integer | Form completion percentage (0–100) |
resume_link |
string | The visitor's personal resume link |
location_id |
integer | Sweep&Go location ID (0 if unknown) |
location_name |
string | Sweep&Go location name |
abandoned_at |
string | ISO 8601 date the lead was marked abandoned (empty if never) |
created_at |
string | ISO 8601 date the visitor started the form |
updated_at |
string | ISO 8601 date of the last activity |
sent_at |
string | ISO 8601 date this request was sent |
site_name |
string | WordPress site name |
site_url |
string | WordPress site URL |
Example
{
"event": "lead.abandoned",
"lead_id": "LR-000012",
"status": "abandoned",
"first_name": "Jane",
"last_name": "Doe",
"name": "Jane Doe",
"email": "jane.doe@example.com",
"phone": "+15555550123",
"sms_consent": true,
"zip_code": "78215",
"step": 3,
"progress": 62,
"resume_link": "https://yoursite.com/lr/A7K29P",
"location_id": 2,
"location_name": "Austin",
"abandoned_at": "2026-07-21T07:30:00+00:00",
"created_at": "2026-07-21T06:58:00+00:00",
"updated_at": "2026-07-21T07:01:00+00:00",
"sent_at": "2026-07-21T07:31:00+00:00",
"site_name": "Poop Free",
"site_url": "https://yoursite.com"
}
The resume link is sensitive
resume_link gives access to the visitor's saved form answers. Store it securely and only share it with that visitor.
Responding
- Respond with any 2xx status code within 10 seconds to confirm delivery. The response body is ignored.
- Do slow work (CRM calls, emails) after responding, or in a background job.
- Any other status code, a timeout, or a connection error counts as a failure.
Retries
Failed deliveries are retried automatically:
| Attempt | When |
|---|---|
| 1 | A few seconds after the event |
| 2 | 5 minutes after attempt 1 failed |
| 3 | 30 minutes after attempt 2 failed |
After 3 failed attempts the lead's timeline shows Webhook Delivery Failed. Before every attempt the lead is checked again — for example, a lead.abandoned delivery is cancelled if the visitor came back in the meantime.
Duplicates
Your endpoint may receive the same lead more than once — for example when an admin clicks Resend to Webhook, or if your server processed a request but responded too late. Use lead_id + event to detect duplicates, and use create-or-update logic for contacts.
Skipped Leads
Leads with no email address and no consented phone number are not sent — a contact cannot be created without one of them.
Verifying Requests
When a Signing Secret is set in the settings, verify each request before trusting it:
- Read the raw request body (before any JSON parsing).
- Compute HMAC-SHA256 of the raw body, using the Signing Secret as the key, as a lowercase hex string.
- Prepend
sha256=and compare it with theX-SNG-Signatureheader using a constant-time comparison. - Reject the request if they don't match.
Example in PHP: