Marketing Automation & MarTech

Custom Webhooks for Lead Sources Without a Native Integration

When a form tool, dialer or lead vendor has no native integration, a custom webhook fills the gap. Here's how to set one up so leads keep their ad source.


Every marketing stack eventually hits a lead source with no native integration. A niche form builder, a regional dialer, a quiz tool, a lead vendor, a booking widget your client insists on keeping. The standard answer is a custom webhook lead source: the tool sends an HTTP request with the lead’s details to an endpoint you control, and your CRM or attribution system turns it into a contact. It’s the most flexible integration there is, and it’s also where a lot of attribution quietly dies.

The problem isn’t getting the lead in. Most tools can fire a webhook in five minutes. The problem is that the lead arrives as a name, an email and a phone number with no idea where it came from. The ad click, the landing page, the campaign: all of that lived in the visitor’s browser, and the form tool never passed it along. This post covers how custom webhooks work for lead sources, how to carry tracking data through them so leads keep their source, how to test and monitor them, and the mistakes that cause silent data loss.

When a custom webhook is the right choice

You have roughly three options for connecting a tool without a built-in integration, which we compare in more depth in native integrations vs. Zapier vs. custom webhooks:

  • A middleware tool like Zapier or Make. Fast to set up, no code, but adds a cost per task, a delay, and another place for mapping to break.
  • A direct custom webhook from the source tool to your system. Fewer moving parts, near real time, and you control the payload.
  • A custom integration via API. Most control, most engineering.

A direct webhook is usually the sweet spot when the source tool can send one, the volume is meaningful, and you care about speed (for example, a setter who calls new leads within minutes).

If you’re new to the mechanics, webhooks explained for marketers who aren’t engineers covers the basics.

The anatomy of a lead webhook

A lead webhook has three parts:

  1. The endpoint: a URL on the receiving system that accepts requests.
  2. The payload: the data the source sends, usually JSON or form-encoded fields.
  3. The mapping: which payload field goes into which field on the receiving side.

A typical payload from a form tool looks like this:

{
  "first_name": "Dana",
  "email": "dana@example.com",
  "phone": "+15551234567",
  "revenue_range": "50k-100k",
  "form_name": "Strategy call application"
}

That’s a complete lead and a useless one for attribution. There’s no trace of the visit.

Carrying tracking data through the webhook

The fix is to get tracking identifiers into the form, so the form tool sends them along with the lead. There are three identifiers worth passing:

  • Facebook click ID (fbclid), present in the URL when someone arrives from a Meta ad
  • Google click ID (gclid), present when someone arrives from a Google ad
  • A session ID from your own tracking pixel, which identifies the visit regardless of where it came from

The usual technique is hidden fields. Add hidden fields to the form, and populate them from the page URL or from your tracking script. Most form tools support hidden fields that read URL parameters; some let a script on the page set them. Then include those fields in the webhook payload:

{
  "first_name": "Dana",
  "email": "dana@example.com",
  "phone": "+15551234567",
  "fbclid": "IwAR2xY...",
  "session_id": "cx_8f3a..."
}

The session ID is the most reliable of the three because it exists for every visitor, including organic ones and those whose click IDs were stripped by a redirect.

In Callix, you map a Facebook click ID, Google click ID or Callix session ID on a custom webhook, and the lead is linked to the visit it came from. That means form-tool leads show their source, campaign and landing page like any lead from a page with the pixel. For Typeform specifically there’s a no-code route: add a hidden field named callix_sid and the Callix pixel fills it on embedded forms and links to the form.

Step-by-step setup

Here’s the sequence we’d follow for any new lead source:

  1. List the fields you need. Contact details, qualifying answers, and at least one tracking identifier. Decide which are required.
  2. Add hidden tracking fields to the source form. Test that they populate by submitting the form from a URL that includes a test click ID.
  3. Create the endpoint on the receiving system, and note what it saves (prospects, payments, calls).
  4. Configure the source tool to send to that endpoint on the right trigger, usually “form submitted.”
  5. Send a test request and inspect the raw payload the receiving side logged.
  6. Map every field, including the tracking fields.
  7. Send a second test and confirm the lead appears with its source, campaign and landing page.
  8. Decide what conversion events, if any, this lead should fire to your ad platforms, and confirm they fire once, not twice.

