Paste a URL from Zapier, Make, n8n or your own server. LeadWebia posts the leads you send as JSON and signs every request with HMAC-SHA256, so you can check it came from us.
Included in every paid plan · from $9 a month
In a new Zap, choose Webhooks by Zapier → Catch Hook and copy the webhook URL from the Test tab. Webhooks by Zapier needs a paid Zapier plan.
Open Integrations → Webhook, paste the URL and click "Save". Copy the signing secret: it's shown only once.

Click "Send test" in LeadWebia, then "Test trigger" in Zapier. To act on each lead, add Looping by Zapier → Create Loop From Line Items over the leads (Professional plan or higher).
Add the Webhooks → Custom webhook trigger, create a webhook and copy its address.
Paste the address in Integrations → Webhook, click "Save" and then "Send test": Make learns the data structure from that request.
Add an Iterator on the leads list so each lead becomes its own bundle for the next modules (a CRM, a sheet, Slack…).
Select leads, open Actions → Send to… → Webhook and click "Send". Sends of more than 100 leads run in the background and you're told when they finish.

| Method and body | POST, Content-Type: application/json (UTF-8) |
|---|---|
| Events | leads.sent (your sends) and test ("Send test", one sample lead) |
| Headers | X-LeadWebia-Event, X-LeadWebia-Timestamp (Unix seconds), X-LeadWebia-Signature, User-Agent: LeadWebia-Webhook/1.0 |
| Signature | sha256= + hex HMAC-SHA256 of the raw body, keyed with your signing secret (whsec_…) |
| Batches | Up to 100 leads per request in "leads" (event leads.sent), or one lead per request in "lead" plus its first "email" (event lead.sent, setting "One lead per request"); batch.index / batch.count and one delivery_id per send |
| Retries | Network errors, 5xx and 429: 3 more tries after 1, 2 and 4 seconds (429 honours Retry-After up to 30 s). Other 4xx and redirects aren't retried; a batch that fails for good stops the send. |
| Timeout | 10 seconds per request |
| URLs | https:// only, to a public host (private and internal addresses are refused) |
Each lead in "leads" carries these fields; null when there is nothing to put there.
| Data | Fields | What it is |
|---|---|---|
| Business | name, category | The name and the Google Maps category, e.g. "Roofing contractor". |
| Address | vicinity, city, state, postal_code | The full address, plus city, state and ZIP code in their own columns for US addresses. |
| Phone | phone, phone_e164 | As listed on Maps, and in E.164 format (+15125550134) for dialers and CRMs. |
| Website | website | The website on the listing; empty when the business has none. |
| Reputation | rating, user_ratings_total | Google rating and number of reviews. |
| Emails | emails | Found on the business's website and public pages. Maps listings don't include emails. |
| Social profiles | facebook, instagram, linkedin, twitter, tiktok, youtube | Links to the profiles the business publishes. |
| PageSpeed (mobile) | performance, accessibility, best_practices, seo | Google PageSpeed scores, 0–100, for businesses with their own site. |
| Tech | cms, ads | The CMS (WordPress, Wix, Squarespace…) and the ad pixels found on the site. |
| Lead score | score, score_label | 0–100 and hot / warm / cold, from no website, slow or broken site, no SSL, ads and an unclaimed profile. |
| Links and pipeline | google_maps_url, place_id, niche, status, saved_at | The Maps listing, Google's place ID, the niche it was found for, your status and when you saved it. |
{
"event": "leads.sent",
"sent_at": "2026-10-13T15:04:05Z",
"source": "leadwebia",
"delivery_id": "6f1c2a9e-0d4b-4c6e-9a51-2b7e8c1f3d20",
"batch": { "index": 1, "count": 1 },
"leads": [
{
"place_id": "ChIJ…",
"name": "Joe's Pizza",
"status": "Contacted",
"score": 78,
"score_label": "hot",
"category": "Pizza restaurant",
"vicinity": "1200 Congress Ave, Austin, TX 78701",
"city": "Austin",
"state": "TX",
"postal_code": "78701",
"rating": 4.6,
"user_ratings_total": 212,
"website": null,
"phone": "+1 512-555-0134",
"phone_e164": "+15125550134",
"emails": ["hello@joespizza.com"],
"facebook": "https://www.facebook.com/joespizza",
"instagram": null, "linkedin": null, "twitter": null, "tiktok": null, "youtube": null,
"performance": null, "accessibility": null, "best_practices": null, "seo": null,
"cms": null,
"ads": [],
"niche": "pizza",
"google_maps_url": "https://www.google.com/maps/place/?q=place_id:ChIJ…",
"landing_page_url": null,
"leadwebia_url": "https://leadwebia.com/dashboard?q=Joe%27s+Pizza&websiteFilter=all",
"saved_at": "2026-10-12T18:30:00Z"
}
]
}// Express: keep the raw body, the signature is computed over its exact bytes.
const crypto = require('crypto');
const express = require('express');
const app = express();
app.post('/leadwebia', express.raw({ type: 'application/json' }), (req, res) => {
const header = req.get('X-LeadWebia-Signature') || '';
const expected = 'sha256=' + crypto
.createHmac('sha256', process.env.LEADWEBIA_SIGNING_SECRET)
.update(req.body) // Buffer with the raw body
.digest('hex');
const valid = header.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
if (!valid) return res.sendStatus(401);
const payload = JSON.parse(req.body.toString('utf8'));
// Optional: refuse old deliveries (replays).
if (Date.now() - Date.parse(payload.sent_at) > 5 * 60 * 1000) return res.sendStatus(400);
for (const lead of payload.leads) {
// lead.place_id, lead.name, lead.phone_e164, lead.emails…
}
res.sendStatus(200);
});# Flask: request.get_data() is the raw body the signature covers.
import hashlib
import hmac
import os
from flask import Flask, abort, request
app = Flask(__name__)
SECRET = os.environ["LEADWEBIA_SIGNING_SECRET"].encode()
@app.post("/leadwebia")
def leadwebia():
raw = request.get_data()
expected = "sha256=" + hmac.new(SECRET, raw, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, request.headers.get("X-LeadWebia-Signature", "")):
abort(401)
payload = request.get_json()
for lead in payload["leads"]:
... # lead["place_id"], lead["name"], lead["phone_e164"], lead["emails"]…
return "", 200Facts about other companies come from their own documentation, checked on October 13, 2026: Zapier: trigger Zaps from webhooks · Zapier: loop your Zap actions · Make: webhooks · Make: Iterator · n8n: Webhook node.
Compute HMAC-SHA256 of the raw request body with your signing secret, prefix it with "sha256=" and compare it with the X-LeadWebia-Signature header in constant time. The Node and Python snippets above do exactly that.
Yes: any HTTPS URL on a public host works. In n8n, add a Webhook node with the POST method and use its production URL (n8n registers it when you publish the workflow); the leads are in $json.body.leads.
Network errors, 5xx and 429 answers are retried three times (1, 2 and 4 seconds apart). If a batch still fails, the send stops and the Dashboard shows how many leads went through.
Each request carries up to 100 leads. batch.index and batch.count tell you where you are, and delivery_id is the same for every batch of one send.
Start with 50 free leads; webhooks are included in every paid plan.