Skip to content

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:

  1. Read the raw request body (before any JSON parsing).
  2. Compute HMAC-SHA256 of the raw body, using the Signing Secret as the key, as a lowercase hex string.
  3. Prepend sha256= and compare it with the X-SNG-Signature header using a constant-time comparison.
  4. Reject the request if they don't match.

Example in PHP:

$raw      = file_get_contents( 'php://input' );
$expected = 'sha256=' . hash_hmac( 'sha256', $raw, 'YOUR_SIGNING_SECRET' );
$received = $_SERVER['HTTP_X_SNG_SIGNATURE'] ?? '';

if ( ! hash_equals( $expected, $received ) ) {
    http_response_code( 401 );
    exit;
}