Skip to content

How it works · 4 of 8

Webhook for Zapier and Make

Checked · 8 min read

Written by Mateusz Cieśliński · Creator of LeadScanner

In short

A LeadScanner webhook sends a JSON POST to Zapier, Make, or your own HTTPS endpoint when new leads are found or a scan finishes. Use the receiving URL as the channel address, test it once, then map the lead fields into your CRM.

Why a webhook and not a ready-made Zapier app

Until April 2024 there was an official route: the Facebook Groups API, which the "New Post in Group" trigger in Zapier and the matching module in Make were built on. Meta switched it off and put nothing in its place. The Facebook app in Zapier still exists, but it handles pages and ads — groups are gone from the list of triggers and will not return, because there is no interface left for them to stand on.

LeadScanner reads public groups and pages without an account, exactly as a signed-out passer-by sees them, and after every scan it can send an event to an address you choose. From where Zapier and Make sit that is an ordinary incoming webhook — which is to say, precisely the trigger that is missing. Everything after it is what those tools already do well: a row in a spreadsheet, a card in the CRM, a Slack message, a task for a salesperson.

The webhook channel is available on the Growth plan and above. The organisation's owner or an administrator sets it up in the panel, under Notifications → Channels.

4

If delivery fails, LeadScanner tries the event up to four times before it remains marked as failed.

product rule

Setting it up in Zapier

In Zapier create a new Zap and pick the "Webhooks by Zapier" app as its trigger, with the "Catch Hook" event. Zapier shows the address it is listening on — copy it.

In the LeadScanner panel open Notifications → Channels and add a Webhook channel. Paste the copied address. If you want the receiving side to tell your events from anybody else's, add an authentication header: a name (X-Api-Key, say) and a value you make up.

Tick the events that should go out: "New leads", "Scan finished" or both. Sales automation usually needs only the first; the second is for logging every scan, empty ones included. Save the channel and click "Send a test".

Back in Zapier, click "Test trigger". Zapier receives the test event and breaks it into fields you can map in the steps that follow: person_name to the name column, post_url to the link, score to the priority. The test event carries a test field set to true and sample data — do not file that person in the CRM, because they do not exist.

Setting it up in Make

In Make add a "Webhooks" → "Custom webhook" module to the scenario, name it and copy the generated address. From that moment Make is listening, waiting for the first message so it can read the data structure off it.

The panel steps are the same as for Zapier: Notifications → Channels → Webhook, paste the address, optionally add the authentication header, choose the events, save and click "Send a test".

After the test Make reports that it has determined the structure. If you do not see that — because the webhook was already listening earlier and remembered a different shape, for instance — click "Redetermine data structure" on the module and send the test once more. From then on the payload fields are available in every module that follows.

One practical note for both tools: the "New leads" event carries a list, not a single lead. In Make split it with an iterator; in Zapier use a "Looping by Zapier" step — or map only the first element, if you react to the whole batch at once anyway.

The new_leads event: what arrives

Every event is one POST request with a JSON body. The top level always carries the same set of fields: event — the event name, here new_leads; version — the payload format version, currently 1; organization_id — your organisation's identifier; sent_at — the send time in ISO 8601; subject — a one-sentence title, the same one used as the e-mail subject; leads_count — how many leads are in the batch; leads — the list of leads.

Each element of leads has: person_name — the author's name as it appears on Facebook; score — a rating from 0 to 100, the higher the surer the enquiry; excerpt — the fragment of the post or comment where the question was asked; post_url — a link to the post; profile_url — a link to the author's profile if it was visible, otherwise null; rationale — one sentence on why this was counted as a lead; source_name — the group or page it was found in.

A test send has exactly this shape, only with sample data and an extra test field set to true. That is the simplest way to see a complete example: click "Send a test" and look at what Zapier or Make caught.

The scan_finished event: the same, plus the scan

The scan_finished event carries every field described above — with the leads list holding what this scan found, which may be empty — and in addition a scan object. In it: id — the scan's identifier; source_id, source_name and source_url — which source was checked; status — how it ended; mode — keyword or AI; scheduled_slot — the schedule slot the scan belonged to; started_at and finished_at — when it began and ended; points_spent — what it cost in points; leads_found — how many leads it found; error and error_code — a description and code when the scan failed, otherwise null.

Then coverage, the account of what the scan looked at: posts_seen and comments_seen — how many posts and comments it read; posts_suppressed — how many posts it skipped because their authors asked for their data to be erased; posts_stale and comments_stale — how many were older than the freshness window; posts_unchanged and comments_unchanged — how many it already knew from an earlier visit and did not grade again; graded — how many fragments went to grading; leads — how many of those became leads; rejected — a list of reason and count pairs: why, and how many, fell out.

