Offline conversion tracking: send CRM deals back to Google Ads
Get your closed CRM deals back into Google Ads so bidding optimizes toward revenue, not form fills. The full setup, the 2026 Data Manager migration most guides miss, and the two silent failures that quietly zero out your imports.

Your Google Ads report is full of conversions. Your sales team closed a handful of real deals. Smart Bidding is optimizing toward the first number, because the deals that became revenue closed weeks later in a CRM it can't see. Offline conversion tracking closes that gap: it sends those closed deals back into Google Ads, matched to the ad click that created each one by its GCLID (or by hashed email, via enhanced conversions for leads). Without it, lead-gen accounts bid toward form fills instead of revenue: Smart Bidding optimizes for the $0 event it can see, not the $50k contract it can't.
One scope note before the plumbing: "offline conversions" means two different things depending on your business. For B2B and lead-gen (this article) it means deals that close later in the funnel, in your CRM, matched back to the click by GCLID or hashed email. For retail and ecommerce it means literally offline transactions: in-store purchases matched through POS or loyalty data (Google's store sales uploads, hashed customer records), a different mechanism with different plumbing, and it gets its own guide. If you're here for in-store sales, that one's for you.
A quick Google search will tell you to "upload the file," and that's the easy 20%. The game is won or lost weeks earlier, at GCLID capture, where the two failure modes that actually kill imports (missed capture and import lag) are both silent. This guide walks the full CRM-side path, including the June 2026 Data Manager migration that most ranking guides predate.
#How the match works: one ID travels the whole pipeline
The entire system is one string making a round trip. When auto-tagging is on,
Google appends a gclid parameter to your final URL at click time. Your
landing page writes it into a hidden form field; your CRM stores it on the
lead; and when the deal closes, days or weeks later, you upload that same
GCLID with a conversion name, a conversion time, and a value. Google matches
it to the click and credits the campaign, ad group, and keyword that earned
it.
Two properties of this match decide everything downstream. It is deterministic (one GCLID matches exactly one click, so there's no modeled fuzziness) and perishable: the conversion must land inside the conversion action's click-through window, at most 90 days after the click. Everything below exists to keep that string alive for the round trip.
#Step 1: capture the GCLID before it evaporates
The GCLID exists for exactly one pageview unless you persist it. It arrives as a URL parameter and dies on the first navigation, which is why capture, not upload, is where most implementations fail. The standard pattern:
- Turn on auto-tagging (Google Ads → Account settings → Auto-tagging). Without it there is no GCLID at all. Manual UTM tagging does not replace it: UTMs are labels you write; the GCLID is the key Google matches on.
- Persist the parameter. A small script reads
gclidfromlocation.searchon landing and writes it to a first-party cookie orlocalStorage, so it survives the browse to your demo page. - Write it to a hidden field on every lead form, mapped to a dedicated CRM property.
Where it silently drops (each of these is a real stack, not a hypothetical):
form tools that rebuild their embed URL and strip query parameters; www or
https redirects that discard the query string; consent banners that block
the persistence script itself; single-page apps that route past the landing
URL before the script runs; and forms added later that never got the hidden
field. Test the whole chain by clicking your own ad: the GCLID must be
visible on the CRM lead, not just in the URL bar.
#Step 2: store it in the CRM like the match key it is
The CRM field spec is stricter than it looks. Three rules:
- One dedicated field, text type, no processing. In HubSpot a custom contact property; in Salesforce a text field on Lead/Opportunity. GCLIDs are long, so size the field generously: truncation produces a non-matching ID with no error anywhere.
- Case-sensitive, stored verbatim. Google matches the GCLID exactly as issued (Google's GCLID import doc). A CRM or middleware layer that lowercases "for consistency" zeroes your match rate while everything looks fine.
- First click wins, and the ID follows the money. Store the GCLID at lead creation and don't overwrite it on later visits; make sure it travels the lead → opportunity conversion, since the upload happens when the deal closes, not when the form fires.
#Step 3: structure the import so Google accepts it
An import row is five columns; four of them have sharp edges. Per Google's import documentation:
| Column | Rule | The sharp edge |
|---|---|---|
| Google Click ID | Verbatim GCLID | Case-sensitive; no truncation |
| Conversion Name | Must exactly match the import-type conversion action in Google Ads | A typo means silent non-attribution |
| Conversion Time | Deal-close time, after the click time | Timezone: append the offset or set it account-wide; a wrong zone pushes edge conversions outside the window |
| Conversion Value | Deal value | Without it you've rebuilt equal-weighted counting (see Value-based bidding needs values you can trust) |
| Currency | ISO code per row | Mixed-currency exports that skip it get one wrong default |
The window rule once more, because it drives cadence: a conversion uploaded 91 days after its click imports as nothing. For most B2B sales cycles 90 days is enough, but only if your import runs on schedule, which is Step 4's job.
#Step 4: upload, and mind the June 2026 Data Manager cutover
The upload landscape changed in 2026, and most ranking guides predate it. Google is migrating offline conversion uploads to the Data Manager API; legacy Google Ads API upload paths are blocked from June 15, 2026 (your guide to upgrading offline conversion imports). What that means in practice:
- Scheduled imports (Google Sheets on a daily schedule, or direct HubSpot/Salesforce connectors) now run through Data Manager. Set them up there, not against the deprecated endpoints.
- Custom integrations built on the old Google Ads API upload services need migrating now; after the cutover they fail, and they fail on the Google side where your CRM won't alert you.
- Manual CSV uploads remain for backfills and testing, but a manual-upload habit is an import-lag generator, so schedule it.
Pick the connector when one exists for your CRM (it inherits the schema and retries); pick a scheduled Sheet when you need transformation between CRM and Ads (currency normalization, conversion-name mapping); build against Data Manager directly only when neither fits.
#The two silent killers: missed capture and import lag
Both failure modes produce zero errors. That's what makes them killers: the pipeline "works," Google accepts the file, and the account quietly bids blind.
Missed capture is the bigger one. Every lead whose GCLID never reached the CRM is invisible to the import forever: no error string, just a lower match rate. Detection is one CRM report: percentage of ad-sourced leads (UTM- or referrer-identified) with a populated GCLID field, trended weekly. A drop in that report is a form change, a redirect, or a consent update, so find which within the week, because those leads don't backfill.
Import lag is subtler: the conversions arrive, but late, and Google Ads books each one against its click date, not the upload date. A three-day cadence means every import rewrites the recent past: yesterday always looks like your worst day, last-click-week metrics wobble with the import schedule, and a "why did conversions crash this week" panic is often just Tuesday's file not having run. If your Google Ads and GA4 numbers already disagree, lag is one of the standard causes, and Why your GA4 and Google Ads conversions don't match walks the full triage.
Our position: this is exactly why offline tracking is an operations problem, not a setup task. Both killers are trivially detectable with two monitored numbers (GCLID coverage and import recency) and invisible without them.
#GCLID import vs enhanced conversions for leads
The GCLID import is the primary path; enhanced conversions for leads is the fallback match: know which you're on. Enhanced conversions for leads matches on hashed email instead of click ID: the form captures an email, Google hashes it, and the match happens against signed-in Google users. Choose by constraint:
- GCLID import when you can capture and store the click ID reliably: the match is deterministic, works without an email match, and carries per-deal values cleanly.
- Enhanced conversions for leads when GCLID capture keeps failing (long redirect chains, hostile form tooling, phone-first funnels) or as a resilience layer beside the GCLID path. Setup in Enhanced conversions for leads: CRM matching for B2B.
If your GCLID coverage report (above) is healthy, run the GCLID path. If it's structurally broken and unfixable, don't limp: switch to the email match.
#Import values, not just counts
A count-only import upgrades Smart Bidding from blind to nearsighted; values finish the job. Upload the actual deal amount in the Conversion Value column and bidding strategies like tROAS optimize toward revenue instead of lead volume: the difference between "efficiently buying meetings" and buying customers. This is the values argument in one line; the full case, including when not to switch strategies yet, is Value-based bidding needs values you can trust.
#Verify it's working
Verification has a built-in delay: imported conversions take 24 to 48 hours to appear in reporting, so don't judge an import before then. The checklist:
- Upload diagnostics (Data Manager / Conversions → Uploads): rows
received vs matched, with per-row error strings for the failures like
unparseable gclid, click outside the window, or conversion name mismatch (Google's discrepancy-fixing guide decodes them). - Match rate over time, not just launch day: capture defects show up here first.
- Campaign-level sanity: imported conversions should concentrate in the campaigns that plausibly source pipeline.
Run this weekly, not once: the full account-wide routine lives in The conversion tracking QA checklist: test it like you'd test code.
Offline conversion tracking is a pipeline, and pipelines drift: forms change, redirects appear, connectors stall, cutover deadlines pass. Every one of those is silent, which is why the accounts that stay accurate are the ones watching two numbers, GCLID coverage and import recency, on a standing cadence rather than remembering to look. That standing check is the part worth handing off: Buron watches yours continuously (GCLID coverage, import recency, match rate) so a stalled import becomes a finding in your inbox, not a quarter-end surprise.
Frequently asked questions
How does offline conversion tracking work?
Google Ads auto-tagging appends a GCLID to every ad click. You capture that GCLID in a hidden form field, store it on the lead in your CRM, and when the deal closes you upload the GCLID with a conversion name, time, and value. Google matches it to the original click and credits the campaign.
How do I set up offline conversion tracking in Google Ads?
Four steps: enable auto-tagging so clicks carry a GCLID; capture the GCLID into a hidden form field and write it to the CRM lead; create an import-type conversion action in Google Ads; then upload closed deals (GCLID, conversion name, time, value) on a schedule via Data Manager or a CRM connector.
How long do I have to upload an offline conversion?
The conversion must land within the conversion action's click-through window, at most 90 days after the click. Upload on a daily cadence where you can: imports take 24 to 48 hours to process, and Google Ads books each conversion against the click date, so late uploads keep rewriting your recent reports.