- A bad lead is a bidding instruction, not a sales problem. The platform optimizes toward whatever you last reported.
- Google matches on GCLID, GBRAID, or WBRAID, or on normalized hashed user identifiers. [1]
- Meta accepts an event_time up to seven days old, and one stale event fails the entire request. [3]
- Google names no general upload window in its docs, only a same-month rule for Hotel ads commissions. [1]
- Weight stages by expected value: close probability times average deal size.
- Restate one conversion as the deal progresses. Do not fire a new one per stage. [5]
- Google says do not hash city, state, zip, or country. Meta requires hashing all four. [1][4]
- Populate the consent field. Google warns conversions may not be attributable without it. [1]
Somewhere in your CRM there is a record marked disqualified, timewaster, or student project. Somewhere in your ad account there is a campaign that considers that same record a success, because a form was submitted and the form was the finish line.
Nobody ever told the campaign otherwise. So it went and found more people like that, which is precisely what it was built to do, and it will keep doing it with impressive efficiency for as long as the only outcome it is ever shown is a submission.
This is the whole problem, and it is worth stating in a way that survives contact with a sales meeting: a bad lead is not a sales problem, it is a bidding instruction. Fixing it means changing what the algorithm is told a success looks like, which is a plumbing job with three specific traps in it.
What travels back, and on what key
Google’s offline conversion upload accepts a click identifier or hashed user data. The click identifiers come in three flavors, and the two obscure ones exist for iOS: GBRAID is present when someone clicks a web ad and is directed into your iOS app, WBRAID when the click starts in an iOS app and lands on your webpage. [1] Enhanced conversions for leads takes the other route, described by Google as “an updated offline conversion import that utilizes first-party data, such as your customer email or phone number, to get the most accurate measurement and performance.” [2]
On the Meta side the same job runs through the Conversions API, which exists to connect data from a server, a website platform, an app, or a CRM into the systems that optimize delivery. [6]
The operational point underneath all of them is the same and it is unforgiving. Whatever key you intend to match on has to be captured at first touch and stored on the record. A click identifier that was not written into the CRM when the form was submitted cannot be reconstructed six weeks later from anything. This is the single most common reason a closed-loop project stalls in month three: the pipeline is built, the values are agreed, and the historical records have nothing to join on.
Capture at the form, not at the deal
Write the click identifier and a stable record ID into the CRM at submission. Store consent alongside it, in the same write.
Cannot be backfilledDecide the one event you will report
Pick the earliest stage that both correlates with revenue and arrives inside the platform’s window. For most B2B that is a qualified lead, not a closed deal.
The optimization targetSend it once, with an expected value
One conversion per record, valued at close probability times average deal size. Not one conversion per stage.
Avoids triple countingRestate the value as reality arrives
When the record advances or closes, upload an adjustment against the same order ID rather than a new conversion. Retract it if it turns out to be junk.
The return legReconcile daily and log what failed
Match rate is a metric you own. Track uploaded, matched, and rejected every run, because silent partial failure is the normal failure here.
Observability
The window, which only one platform documents
Meta is explicit and strict. The event_time parameter “can be up to 7 days before you send an event to Facebook,” and it adds the consequence that catches everyone: “If any event_time in data is greater than 7 days in the past, we return an error for the entire request and process no events.” [3] One badly dated record does not get skipped. It takes the batch down with it, which means your uploader needs to filter and quarantine before sending rather than discovering this in a 400 response.
Google is quieter. Its offline conversion upload documentation names no general limit between click and upload, mentioning only that commissions for Hotel ads can be imported for clicks in the same month. [1] Various day counts circulate in the industry as hard limits. They are not in the documentation, and building a nine-month pipeline strategy on a number nobody publishes is a poor bet in either direction.
Either way the strategic conclusion holds. If your sales cycle is longer than the window you can rely on, closed-won will not be your optimization event. That is not a defeat. It just moves the revenue information out of the timing and into the value.
Stage weights, computed rather than borrowed
The mechanism is expected value: what a record at this stage is worth on average, given how often records at that stage eventually close.
| Stage | Historical close rate to won | Value sent | What it says to the algorithm |
|---|---|---|---|
| Marketing qualified | 0.04 | $960 | Worth having, worth very little |
| Sales qualified | 0.12 | $2,880 | Three times the previous stage |
| Opportunity | 0.35 | $8,400 | Nearly nine times an untouched lead |
| Closed won | 1.00 | $24,000, actual | The truth, usually arriving too late to bid on |
Those figures come from one worked example with a $24,000 average contract value. The numbers that matter are yours: take each stage, compute what fraction of records at that stage historically became revenue, and multiply by your average deal. Borrowing someone else’s close rates produces a weighting scheme that describes their funnel and misprices yours.
Two cautions. This only works if your stage definitions are stable, so a CRM where anybody can drag a card into opportunity will encode that habit into your bidding. And the ratios matter more than the absolute values, because the algorithm is learning relative worth.
The double-counting trap
Here is the mistake that survives review because it looks like thoroughness.
A record becomes an MQL and fires a conversion worth $960. Three weeks later it becomes an SQL and fires another worth $2,880. It becomes an opportunity and fires a third at $8,400. One deal has now reported three conversions and $12,240 of value, and your cost per acquisition has silently improved by a factor of three while your reported value bears no relationship to anything.
The correct shape is one conversion per record, restated as it progresses. Google’s API supports exactly this: a RESTATEMENT replaces the conversion value while the conversion stays counted, and a RETRACTION removes it entirely when the lead turns out to be worthless. Both are matched on the order ID you supplied at upload. [5] That gives the algorithm a truthful, sharpening estimate of one thing rather than a growing pile of duplicates, and it means a disqualified lead can actually be taken back rather than merely stopping its ascent. The same discipline that keeps e-commerce conversion values honest after refunds is what keeps a pipeline honest after disqualification.
The hashing spec the platforms disagree on
Google: SHA-256 on email address, phone number, first name, last name, and street address. Country, state, city, and zip code are explicitly not to be hashed. [1]
Meta: hashing required on email, phone, first name, last name, date of birth, gender, city, state, zip, and country, with its own normalization rules such as two-letter lowercase country codes and state abbreviations. [4]
This is not a detail to delegate to whoever writes the integration. Sending Meta an unhashed city or Google a hashed one degrades match rate quietly, and match rate is the entire leverage of the exercise. Normalize first, hash second, and keep the two platform payloads as genuinely separate transformations rather than one payload with a flag.
Consent belongs in the same conversation. Google’s documentation is direct that it is “highly recommended that you populate the consent field of the ClickConversion object” and that without it, conversions may not be attributable. [1] Consent captured at the form has to travel with the record for months, which is a schema decision you make at the start or retrofit painfully later.
What to expect, honestly
The vendor case studies for this are plentiful and the independent evidence is thin. There is no credible primary research isolating offline conversion uploads from the several other things that change when a team finally builds this. The mechanism is sound, the reasoning is sound, and the proof will have to come from your own account.
Which means the last piece of the build is a way to tell. Hold a segment, a region, or a campaign on the old signal for a full sales cycle, and compare lead-to-opportunity rate rather than lead volume. Expect volume to fall and quality to rise, because you have just told the system that most of what it was buying does not count. If nobody warns the person who watches the lead-count dashboard, that improvement will be reported as a failure in week two.
- Write the click identifier, a record ID, and consent into the CRM at form submission, before anything else is built.
- Pick one optimization event, the earliest stage that correlates with revenue and lands inside the window.
- Compute stage values from your own close rates, not from a benchmark.
- Send one conversion per record and restate it. Never fire a new conversion per stage.
- Filter and quarantine stale events before sending to Meta, so one bad row cannot fail the batch.
- Build the Google and Meta payloads as separate transformations, because the hashing rules genuinely differ.
- Report uploaded, matched, and rejected counts on every run, and alarm on match-rate drops.
- Hold a control segment for one full sales cycle, and tell the dashboard owner that lead volume is supposed to fall.
Sources
- Google Ads API · Upload offline conversionsGCLID, GBRAID, and WBRAID definitions, the SHA-256 hashing list with country, state, city, and zip excluded, the consent field recommendation, and the Hotel ads same-month restriction as the only stated window
- Google Ads API · Enhanced conversions for leadsan updated offline conversion import using first-party data such as customer email or phone number
- Meta for Developers · Conversions API: server event parametersevent_time up to seven days before sending, and an error for the entire request with no events processed if any event is older
- Meta for Developers · Conversions API: customer information parametersthe fields requiring hashing, including city, state, zip, and country, with normalization rules for each
- Google Ads API · Upload conversion adjustmentsRESTATEMENT and RETRACTION semantics, and order ID as the preferred match key
- Meta for Developers · Conversions APIthe connection from an advertiser’s server, website platform, mobile app, or CRM into Meta’s optimization systems
Frequently asked questions
Why does my ad platform deliver so many low-quality leads?
Because a submitted form is the only outcome it has ever been shown. Smart Bidding optimizes toward the conversion you report, so if the reported conversion is a form fill, it will find the population most likely to fill in forms. That is not a targeting failure, it is the instruction being followed accurately.
What identifiers can I use to match a CRM record back to an ad click?
Google accepts a GCLID, a GBRAID, or a WBRAID, or normalized and hashed user identifiers such as email, phone, name, and address. GBRAID is present when a user clicks a web ad and lands in an iOS app, WBRAID when the click starts in an iOS app and lands on your webpage. Capture whichever exists at first touch, because you cannot recover it later.
How far back can I upload an offline conversion?
It depends on the platform, and only one of them publishes a number. Meta states that event_time can be up to seven days before you send the event, and that a single older event causes an error for the entire request with no events processed. Google’s upload documentation names no general limit, mentioning only a same-month restriction for Hotel ads commissions.
My sales cycle is nine months. Can closed-won ever reach the bidding algorithm?
Usually not as a closed-won event, which is why stage weighting exists. You optimize toward the earliest stage that correlates with revenue and arrives inside the window, and you carry the revenue information in the value rather than in the timing.
How do I set values for pipeline stages?
Use expected value: the probability that a record at this stage eventually closes, multiplied by average deal size. With a $24,000 average contract and historical close rates of 0.04 from MQL, 0.12 from SQL, and 0.35 from opportunity, the stage values are $960, $2,880, and $8,400. These are your close rates, not anyone else’s benchmark.
Should I fire a new conversion at each pipeline stage?
No, and this is the most common way the build goes wrong. Firing at MQL, then SQL, then opportunity records three conversions for one deal and inflates everything downstream. Send one conversion and restate its value upward as the record progresses, using a conversion adjustment keyed on the order ID.
Do Google and Meta hash the same fields the same way?
No, and assuming they do is a real source of low match rates. Google requires SHA-256 hashing of email, phone, first name, last name, and street address, while explicitly stating that country, state, city, and zip should not be hashed. Meta requires hashing on city, state, zip, and country as well. The normalization rules differ too.
What about consent?
It is a field, not an afterthought. Google’s documentation highly recommends populating the consent field on the uploaded conversion and warns that without it your conversions may not be attributable. Consent has to be captured at collection time and travel with the record, which is a CRM schema decision made long before the first upload.
Is there hard evidence this improves lead quality?
Not in the form of independent studies isolating it. The mechanism is sound and the vendor case studies are numerous, but there is no credible primary research separating the effect of offline uploads from everything else changed at the same time. Treat it as a well-reasoned change to your optimization target, and prove it in your own account with a holdout.




