Documentation Developers

Webhooks

Receive new leads and status changes as JSON, signed with HMAC-SHA256.

Leadwon posts every new lead and every status change as JSON to the address under Leads → Settings → Webhook. Use it with Make, Zapier, n8n or your own endpoint. Webhooks are part of the free plugin.

Events

Event When
lead.created A lead was saved. Not sent for submissions marked as spam.
lead.status_changed The status of a lead changed, in WordPress, through a CRM or through the status API.

The event name is also sent in the X-Leadwon-Event header. Requests are sent in the background, shortly after the event, with a timeout of 10 seconds. Answer with a status code from 200 to 299.

Body

{
  "event": "lead.created",
  "sent_at": "2026-10-09T14:05:12+00:00",
  "site": { "name": "Kitchen Studio Nord", "url": "https://example.com/" },
  "lead": {
    "id": 1234,
    "created_at": "2026-10-09T14:05:09+00:00",
    "name": "Anna Keller",
    "email": "anna@example.com",
    "phone": "+4940123456",
    "whatsapp_url": "https://wa.me/4940123456",
    "form": { "plugin": "cf7", "id": "42", "name": "Quote request" },
    "status": "new",
    "status_label": "New",
    "value": null,
    "currency": "EUR",
    "won_at": null,
    "channel": "paid_search",
    "channel_label": "Paid search",
    "source": "google",
    "medium": "cpc",
    "campaign": "Kitchen renovation Hamburg",
    "last_channel": "paid_search",
    "landing_page": "https://example.com/kitchens/",
    "gclid": "Cj0KCQjw…",
    "gbraid": "", "wbraid": "", "fbclid": "", "msclkid": "",
    "fields": [ { "label": "Message", "name": "your-message", "type": "textarea", "value": "…" } ],
    "attribution": { "first": { … }, "last": { … } },
    "recording_url": null,
    "admin_url": "https://example.com/wp-admin/admin.php?page=leadwon&lead=1234"
  }
}

status is one of new, contacted, qualified, won, lost or spam. recording_url links to the Microsoft Clarity recording of the visit, if your site uses Clarity.

Verify the signature

Enter a Signing secret in the settings, and every request carries an X-Leadwon-Signature header: sha256= followed by the HMAC-SHA256 of the raw body with your secret. Compare it before trusting the request:

$body      = file_get_contents( 'php://input' );
$expected  = 'sha256=' . hash_hmac( 'sha256', $body, $secret );
$signature = $_SERVER['HTTP_X_LEADWON_SIGNATURE'] ?? '';

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

Change the payload

The leadwon_webhook_payload filter receives the lead part of the body and the lead row:

add_filter( 'leadwon_webhook_payload', function ( $payload, $lead ) {
	unset( $payload['fields'] );
	return $payload;
}, 10, 2 );