Short answer: For lead generation, the Meta Conversions API (CAPI) sends your Lead event from your server as well as from the browser Pixel, so Meta still receives the lead when the Pixel is blocked. Pick a setup path (a platform or CRM partner integration, the self-hosted Conversions API Gateway, server-side GTM, or a direct API call), send the same event_name and the same event_id from both browser and server so Meta deduplicates them within 48 hours, and include hashed email and phone plus fbc, fbp, IP and user agent to raise Event Match Quality.
Need this done for you? GrowthSparx offers a fixed-scope lead tracking and attribution setup: GA4, Google Ads, Meta, WhatsApp, calls and CRM wired into one dashboard, usually live in 2–3 weeks.
What does the Meta Conversions API do for lead generation?
The Conversions API is a server-to-Meta connection. Meta's Conversions API overview says server events are linked to a dataset ID and "are processed like events sent using the Meta Pixel", so they can be used for measurement, reporting and optimisation. For a lead-generation advertiser that matters in three places:
- Lost browser events. Ad blockers, iOS privacy settings, slow mobile networks in tier-2 cities and visitors who close the tab before the Pixel loads all drop browser events. A server event sent from your form handler does not depend on the visitor's browser.
- Better matching. Your server knows the email and phone the lead just typed. Sent hashed, they help Meta match the event to an account, which the Pixel alone often cannot do.
- Events that never happen in a browser. "Qualified", "Site visit done" and "Admission confirmed" are recorded in the CRM, days later. Only a server connection can send them. That CRM side is covered in our guide to tracking Meta ads leads to CRM and sales; this guide is about getting the website
Leadevent right first.
Meta's deduplication guide is explicit: "we recommend that advertisers implement the Conversions API alongside their Meta Pixel." CAPI is an addition to the Pixel, not a replacement.
If you run Instant Forms (lead ads inside Facebook and Instagram) only, there is no website event to send. You need the lead webhook and CRM events instead; the sibling guide above covers that path.
Which Conversions API setup path should you choose?
Meta's get-started page says the integration methods "vary by level of effort, cost, and the features they enable." In practice there are four:
| Path | How it works | Effort | event_id control | Fits |
|---|---|---|---|---|
| Partner integration | Your website platform or CRM sends server events once you connect it in Events Manager | Low: hours | Handled by the partner; check it is on | Shopify or WordPress sites with standard forms; teams without a developer |
| Conversions API Gateway | Meta's software runs in your own AWS or GCP account and relays browser events from a first-party endpoint | Medium: cloud admin needed | Handled by the Gateway for Pixel events | Businesses with a cloud account but little backend development time |
| Server-side GTM | The browser sends events to your tagging server, which forwards them to Meta with a CAPI tag | Medium to high | Full: you pass the ID through the data layer | Teams already running GA4 through server-side GTM |
| Direct API | Your form handler or CRM posts JSON to the Graph API /{DATASET_ID}/events endpoint | High: developer time | Full | Custom sites, lead-scoring backends, and anyone sending CRM stages |
Two notes on the Gateway. Meta's Gateway configuration page says it is provisioned inside your own cloud account and is "designed to have no interaction with business' server-side assets", so it can relay browser events but cannot see your CRM. You also pay the cloud hosting bill and own the uptime. Meta lists default capacity of 100 requests per second on AWS App Runner and GCP GKE, which is ample for most lead-gen sites.
Our default for Indian lead-gen clients: a partner integration if the site platform offers one, and a direct API call from the form handler when the site is custom-built or we need CRM stages later. The direct route costs more developer time once, but it is the only one that lets you send "Qualified lead" from the same code base.
Whichever path you choose, generate the access token in Events Manager (dataset, Settings, Conversions API, "Generate access token"). Meta notes only users with developer privileges see that link, and no App Review is needed.
How should you design the lead event?
Decide the event before writing code. A lead event that fires on the wrong action poisons optimisation whichever path you use.
| Decision | Our recommendation | Why |
|---|---|---|
| Event name | Standard Lead for a confirmed enquiry; Schedule for a booked call or visit; SubmitApplication for admission or loan applications | Standard events are understood by Meta's delivery system without a custom conversion |
| Fires when | The server accepts the submission (validation passed, record saved) | A button-click Lead counts failed and spam submissions |
event_id | Your own lead or submission ID, e.g. lead_20261011_48213 | Same ID can be sent from browser and server, and later from the CRM for stage events |
action_source | website for the form event | Meta's other values (phone_call, chat, physical_store, system_generated) are for CRM-stage events |
| Customer data | Email, phone, first name, city, external_id (CRM ID), fbc, fbp, IP, user agent | Raises Event Match Quality; see below |
| custom_data | lead_type, project or course, value and currency only if you use value-based bidding | Never send health conditions, financial details or other sensitive answers |
For a healthcare advertiser such as Advancells, where we ran worldwide patient enquiries at around ₹40 average CPL, the rule about sensitive data is not optional: the event says "a lead happened", never which treatment the patient asked about.
How does event_id deduplication work?
When the browser Pixel and the server both send the same lead, Meta keeps one. Per Meta's deduplication rules:
- The Pixel's
eventIDmust equal the server'sevent_id, and the Pixel event name must equal the serverevent_name. Both must match. - The Pixel's eventID is the fourth argument of
fbq('track', ...). - Duplicates are discarded only if they arrive within 48 hours of the first event with that ID, for the same Pixel/dataset.
- When both copies are similar, the one received first is generally kept.
- A fallback method using
fbpand/orexternal_idexists, but it only works when the browser event arrives first, so treat it as a backup, not the plan.
Generate the ID once, in the page, and hand it to both sides. For a form posted with JavaScript:
// 1. create one ID per submission attemptconst leadEventId = 'lead_' + Date.now() + '_' + Math.random().toString(36).slice(2, 8);// 2. send it to your server with the form fields (hidden field or JSON body)formData.append('event_id', leadEventId);// 3. after the server confirms success, fire the Pixel with the same IDfbq('track', 'Lead', {lead_type: 'site_visit'}, {eventID: leadEventId});
Your server then sends "event_id": "lead_..." in the CAPI payload. If you use GTM, push event_id into the data layer in the same success push that triggers your Meta tag, and map it in both the Pixel tag and the server-side tag.
How to confirm it works: in Events Manager, open the dataset's Overview and select the Lead event. It should show both "Browser" and "Server" as connection methods, and the deduplication view should show server events being matched to browser events rather than counted twice. If your Lead count doubled on the day CAPI went live, deduplication is not working; the fixes are in fixing duplicate conversions.
What does a lead event payload look like?
A website Lead sent from a form handler. Email and phone are SHA-256 hashes of the normalised values; IP, user agent, fbc and fbp are sent as plain text.
POST https://graph.facebook.com/{API_VERSION}/{DATASET_ID}/events?access_token={TOKEN}{"data": [{"event_name": "Lead","event_time": 1760165400,"event_id": "lead_1760165398123_k3x9qa","action_source": "website","event_source_url": "https://example.com/sector-150-3bhk","user_data": {"em": ["<sha256 of rahul.verma@example.com>"],"ph": ["<sha256 of 919876543210>"],"fn": ["<sha256 of rahul>"],"ct": ["<sha256 of noida>"],"country": ["<sha256 of in>"],"external_id": ["<sha256 of CRM-48213>"],"client_ip_address": "203.0.113.24","client_user_agent": "Mozilla/5.0 (Linux; Android 14) ...","fbc": "fb.1.1760160000000.IwAR...","fbp": "fb.1.1759900000000.123456789"},"custom_data": {"lead_type": "site_visit", "project": "sector-150"}}]}
Field rules from Meta's server event parameters and customer information parameters:
event_timeis a Unix timestamp in seconds. It can be up to 7 days in the past; if any event in a request is older, the whole request is rejected. Queue and retry failures within hours, not days.event_source_urlis required for website events, andclient_user_agentis required for website events sent through CAPI.- Hash
em,ph,fn,ln,ct,st,zpandcountrywith SHA-256. Hashingexternal_idis recommended. Never hashclient_ip_address,client_user_agent,fbcorfbp. - Phone: remove symbols, letters and leading zeros and include the country code before hashing. "098765 43210" and "+91-98765-43210" must both become
919876543210. - Email: trim spaces and lower-case before hashing. A single trailing space produces a different hash and no match.
What is Event Match Quality and how do you raise it?
Event Match Quality (EMQ) is Meta's score, out of 10, for how well the customer information in your server events can be matched to Meta accounts. Meta's CAPI best practices note that only matched events can be used for attribution and delivery optimisation, that EMQ is currently available only for web events, and that adding parameters such as email, IP address, name and phone "may help increase Event Match Quality." You see it per event in Events Manager.
| EMQ problem you see | Likely cause | Fix |
|---|---|---|
| Phone listed but match rate low | Numbers hashed with spaces, +, or a leading 0, or without 91 | Normalise to 91XXXXXXXXXX before hashing |
No fbc coverage | The _fbc cookie is not read server-side, or redirects strip fbclid | Pass the cookie in a hidden field; if missing, build it from fbclid on landing |
| IP shows your server's address | Handler sends REMOTE_ADDR behind a CDN or load balancer | Read the visitor IP from the forwarded header your CDN sets |
| Email coverage low | Form asks only for phone | Make email optional rather than absent; send external_id on every event |
| Score drops after a site change | New form builder stopped passing hidden fields | Add a weekly check of parameter coverage after every site release |
Meta also warns that fbc and fbp are cookie values that change, so read them at submission time rather than storing them once per contact.
How do you test the Conversions API before going live?
- Test Events tab. In Events Manager, open the dataset's Test events tab, copy the test code, and add it as
test_event_codeto your server payload during QA. Submit a real form on mobile data and on Wi-Fi. - Check both sources arrive for the same submission, with the same
event_id, and that only one is counted. - Check parameters. The event detail should list email, phone, IP, user agent, fbc and fbp as received. A missing
fbcon an ad click means your landing flow losesfbclid. - Test failures. Submit with an invalid phone and confirm no Lead fires from either side. Reload the thank-you state and confirm nothing re-fires.
- Remove the test code, publish, and compare the next 7 days of Lead events against form submissions in your CRM. A gap of a few per cent is normal (consent, bots filtered by your form); a gap of 30% means something is broken.
- Consent. Under India's DPDP Act 2023, sharing hashed contact details with an ad platform is processing of personal data. Mention ad measurement in your form's notice and privacy policy, and do not send events for visitors who declined it.
What are the common Conversions API mistakes in lead generation?
- Different event names on each side. Pixel sends
Lead, server sendsleadorSubmitForm. Deduplication needs an exact name match, so you count every lead twice. - A new random ID on each side. The browser and server each generate their own
event_id, which guarantees duplicates. Generate once, pass to both. - Two partner integrations at once. A WordPress plugin and a CRM connector both sending server Leads. Keep one server source per event.
- Firing on click. Covered in detail in our form tracking guide: fire on confirmed success only.
- Optimising for Lead forever. CAPI improves signal volume, but a Lead is still a form fill. Once your CRM can send qualified stages, move optimisation closer to revenue. Our attribution and lead tracking guide explains how to keep the CRM as the source of truth across Meta and Google.
Sources
- Meta for Developers: Conversions API (server events processed like Pixel events, linked to a dataset)
- Meta for Developers: Get started (integration methods, access token generation)
- Meta for Developers: Deduplicate Pixel and server events (event_id + event_name, 48-hour window, fbp/external_id method)
- Meta for Developers: Server event parameters (7-day event_time limit, action_source values, event_source_url)
- Meta for Developers: Customer information parameters (hashing and phone normalisation rules)
- Meta for Developers: Conversions API best practices (EMQ score out of 10, web events only, fbc/fbp refresh)
- Meta for Developers: Gateway products configuration (self-hosted in your cloud, default capacity)
