rytisbalys.com / troubleshooting

Offline conversions: getting real sales back into Google Ads (when your CRM fights you)

If Google Ads only sees form fills and calls, Smart Bidding chases cheap leads that never close. Offline conversions send the actual sale back to the click that caused it - here's the flow, and the specific places it breaks in real accounts.

The problem is rarely the tracking, it's what you're optimizing on. Google Ads counts the form submit or the phone call as the conversion, so bidding learns to produce more of whatever is cheapest to generate - not the leads that turn into revenue. The fix is to feed the real outcome (the sale, the signed quote) back to Google, tied to the click that started it. Almost every failure comes down to one of two things: the gclid not surviving the trip into your CRM, or the upload getting silently rejected.

01Create the conversion action first

Before you touch the website, build the destination. Google Ads > Goals > Conversions > New conversion > Import > conversions from clicks. This is a separate bucket from the form-fill conversion - the closed deal lands here. Set count and value to match one real sale, not a lead.

VERIFY - the action shows up as "No recent conversions", then flips to "Recording conversions" after your first upload. If it isn't listed, nothing you upload has anywhere to land.

02Capture the click ID at the moment of the lead

When someone arrives from a Google ad, the Conversion Linker (a GTM tag, or gtag auto-tagging) drops a first-party _gcl_aw cookie holding the gclid. Read that cookie into a hidden field on your lead form so it's saved with the name, email and phone into whatever receives the lead. One catch most setups miss: on some iOS and in-app traffic Google hands you a wbraid or gbraid instead of a gclid - capture whichever one is present.

VERIFY - load your form from a URL with ?gclid=test123, submit, and check the record actually carries it. Empty field = the capture is where you fix things, not the upload step.

03Where to store the click ID when your CRM has no field for it

This is where it usually breaks. Jobber, Housecall Pro, and a lot of dealership and home-service CRMs either give you no field to hold the gclid or won't export it. If the CRM takes any custom field - Jobber does - put it there. If it's fully locked, route the lead through a thin layer first that keeps the gclid mapped to the lead by email/phone, then hands the clean lead on to the CRM:

a form / call tracker   WhatConverts, CallRail
an automation step      Zapier, Make
a plain spreadsheet     Google Sheet keyed on email + phone
VERIFY - trace one lead the whole way: ad click, cookie, hidden field, CRM record (or the middle layer). The gclid has to be readable at the point where you'll later learn the deal closed.

04Upload on the real milestone, with the real value

When the lead becomes a sale - or quote-approved, whatever "real" means for the business - export the gclid, the conversion time, the value and the conversion action name, and send it up. Roughly in order of effort:

manual CSV         Conversions > Uploads
scheduled Sheet    a recurring upload from Google Sheets
SFTP / Ads API     once the volume justifies it
native connector   if your CRM ships one

Value matters as much as the count - a $12k job and a $300 job feeding back as the same conversion teaches bidding the wrong lesson. And the uploads that get silently rejected are almost always the same three: a conversion timestamp that sits before the click, a timestamp with no timezone offset, or a click that's older than the 90-day import window.

VERIFY - a day or two after an upload, the action's count and total value match what you sent. If rows went missing, open the upload log - it lists each rejected row and the reason.

05When the click ID can't survive: Enhanced Conversions for Leads

Sometimes the gclid just doesn't make it - the form sits on a different subdomain, the CRM strips query data, or the record predates your capture fix. For google-click leads where the gclid got lost (not third-party directory leads - those never had a click to attribute), use Enhanced Conversions for Leads instead. You upload hashed email/phone on the conversion and Google matches it back to the click on its side. Every CRM has the email and phone even when it won't hold a gclid. The catch: it only recovers leads that genuinely came from a Google click, and you have to accept the customer-data terms.

VERIFY - Google Ads > Conversions > the action's diagnostics reports a match rate on the hashed data. A rate near zero means the hashing format is wrong or the terms toggle isn't on.

06Reconcile once a month - it rots quietly

Offline import is not set-and-forget. A CRM export change or a broken cookie capture stops feeding it with no error anywhere. Once a month, line up the conversions Google recorded against the deals your CRM actually closed from paid traffic for the same window - the same reconcile-against-the-real-numbers habit that keeps GA4 honest.

VERIFY - Google shows 40 closed-deal conversions, the CRM shows 90 closed from paid: the pipe is leaking between capture and upload. Start again at step 02 and follow one lead through.

The one-line rule

Don't optimize on the form fill. Send the signed deal back with its real value, mind the timestamp and the 90-day window, and reconcile monthly - then bidding chases the money instead of the cheapest click.

Leads coming in but the sales never get back to Google? I build offline-conversion pipelines - gclid capture, CRM export, Enhanced Conversions for Leads - with monthly reconciliation so they don't silently rot. The same verify-everything approach I run on my own work.

work@rytisbalys.com