How to capture Facebook and Instagram lead ads by webhook

October 28, 2026 · Zoosial team

Connect your Facebook Page to Zoosial, register an HTTPS endpoint with POST /hooks subscribed to lead.received, and every new lead-form submission is delivered to your server as a signed JSON event, normally within seconds. From there you can insert it into your CRM, message the person or trigger a call.

The flow

  1. Connect the Facebook Page that owns your lead forms (dashboard, official Meta login).
  2. Create a webhook for lead.received. The response contains your secret once, so store it.
  3. Meta notifies Zoosial when the form is submitted, and Zoosial forwards the lead to your URL. If that notice is lost, a backup checks the forms every few minutes.
  4. Your endpoint verifies the signature and stores the lead.
POST /hooks
{ "url": "https://your-app.example/hooks/zoosial",
  "events": ["lead.received"] }

The URL must be HTTPS. An owner can have up to 20 webhooks. If you create the webhook with a key scoped to specific profiles, it only receives events from those profiles.

What the event looks like

The lead is nested under data.lead, not at the root:

{ "event": "lead.received", "id": "...", "ownerId": "...", "profileId": "prof_...",
  "data": { "formId": "...",
    "lead": { "id": "...", "created_time": "...", "form_id": "...", "platform": "...",
      "is_organic": false, "ad_id": "...", "ad_name": "...",
      "adset_id": "...", "adset_name": "...",
      "campaign_id": "...", "campaign_name": "...",
      "field_data": [ { "name": "...", "values": ["..."] } ] } } }

The ad fields are empty or missing when the lead is organic (is_organic: true) or came from an ad preview. Answers to your form questions are in field_data.

Verify the signature

Each delivery carries X-SocialGate-Signature: sha256=<hmac>, the HMAC of the raw body with your secret, plus X-SocialGate-Event and X-SocialGate-Delivery. Compute it on the raw bytes, before any JSON parsing:

const expected = "sha256=" +
  crypto.createHmac("sha256", WEBHOOK_SECRET).update(req.body).digest("hex");
if (req.headers["x-socialgate-signature"] !== expected) return res.sendStatus(401);

Failed deliveries are retried with backoff, and GET /hooks/:id/deliveries shows the history. Because retries can happen, make your handler idempotent, for example by keying on data.lead.id.

Test without waiting for a real lead

POST /accounts/:id/lead-forms/:formId/test-webhook emits a sample lead.received to your webhooks. Its field_data follows the real questions of that form, and the ad attribution is sample data (test_ad_...). It does not touch Meta. POST /hooks/:id/test sends a plain webhook.test ping.

Push to your CRM

Map field_data to your CRM fields in the handler and keep campaign_name and ad_name for attribution. If you would rather not build a CRM, Zoosial keeps a lead pipeline on top: PATCH /accounts/:id/lead-states/:leadId sets a stage, a value and a note. The lead itself stays in Meta; this is only your state layer. Meta does not allow editing a form after creation, so a change means a new form.

Use it from an AI agent

Over MCP, the tools lead_forms, leads, set_lead_state, create_webhook and test_webhook cover the same steps.

Where to read more

The full contract is in /llms.txt and /openapi.json, with English field names. The guides under /docs/webhooks and /docs/leads-crm are in Spanish today. Product pages: Leads y CRM and API y webhooks (Spanish). The English landing page is /en, and you can start free.

FAQ

How do I get Facebook lead ads into my CRM automatically?

Subscribe a webhook to lead.received. Each submission is posted to your URL as a signed event; your handler maps data.lead.field_data to your CRM fields and creates the contact.

How fast do leads arrive?

Normally within seconds: Meta notifies Zoosial when the form is submitted and Zoosial forwards it to your webhook. A backup check runs every few minutes in case a notice is lost.

Do I still need to poll the leads endpoint?

No. With a webhook subscribed, new leads arrive on their own. GET /accounts/:id/leads remains available if you need to backfill.

Does it work with Instagram lead forms?

Zoosial's contract covers leads from Facebook and Instagram lead forms. Forms are created on a Facebook Page, and each lead includes its platform.

← All articles