Webhook payload reference
The JSON payload Find Prospects Now sends to custom webhooks after a scan, its headers, and how to verify the HMAC-SHA256 signature.
Custom (non-Slack, non-Discord) webhooks receive one POST request with a JSON body per scan that finds new matches.
Example
{
"schema_version": 1,
"event_id": "6f1c2a8e-1b0d-4b7a-9d3e-2f4c5a6b7c8d",
"event": "scan_completed",
"timestamp": "2026-10-17T14:05:12.000Z",
"scan_id": "a3b4c5d6-…",
"summary": {
"total_matches": 2,
"total_processed": 180,
"groups_scanned": 9,
"scan_type": "scheduled",
"truncated_leads": 0
},
"leads": [
{
"post_id": "1234567890",
"group_name": "Austin Homeowners",
"author": "Jane Doe",
"text": "Can anyone recommend a plumber? Our water heater is leaking.",
"url": "https://www.facebook.com/groups/…/posts/…",
"created_at": "2026-10-17T13:52:00.000Z",
"matched_keywords": ["recommend a plumber", "leaking"],
"match_type": "keyword",
"ai_classified": true,
"ai_match": true,
"ai_label": "Plumbing request"
}
]
}Fields
| Field | Description |
|---|---|
event | scan_completed for real scans. Test sends the same shape with scan_type: "test" and a sample lead. |
event_id | Unique ID of this event. Use it to ignore duplicates. |
timestamp | When the scan finished (ISO 8601). |
summary.total_matches | Number of matching posts in the scan. |
summary.total_processed | Posts checked. |
summary.groups_scanned | Groups scanned. |
summary.scan_type | How the scan started, for example manual, scheduled or test. |
summary.truncated_leads | Leads not included because a payload holds at most 100 leads. |
leads[].post_id | Facebook post ID. |
leads[].group_name | Group name. |
leads[].author | Author's display name. |
leads[].text | Post text. |
leads[].url | Link to the post on Facebook. |
leads[].created_at | When the post was published, or null if unknown. |
leads[].matched_keywords | Keywords that matched (may be empty). |
leads[].match_type | keyword or ai. |
leads[].ai_classified | Whether AI checked the post. |
leads[].ai_match | Whether an AI criterion matched. |
leads[].ai_label | Label of the matching AI criterion, or null. |
Headers
| Header | Value |
|---|---|
Content-Type | application/json |
User-Agent | FindProspectsNow/1.0 |
X-Webhook-Event | The event name, e.g. scan_completed |
X-Webhook-Id | The event ID |
X-FPN-Delivery-Id | Unique ID of this delivery attempt series |
X-Webhook-Signature | sha256=<hex> — only when a signing secret is set |
Verify the signature
When you set a signing secret, compute the HMAC-SHA256 of the raw request body with your secret and compare it with the header.
import { createHmac, timingSafeEqual } from 'node:crypto';
function isValid(rawBody, header, secret) {
const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex');
return header && expected.length === header.length &&
timingSafeEqual(Buffer.from(expected), Buffer.from(header));
}Responding
Return any 2xx status within a few seconds. Timeouts, 408, 425, 429 and 5xx responses are retried a few times with increasing delays; other 4xx responses are not retried. Process leads asynchronously if your work is slow, and deduplicate with event_id.
Last updated on
Slack, Discord and webhooks
Send new Facebook group leads from Find Prospects Now to Slack, Discord, a CRM or any webhook URL after every scan.
Zapier, Make and n8n
Send Facebook group leads from Find Prospects Now into Zapier, Make, n8n or a CRM such as HubSpot or Google Sheets using a webhook trigger.