Step 8 matters if the same lead could also be captured another way, such as by your pixel on the thank-you page. Pick one path to own each conversion.

The silent failure: endpoints that accept data and save nothing

The most expensive webhook bug isn’t an error. It’s a request that succeeds, returns a 200, shows as processed, and saves nothing, because no one finished the field mapping. The source tool thinks delivery worked. Your team thinks leads are flowing. Two weeks later someone asks why the new quiz funnel produced zero leads.

Good systems make this loud. In Callix, a request to a custom webhook endpoint that saves payments, prospects, calls or dials, but has no field mappings yet, shows as Failed with what to do, instead of Processed while nothing was saved. The endpoint card says Not mapped, and Setup Health warns about an active endpoint receiving requests it can’t save. You map the fields in Settings → Developers → Webhooks and then rerun the stored requests to save them.

One detail in that design is worth copying in any system: payments and leads from requests more than a week old are saved without being sent to your ad platforms. If you back-fill a broken endpoint after two weeks, you don’t want Meta or Google receiving a burst of “new” leads and sales that actually happened a fortnight ago. That would distort the platform’s learning.

Monitoring webhooks after launch

A webhook that worked on day one can break later: the source tool changes its payload, someone renames a field, a form is duplicated without its hidden fields. Set up a few checks:

  • Volume check. Compare leads received per day against the source tool’s own submission count. A gap means dropped requests.
  • Source coverage. What share of leads from this endpoint have a tracked source? If it drops from 85% to 20%, the hidden fields probably broke.
  • Failed request log. Review failures weekly. Most systems keep a request log; use it.
  • After any change to the form, send a test submission with a test click ID and check it end to end.

A worked example: a quiz funnel leaking attribution

Say an agency runs a quiz funnel for a client’s coaching offer. The quiz tool has no native integration, so it sends leads by webhook. Over a month, Meta spend on the quiz campaign is $12,000, the quiz tool reports 600 completions, and the CRM shows 600 leads. Good so far.

But in the attribution report, only 90 of those 600 leads have a Meta source. The other 510 show as having no source. The quiz campaign appears to have produced 90 leads at $133 each, and the client wants to kill it.

The cause: the quiz tool’s hidden fields were set up for UTM parameters, but the webhook mapping only included contact fields. The tracking data was captured and then dropped. The 90 with a source were people who later visited a page with the pixel and were matched by email.

After adding the session ID and click ID fields to the mapping, new leads arrive with their source. The real number is around 560 Meta-sourced leads at about $21 each, and once calls and sales are tied to them, the campaign turns out to be one of the client’s best. Same campaign, same leads, opposite decision.

Beyond form leads: dials, calls and payments

The same pattern applies to other data your tools generate:

  • Dialers without an integration. In Callix, a custom webhook set to Analyze Dial counts each dial in your dial metrics, shows it under Deal Analysis → Dials, and transcribes and analyzes its recording.
  • Payment tools. Send payments by webhook with the buyer’s email and phone so they match the right contact.
  • Booking tools. Send bookings with the same tracking fields as leads so the call is credited to the visit that produced it.

In each case, the rule holds: the webhook should carry whatever identifier ties the event to a person and a visit, not just the event itself.

A short checklist

Before calling any custom webhook lead source done:

  • Every lead includes at least one tracking identifier, ideally a session ID.
  • Every payload field that matters is mapped, including tracking fields.
  • A test lead shows the correct source, campaign and landing page.
  • Conversion events fire once per lead, from one path.
  • Failed and unmapped requests are visible, not silently “processed.”
  • Someone owns a monthly check of volume and source coverage.

Do those six things and a lead source without a native integration behaves like one that has it. Skip them and you’ll likely find out the way most teams do: when a profitable campaign gets switched off because its leads looked like they came from nowhere. For routing those leads once they arrive, see how to automate lead routing without losing leads.

Book a demo