A marketing team connects Meta Lead Ads to their CRM, watches leads land in real time, and calls the integration done. Six weeks later cost per lead is down and cost per customer is up. The ad platform has been optimising hard for the thing it can see — form fills — and it has got very good at finding people who fill in forms and never buy.
Nothing is broken. The integration was only ever built in one direction.
Connecting a CRM to Meta, Google or LinkedIn is two separate pieces of plumbing with different failure modes. Leads flowing in is the visible one. Revenue flowing back out is the one that changes the bidding, and it is the one that quietly does not get built, because nothing looks wrong when it is missing.
The inbound half is a solved problem
Getting a lead from an ad platform into a CRM has three implementations, in ascending order of how much you should want them.
Native connector. HubSpot, Salesforce and Zoho all ship a Meta and Google integration you authorise in a settings screen. It works. It maps a fixed set of fields, it is opaque when a lead does not arrive, and you will hit its edges the first time you need a custom field or conditional routing.
Webhook to your own endpoint. Meta will POST a leadgen_id to a subscribed endpoint the moment a form is submitted; you then call the Graph API to retrieve the field values. Google's Lead Form extensions do something similar. More work, complete control, and you own the retry behaviour — which matters, because a webhook you do not retry is a lead you silently lost.
Polling on a schedule. A workflow asks the platform for leads created since the last run. Simplest to reason about, and it needs a watermark on the record rather than a time window in the schedule, or a missed run costs you leads permanently.
Whichever you pick, the field to obsess over is not name or email. It is the click identifier.
The click identifier is the whole game
Every platform stamps its own identifier on the click, and everything downstream depends on that string surviving.
| Meta | Google Ads | ||
|---|---|---|---|
| Click parameter | fbclid on the URL | gclid (or gbraid / wbraid) | li_fat_id |
| Stored as | _fbc cookie, formatted | gclid, stored verbatim | li_fat_id cookie |
| Send conversions via | Conversions API | Offline conversion import | Conversions API |
| Also matches on | Hashed email and phone | Hashed email | Hashed email |
| Lead-ad shortcut | leadgen_id, no click ID needed | Lead form submission ID | Lead gen form response |
That identifier arrives on a URL, gets read by a script, and has to be written onto a hidden form field, then onto the contact, then carried to the deal. Five hops, each one optional, each one a place where it stops.
01T+0
Ad click
gclid / fbclid on the landing URL
02T+90s
Hidden form field
only if someone added it to this form
03T+2m
CRM contact
custom field, write-once
04T+9d
Deal created
often manually, by a rep, with no link
05T+74d
Closed won
amount is here; the click ID needs to be too
The fourth hop is where most implementations break, and it breaks for an organisational reason rather than a technical one. A rep has a good call, creates a deal from scratch, and the association back to the originating contact never gets made. The revenue exists. The path to it does not. This is the same failure that quietly caps how much of your revenue any attribution model can see.
The outbound half is what changes the bidding
Once a deal closes, you send an event back saying this click, this amount, this date. Meta calls it the Conversions API. Google calls it offline conversion import. LinkedIn calls it the Conversions API too.
The mechanics differ; the shape does not. You are sending back the click identifier you preserved, a conversion name, a timestamp, and a value. Where the click identifier is missing you can fall back to hashed identifiers — email and phone, lowercased, trimmed, SHA-256 — and the platform will match on those instead, at a lower match rate.
This matters because it changes what the algorithm optimises towards. Feed the platform form fills and it will find you form fills. Feed it £40,000 closed-won deals and it starts finding people who look like the ones who paid you. That is not a reporting improvement — the bidding behaviour genuinely changes.
Two things to get right:
Send the value, not just the event. A conversion with no value tells the platform all customers are worth the same. If your deals range from £2k to £80k, that is throwing away most of the signal you just went to the trouble of connecting.
Deduplicate. If the same conversion arrives from both the pixel and the server, you will double-count. Every platform supports an event ID for this. Set it deliberately from something stable — the deal ID — rather than generating one per send.
When the sales cycle outlasts the upload window
Here is the constraint that actually decides the design, and the one nobody mentions in the setup guide.
Each platform will only accept conversions within a bounded window after the click. That window is measured in weeks and a couple of months, not in quarters, and the exact figure has changed more than once — check the current documentation rather than trusting a number in an article, including this one.
If your average sales cycle is longer than that window, closed-won revenue can never be sent back. The deal closes after the platform has stopped listening.
The fix is not to argue with it. Pick an earlier event as the thing you optimise on — a qualified opportunity, a completed discovery call, a stage the pipeline reaches inside the window — and send that back with an expected value rather than a realised one. You lose precision and you keep the feedback loop. Then check quarterly whether that proxy still correlates with revenue, because if it drifts, you are optimising towards a milestone that no longer predicts money.
Getting there requires knowing your actual cycle length rather than the one in the pitch deck. That is a straightforward query against stage history, and it is worth running before designing any of this — sales cycle analysis is the input to the decision, not a separate project.
Consent, and what you are allowed to send
Sending customer data to an advertising platform is a processing activity, and the platforms push the compliance obligation to you in their terms. Two practical consequences.
Hash before you send. Email and phone go as SHA-256 of the normalised value — lowercase, whitespace stripped, phone in E.164. Every platform's SDK will do this, and every platform's API will also happily accept plaintext if you send it, which is how plaintext ends up in request logs.
Respect the consent state you captured. If someone declined advertising cookies, the click identifier should not exist for them and you should not be substituting hashed email to make up the match rate. Whatever your consent mechanism records needs to reach the point where the conversion upload decides whether to include a record — which usually means a flag on the contact, not a lookup at send time against a system that has since forgotten.
Sales Navigator is a different thing
Worth separating, because it gets grouped with the ad platforms in the same request. LinkedIn Sales Navigator is a prospecting tool, and its CRM integration writes activity — InMails, saved leads — back to the CRM. It is not an advertising conversion path, and there is no revenue signal going back to it. If the ask is "connect our CRM to Sales Navigator", that is a seat licence and a sync, not the two-way loop described here.
The check worth doing today
Pull ten closed-won deals from last quarter. For each one, try to find the click identifier — gclid, _fbc, or li_fat_id — on the associated contact record.
If you find it on eight, your plumbing is sound and the outbound half is worth building this month. If you find it on two, building the return trip now would send the platform a biased sample of your best customers, which is worse than sending nothing. Fix the hops first. The field mapping and routing work that keeps the identifier attached is unglamorous, and it is the entire foundation the rest of it sits on.
Common questions
- How do I connect my CRM to Meta ads?
- There are two connections, not one. Inbound, you subscribe to Meta''s leadgen webhook or use your CRM''s native connector to pull lead ads into the CRM. Outbound, you send conversions back through the Conversions API using the _fbc value derived from the fbclid on the original click. The inbound half is what most teams build; the outbound half is what changes how Meta bids.
- What is a gclid and why does it matter?
- The gclid is the identifier Google Ads appends to the landing page URL on every ad click. It is how Google recognises a conversion you upload later as belonging to a specific click, campaign and keyword. If it is not captured on the form and carried through to the deal record, offline conversion import can only fall back to matching on hashed email, at a materially lower match rate.
- What if my sales cycle is longer than the conversion upload window?
- Then closed-won revenue can never be sent back, because the platform stops accepting conversions for a click after a bounded period measured in weeks to a couple of months. Send an earlier milestone instead — a qualified opportunity or completed discovery call — with an expected value rather than a realised one. Re-check quarterly that the proxy still correlates with revenue.
- Do I need to hash customer data before sending it to an ad platform?
- Yes. Email and phone should be sent as SHA-256 of the normalised value: lowercased, whitespace stripped, phone in E.164 format. Every platform SDK will do this for you, and every platform API will also accept plaintext without complaint, which is how unhashed customer data ends up in request logs.
- Is connecting a CRM to Sales Navigator the same thing?
- No. Sales Navigator is a prospecting tool, and its CRM integration writes activity such as InMails and saved leads back to the CRM. There is no advertising conversion loop, so no revenue signal goes back to it. That request is a seat licence and a data sync, not the two-way conversion plumbing that Meta and Google Ads need.
- CRM
- Integration
- Attribution
- Paid Media