UpliftCRE Docs

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:

  1. Click Add Destination under Webhook Destinations.
  2. Give it a Label, set Enabled, pick the Method (POST by default, PUT available), and paste your Webhook URL.
  3. Under Send for these forms, tick which forms feed this destination — all forms or specific ones.
  4. 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:

FieldWhat it carries
ucre_lead_nameContact name
ucre_lead_emailEmail address
ucre_lead_phonePhone number
ucre_lead_companyCompany
ucre_lead_titleJob title
ucre_lead_typeLead type (buyer, seller, tenant, and so on)
ucre_lead_form_typeWhich form was submitted — stable per form type (see Forms reference)
ucre_lead_sourceSource label for the lead
ucre_lead_statusLead status at send time
ucre_lead_property_typeProperty type, as its readable label
ucre_lead_timelineTimeline the visitor gave
ucre_lead_budgetBudget or rate
ucre_lead_sf_neededSquare footage needed
ucre_lead_addressProperty address the visitor gave
ucre_lead_messageThe visitor's message
ucre_lead_notesAnything captured that did not map to another field
ucre_lead_page_urlThe page the form was submitted from
ucre_lead_page_titleThat page's title
ucre_lead_referrerReferrer
ucre_lead_utmUTM parameters
ucre_lead_listingThe listing the inquiry is about
ucre_lead_linkedin_urlLinkedIn profile URL, when captured
ucre_lead_idThe lead's id — injected at dispatch time; your dedupe key
ucre_lead_attribution_sourceAttribution channel — search engine, AI assistant, listing portal, referral, social media, other
ucre_lead_attribution_detailAttribution 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:

HeaderValue
X-UCRE-Eventlead.created
X-UCRE-Event-Idevt_ followed by 20 hex characters — identifies an individual delivery attempt
X-UCRE-TimestampUnix seconds, when the request was signed
X-UCRE-Signaturesha256= 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-Timestamp is older than your own replay window.
  • Deduplication: map ucre_lead_id to 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-Id identifies 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.

On this page