Meta Lead Ads with a generic webhook
The Meta Lead Ads settings do all of this in one place. This page builds the same intake from the general settings, for when you want to see or change each part. The shared settings are in Receive a webhook from any system.
What you need
- A Meta app you manage, and its app secret from the app's basic settings in Meta.
- A Page access token with the
leads_retrievalpermission, to read each lead's answers. - A project with a Webhook Trigger node.
Create the webhook
-
In Manage Account > Webhooks, select New webhook, enter a name and set Signature to Custom HMAC.
-
Enter:
Field Value Signing secret The Meta app secret. Signature header X-Hub-Signature-256Signature prefix sha256=Algorithm SHA-256 Encoding Hex Signed content Body Reply status 200 OK -
Select Answer a GET verification challenge. Leave Token parameter and Challenge parameter blank, enter
hub.modein Mode parameter (Optional) and leave Mode value blank. Leave Challenge verify token (Optional) blank to generate one. -
Press Create webhook. Copy the inbound URL and the verify token. The verify token is shown once.
Set up the Meta app
- In your Meta app, open Webhooks and select the Page object.
- Paste the inbound URL as the callback URL and the verify token, then verify and save.
- Subscribe to the
leadgenfield. - Subscribe the app to the Page with the Graph API
subscribed_appscall and theleadgenfield.
Split the notification into rows
Meta sends one notification with an entry list, and each entry holds a changes list. In the
Webhook Trigger node, press Configure and set:
- Rows from each delivery: Split array at path.
- Array path:
entry[].changes[].value.
Each row is one change, with leadgen_id, page_id, form_id, ad_id and created_time, and the
change's own fields with the prefix parent_, such as parent_field. A Page subscribed to more
fields than leadgen sends other changes too: add a Filter node that keeps rows where
parent_field is leadgen.
Read the lead's answers
The notification carries ids only. A Lookup node reads each lead from the Graph API and adds the answers to the row.
-
Create a Generic REST API connection:
Field Value Base URL https://graph.facebook.com/v26.0Auth method API key Send in Query parameter Parameter name access_tokenAPI key The Page access token. -
Add a Lookup node after the Webhook Trigger, or after the Filter if you added one, and set:
Setting Value Lookup connection The Generic REST API connection. Key expression row.leadgen_idRequest method GET Path /{key}Records path Blank Name and values list field_dataFields to add Blank, or the form's question names, such as email, full_name, phone_numberColumn prefix lead_Failure policy Route to error
Meta answers with the lead's id, created_time and field_data, a list of
{"name": ..., "values": [...]} items, one per form question. Name and values list turns each
item into a column, so a form that asks for an email and a full name adds lead_email and
lead_full_name to the row. A question with several answers, such as a multiple choice question,
becomes one value joined with , .
The question names are the ones in the form, including custom questions. To see them, run the project once with Fields to add blank and read the columns in the run's output.
A lead that Meta cannot return gives an error status, and the row goes to error. Each
leadgen_id is read once per run, however many rows carry it.
Duplicates
Meta retries a notification it could not deliver, for up to 36 hours. Without an event id, two identical notifications are one delivery only within 24 hours, so a retry after that runs again.
To pin each notification to its lead, open Settings, set Event id for duplicates to Field
path and enter entry[0].changes[0].value.leadgen_id. A notification with several changes is
then identified by its first change only.
Compared with the Meta Lead Ads settings
| Generic webhook | Meta Lead Ads settings | |
|---|---|---|
| Rows | One per change, answers added by a Lookup | One per lead, with the form's answers |
| Duplicates | 24 hours, or the first change's lead id | Each lead id, without a time limit |
| Page token | Held in a Generic REST API connection | Held in a Meta Lead Ads connection |