Lead Webhooks
The Lead Delivery developer reference — payload fields, headers, HMAC-SHA256 signature verification, and retry behavior.
Lead Delivery sends every lead your site's forms capture to the destinations you choose — Zapier, Make, n8n, GoHighLevel, HubSpot, or any endpoint that accepts webhooks. This page is the integration contract: what the request looks like, how it is signed, and what happens when a delivery fails. For the product overview, see Lead Delivery.
Set up a destination (the user half)
A Director sets this up once per destination, at Website Settings, under the Integrate With Other Apps tab in the When someone contacts you section:
- Click Add Destination under Webhook Destinations.
- Give it a Label, set Enabled, pick the Method (POST by default, PUT available), and paste your Webhook URL.
- Under Send for these forms, tick which forms feed this destination — all forms or specific ones.
- Build the Field Mapping with Add Field pairs (lead field → destination key), and set a Signing Secret so each request is signed. Save.
Optional extras per destination: Static Fields (fixed key/value pairs merged into every payload) and Custom Headers. The signing secret is optional — leave it empty and requests arrive unsigned. And nothing sends until a destination exists: zero destinations, zero outbound requests.
The request
Each matching lead produces one HTTP request to the destination's URL:
- Method: POST (or PUT, per destination).
- Content-Type:
application/json. - Body: a JSON object whose keys are the destination's own mapped keys. The values come from the lead fields below — anything you did not map simply is not included unless you add it. Static fields are merged in first; a mapped, non-empty lead value overrides a static one.
Payload fields
These are the 25 source fields available to map:
| Field | What it carries |
|---|---|
ucre_lead_name | Contact name |
ucre_lead_email | Email address |
ucre_lead_phone | Phone number |
ucre_lead_company | Company |
ucre_lead_title | Job title |
ucre_lead_type | Lead type (buyer, seller, tenant, and so on) |
ucre_lead_form_type | Which form was submitted — stable per form type (see Forms reference) |
ucre_lead_source | Source label for the lead |
ucre_lead_status | Lead status at send time |
ucre_lead_property_type | Property type, as its readable label |
ucre_lead_timeline | Timeline the visitor gave |
ucre_lead_budget | Budget or rate |
ucre_lead_sf_needed | Square footage needed |
ucre_lead_address | Property address the visitor gave |
ucre_lead_message | The visitor's message |
ucre_lead_notes | Anything captured that did not map to another field |
ucre_lead_page_url | The page the form was submitted from |
ucre_lead_page_title | That page's title |
ucre_lead_referrer | Referrer |
ucre_lead_utm | UTM parameters |
ucre_lead_listing | The listing the inquiry is about |
ucre_lead_linkedin_url | LinkedIn profile URL, when captured |
ucre_lead_id | The lead's id — injected at dispatch time; your dedupe key |
ucre_lead_attribution_source | Attribution channel — search engine, AI assistant, listing portal, referral, social media, other |
ucre_lead_attribution_detail | Attribution detail — for example, which AI assistant |
Two formatting rules: empty values are omitted from the payload rather than sent as empty strings, and multi-value fields are flattened to comma-joined strings.
Headers
When a destination has a signing secret, each request carries four headers:
| Header | Value |
|---|---|
X-UCRE-Event | lead.created |
X-UCRE-Event-Id | evt_ followed by 20 hex characters — identifies an individual delivery attempt |
X-UCRE-Timestamp | Unix seconds, when the request was signed |
X-UCRE-Signature | sha256= followed by the HMAC-SHA256 hex digest |
These four are set by the platform itself, after your custom headers, so a custom header cannot shadow or spoof them.
Verifying the signature
The signature is HMAC-SHA256 over timestamp.body — the raw X-UCRE-Timestamp value, a
period, and the exact raw request body as received, keyed with the destination's signing
secret. Verify against the raw body before any framework parsing or re-serialization.
import { createHmac, timingSafeEqual } from "node:crypto";
function verifyLeadWebhook(rawBody, headers, secret) {
const expected =
"sha256=" +
createHmac("sha256", secret)
.update(headers["x-ucre-timestamp"] + "." + rawBody)
.digest("hex");
const received = String(headers["x-ucre-signature"] ?? "");
const a = Buffer.from(expected);
const b = Buffer.from(received);
return a.length === b.length && timingSafeEqual(a, b);
}Two more checks worth making on your side:
- Freshness: reject requests whose
X-UCRE-Timestampis older than your own replay window. - Deduplication: map
ucre_lead_idto a key in Field Mapping, then dedupe on it — it is stable across retries. It is only in the body if you map it.X-UCRE-Event-Ididentifies a single delivery attempt, so a later re-delivery can carry a new one.
Retries
Delivery succeeds on any 2xx response. Anything else — a non-2xx status, a timeout (15 seconds), or a connection error — schedules a retry:
- Three attempts total, with backoff: the first retry after about a minute, the second after about two.
- Redirects are not followed, so point the webhook URL at the final endpoint.
- If all three attempts fail, the failure is recorded on the lead's activity record in your dashboard — the lead is never dropped silently.
Behavior worth knowing
- Creation only. A lead dispatches when it is created — editing or re-saving a lead never re-sends it. Newsletter signups flow through the same pipeline.
- Per-form opt-in. Each destination receives only the forms ticked for it, so different destinations can take different slices of your leads.
- No secret, no signature. An unsigned request is byte-identical to a signed one apart from the four headers — verify only what you asked to be signed.
Test your endpoint
Submit a test lead the way a visitor would: open your own site, fill in one of your own forms, and watch the request arrive at your endpoint. That creates a real lead and dispatches like any other — which is exactly what you want to verify end to end, signature and all.
MCP Tools
The developer reference for the AI Assistant Connector — every tool the connector exposes, with inputs, behavior, role gates, and rate limits.
AI Citability
The machine-readable surfaces every UpliftCRE site publishes — the listing fact feed, llms.txt, markdown doors, the property-facts table, and the information AI can read (JSON-LD).