Google Ads offline conversions are outcomes that happen after the click and off your website (a booked estimate, a signed contract, a closed listing) that you send back to Google Ads tied to the original click so bidding learns from revenue rather than form fills. The setup has three parts: capture the click identifiers (gclid, gbraid, wbraid) into hidden form fields and store them on the lead in your CRM, decide which stages actually predict revenue, and upload those stage changes with a value through a Google Sheets template, the API, Zapier or HubSpot's native sync. This piece walks a contractor, clinic or brokerage through all three, plus the 90-day click limit, the conversion window most people miss, enhanced conversions for leads as the fallback, and the time zone errors behind most rejected uploads.
An offline conversion is a conversion you import into Google Ads rather than one measured by a tag on your site. Google matches it to the click by the click identifier you send, or by a hashed email or phone number in the case of enhanced conversions for leads.
Why leads are the wrong thing to optimize.
Every ad account starts by counting form submissions and calls as conversions, which is the right first step and the wrong last one. A form fill costs the same whether it becomes a full roof replacement or a tire kicker asking for a free inspection. If bidding only sees form fills, it finds the keywords, audiences and hours that produce the cheapest form fills, which are rarely the ones that produce the best jobs.
The effect compounds because Smart Bidding is a learning system. Feed it booked estimates with values for a few months and it bids more on the searches that look like your sold jobs. We have built this for home builders, remodelers and brokerages, and the account starts spending differently before anyone touches a bid. See how this fits a builder's lead system and a brokerage's.
Capture the click ID on every lead.
When someone clicks a Google ad, Google appends a gclid parameter to the landing URL. Where the gclid is restricted, Google instead appends gbraid or wbraid, so capture all three. The parameter only exists on the landing page URL; if the visitor moves to a second page before filling in a form, it is gone unless you stored it.
The standard method: a small script on every page reads gclid, gbraid and wbraid from the URL and writes them to a first-party cookie with a 90-day life. Every form has three hidden fields with those names, and on page load the script copies the stored values into them, so they travel with the lead into whatever system receives it. Google Tag Manager can do this with a custom HTML tag; most form builders, including HubSpot and GoHighLevel forms, support hidden fields that prepopulate from a cookie.
For phone leads, the click ID comes from call tracking. CallRail's dynamic number insertion stores the gclid when the visitor lands, attaches it to the call, and its CRM integrations can pass it through. Without DNI, phone leads from ads have no click ID; enhanced conversions for leads, covered below, are the fallback.
“The click ID is the only thread between the ad and the invoice. Drop it at the form and no report written later will tie them back together.”
Store the click ID on the lead in the CRM.
The lead has to carry its click ID for weeks, through every stage, until it dies or becomes a job. That means custom fields on the lead or contact record, named clearly (gclid, gbraid, wbraid, plus a lead_created_at timestamp if the CRM does not expose one cleanly), mapped from the form.
- JobNimbus: add custom fields on the Contact record under Settings, then Custom Fields, and map them from your web form through the API, Zapier or the native form integration. Keep them read-only for reps.
- GoHighLevel: create custom fields under Settings, then Custom Fields, and map form fields to them in the form builder; its own forms also capture UTM and click parameters.
- HubSpot: gclid is captured automatically on contacts created through HubSpot forms on pages with the tracking code. For other forms, create a custom contact property and map it.
- kvCORE: create custom fields on the lead and map them from your landing page forms through the lead API or Zapier; leads from portals will not have click IDs, and that is expected.
- Everything else (ServiceTitan, AccuLynx, Housecall Pro, Jobber, Clio): the same pattern, a custom field on the lead record, populated at creation and never edited.
Two rules keep this clean. The field is populated once at creation and never overwritten, because a returning visitor with a new gclid does not change which click produced the lead. And the creation timestamp is stored in a known time zone, because you need it to know whether the click is still inside the 90-day limit.
Choose the stages worth importing.
Google will accept a conversion for every stage in your pipeline, and that is a mistake. Import only stages that predict revenue. For most service businesses that is two actions: a booked estimate (a real person at a real address agreed to a visit) and a sold job (contract signed or deposit paid). For a clinic it is a scheduled consult and a completed first visit. For a brokerage, a signed buyer or listing agreement and a closed transaction.
Do not import raw leads; you already count those with the on-site conversion. Do not import contacted or qualified unless you truly bid on them. Set the sold action as primary with a value, and the booked action as secondary or primary with a smaller value depending on your cycle. A remodeler with a four-month cycle needs booked estimates as a primary signal because sold jobs are too rare and too late to teach bidding on their own.
Upload the conversions: four working methods.
| Method | How it works | Good for | Limits |
|---|---|---|---|
| Google Sheets template | Fill Google's template with click ID, conversion name, time and value; Google Ads pulls it on a schedule | Any CRM that can export; weekly cadence | Manual unless scripted; time zone errors are common |
| Google Ads API | Your system posts click conversions when a stage changes | Higher volume; near real time; full control of values | Needs a developer and a developer token |
| Zapier or Make | A zap watches the CRM stage change and sends the offline conversion | No developer; JobNimbus, GoHighLevel, kvCORE | Per-task pricing; timestamp format mapping |
| HubSpot native sync | The Ads tool sends lifecycle stage changes with the stored gclid | HubSpot users with HubSpot forms | Only contacts HubSpot captured a click ID for |
Enhanced conversions for leads when click IDs are lost.
Enhanced conversions for leads are Google's alternative when the click ID did not survive the trip to the CRM. Instead of a gclid, you send the lead's email or phone number, hashed with SHA-256, with the conversion name, time and value, and Google matches it against signed-in users who clicked your ad. The same identifier must have been collected at form submission through the Google tag or Tag Manager, with enhanced conversions enabled on the conversion action.
It is the more resilient path, because email and phone are already in every CRM while click IDs have to be carried deliberately. We set both up: click ID first because it is exact, enhanced conversions as the durable fallback. The upload row can include both; Google uses the click ID if it matches and falls back to the hashed data. Hash exactly as Google specifies (lowercase, trimmed email; phone in E.164; then SHA-256) or let the Sheets template or Zapier hash plain values for you.
Conversion windows, values and time zones.
A few settings cause most of the silent failures, where uploads succeed but conversions never appear in reports.
- Conversion window: if the window on the action is 30 days and the job sold on day 45, the row imports without error and is never counted. Extend the window before your first upload.
- Click age: Google accepts click conversions for clicks up to 90 days old. A remodeler whose jobs close in month five never gets the sold conversion imported; use booked estimate as the primary signal.
- Time zone: the conversion time must carry an offset. A bare timestamp is rejected or shifted, and a time earlier than the click is rejected outright.
- Value and currency: send a numeric value and a currency code on every row. A blank value teaches value-based bidding nothing; a currency symbol in the cell fails.
- Duplicates: the same click ID with two slightly different times counts twice. Send each stage change once, from one system.
Our pre-launch tracking audit checks that the click ID is present on new leads, the CRM timestamp is in a known time zone and the conversion actions have the right windows; the checklist is in our conversion tracking audit.
What usually goes wrong.
- Hidden fields added to the contact form but not to the quote calculator, booking widget or chat tool, so the highest-intent leads arrive with no click ID.
- The gclid overwritten on the CRM record when a lead returns through a later ad click, breaking the tie to the click that produced them.
- Uploading every pipeline stage, so bidding sees five conversions per customer and optimizes toward leads that move quickly rather than leads that pay.
- Conversion time set to the lead creation date instead of the stage change, which misplaces conversions in the window or puts them before the click, which is rejected.
- Local Services Ads leads pushed into the upload. LSA leads carry no gclid and are not eligible; their outcomes are reported in the LSA dashboard.
- Upload succeeds, nobody checks diagnostics, and three months later the account has been bidding on a conversion action with zero data.
A weekly five-minute check of the Uploads diagnostics page is the whole maintenance load. The rest is upstream: whether reps move stages promptly and whether the form still carries the fields after the last site redeploy. This loop is what makes paid search accountable to revenue, the standard behind our paid media work.
How do I send offline conversions to Google Ads from my CRM?
Capture the gclid, gbraid and wbraid from the landing URL into hidden form fields, store them on the lead in a custom CRM field, then when a lead reaches a revenue-predicting stage such as booked estimate or sold, send the click ID, conversion name, conversion time with time zone and a value to Google Ads through the Sheets template, the API, Zapier or HubSpot's native sync.
How long after a click can I import an offline conversion?
Google accepts click conversions for clicks up to 90 days old. The conversion action's own click-through window must also cover the gap, and its default is shorter than that, so extend it in the action settings before uploading. Conversions for older clicks are rejected as click too old; use an earlier stage such as booked estimate as the primary signal if your cycle is longer.
What are enhanced conversions for leads?
A Google Ads method that matches an offline conversion using a hashed email address or phone number instead of a click ID. The same identifier must be collected on your site at form submission through the Google tag, with enhanced conversions enabled on the action. It is the fallback when click IDs are lost between the form and the CRM, and can be sent alongside the click ID.
Can I import Local Services Ads leads as offline conversions?
No. Local Services Ads leads are routed through Google's own phone number and message system, so they carry no gclid and cannot be matched to a click. Their outcomes are managed inside the Local Services Ads dashboard, where you rate leads, dispute unqualified ones and record which ones you booked. Keep them out of your offline conversion uploads.