The coverage numbers always add up: graded is the fresh posts and comments after the stale and the already-known ones are taken away, and leads plus the sum of rejected equals graded. If you build a dashboard on this, those two identities can be relied on.

The reasons in rejected always come from the same list: no_keyword (none of the phrases occurred), no_intent (it cannot be told whether the author is looking for anything), not_in_market (speaks the trade's language but is not buying — advising, reporting, selling), outside_offer (buying, but not what you sell or not where you work), excluded (asking for exactly what you said you do not do), below_threshold (a fit, but too weak for the threshold), ungraded (the model answered in a shape that could not be read). Keep them as a dictionary rather than mapping them by eye.

The HMAC signature, and what to use instead

If you set a secret on the channel, every request gets two headers: X-LeadScanner-Timestamp with the signing time in unix seconds, and X-LeadScanner-Signature with the value v1=<hex>, where hex is an HMAC-SHA256 over the string "<timestamp>.<body>" keyed with your secret. The receiver computes the same thing on its side and compares; a signature older than five minutes is rejected. That way nobody who merely knows the address can impersonate LeadScanner or replay a captured request a week later.

Without a secret there are no signature headers — the event goes out unsigned, as most no-code integrations do. Zapier and Make do not compute an HMAC without an extra code step, so for them the simpler and sufficient protection is the authentication header from the panel: on the automation side add a filter that lets through only requests carrying that name and that value.

Two rules that cannot be switched off: the address must be public HTTPS — plain http and an address on a private network will not pass — and redirects are refused. If your server answers 301 or 302, the delivery ends in an error rather than quietly moving to another address, because at another address the signature and the authentication header would land somewhere they were not meant to.

When a delivery fails

A response other than 2xx, a timeout or a dropped connection count as a failed attempt. We do not stop there: the event is sent again three times, with growing delays — the first retry after half a minute, the last after a few. That is enough to wait out a server restart or a momentary rate limit on Zapier's side, while a notification that does eventually arrive is still a notification and not a history lesson.

Every attempt — successful or not — is visible in the panel under the channel, with its time, response code and the reason it failed. If the event has not arrived after four attempts it stays on that list as failed, and that is where to start looking: usually it is a Zap address that no longer exists, or a Make scenario somebody switched off.

API, templates and MCP

The public API v1 is at /api/v1, on every plan: an ls_ key created under Settings → Integrations, sent in the Authorization: Bearer header, documentation at /api/v1/docs, 600 requests an hour per organisation.

The integrations/ directory of the product repository holds a step-by-step recipe for Zapier, a Make blueprint for Import Blueprint and an n8n workflow for Import from File. All three split leads into single leads, keep a score of at least 60, skip test events and write a Google Sheets row.

The MCP server at /mcp takes the same key, for Claude and other assistants: list_leads, get_lead, set_lead_status, set_lead_feedback, get_reply_draft, list_campaigns, list_sources, create_source, update_source.

Every alert — e-mail, Slack, SMS, webhook — now shows the post's age; a webhook lead carries published_at and age_minutes, null when the date is unknown, and the version stays 1: map by name.

Questions that come with it

How do I send a webhook from LeadScanner to Zapier?

Create a Catch Hook trigger in Webhooks by Zapier and copy its URL. Add that URL as a Webhook channel in LeadScanner, select the events you need, and send a test. Zapier then exposes the payload fields for later steps.

Can Make receive LeadScanner webhook events?

Yes. Add a Custom webhook module in Make, copy its generated URL, and add it as a Webhook channel in LeadScanner. Send a test so Make can determine the data structure. Use an iterator if you need to process each lead separately.

What happens if my webhook endpoint is down?

A non-2xx response, timeout, or dropped connection counts as a failed delivery. LeadScanner retries the event up to four times. Check the channel delivery history for response codes and failure reasons if the event still does not arrive.

The Groups API is not coming back, and a LeadScanner webhook is the "new post in a group" trigger Zapier and Make do not have: one address, one click on "Send a test", and the rest of the work is on the automation's side.

Start your free trial

120 points to start. No card, cancel in one click. You get 7 days on the Growth plan.

Mateusz Cieśliński — Creator of LeadScanner

About the author

Mateusz Cieśliński · Creator of LeadScanner

A software engineer, graduate of Lodz University of Technology, who builds AI-based systems for a living. LeadScanner grew out of his own work: before it was a product, he was fishing for enquiries in public Facebook groups himself, by hand, every morning, for years — and the measurements in the guides here, dates attached, are his.