Google Ads · Revenue Infrastructure

Offline Conversion Tracking:
The Complete Fix Guide

Your CPL looks fine. Your sales team says the leads are garbage. Here is why that happens — and the exact pipeline to fix it.

✍ Brady Christensen · 📅 March 2025 · ⏱ 18 min read
90d
GCLID expiry window. Miss it and the conversion is gone forever.
70%
Minimum match rate. Below this, your pipeline has a data quality problem.
50%
Conversion drop seen in EU accounts with missing Consent Mode v2 params.

01 What It Actually Is

From Form Fills to Revenue Signals

Standard Google Ads tracking stops the moment someone fills out a form. Offline conversion tracking closes the loop — sending your CRM outcomes back to Google so it can attribute real revenue to specific ads, keywords, and campaigns.

When Smart Bidding only sees form submissions, it optimizes for form-fillers. That includes students, job seekers, competitors, and bots — all of whom trigger the same pixel as a qualified buyer. The algorithm finds cheap audiences that like filling forms, your CPL metric looks healthy, and your close rates quietly collapse.

Offline conversion data fixes the signal. Feed Google your actual closed deals, and it starts finding buyers instead.

Frontend vs Pipeline Reality

What form-submit tracking sees vs. actual qualified pipeline

Upload Method Comparison

CSV, middleware, and direct API scored across 5 dimensions

End-to-End Pipeline: Ad Click → Google Attribution

🖱️
Ad Click
GCLID Added
🍪
Cookie
Capture
📋
Form Submit
→ CRM
🤝
Deal Closes
CRM Updated
📤
API Upload
to Google
📊
Ad Gets Credit
Algo Learns
ℹ️

iOS Traffic: GBRAID & WBRAID

Apple's ATT framework means some iOS users don't generate a standard GCLID. Google uses GBRAID for app-to-web and WBRAID for web-to-web iOS traffic. Your capture and upload logic must handle all three identifiers.

02 Capturing the GCLID

The Hidden Field Setup

Everything starts here. If GCLID capture fails, no downstream step can recover it. The standard approach: a hidden form field populated by JavaScript on page load.

Step 1 — Enable Auto-Tagging

Google Ads → Settings → Account Settings → Auto-tagging. Confirm it is on. Without it, no GCLID is ever appended to your URLs. First thing to check in any troubleshooting session.

Step 2 — Add a Hidden Input to Every Form

HTML
<!-- Inside your <form> tag -->
<input type="hidden"
       name="gclid_field"
       id="gclid_field"
       value="">

Step 3 — Capture & Inject With JavaScript

JavaScript
function getParam(p) {
  return new URLSearchParams(window.location.search).get(p);
}
function setCookie(n, v, days) {
  const d = new Date();
  d.setDate(d.getDate() + days);
  document.cookie = `${n}=${v};expires=${d.toUTCString()};path=/`;
}
function getCookie(n) {
  const m = document.cookie.match(new RegExp('(^| )'+n+'=([^;]+)'));
  return m ? m[2] : null;
}
// Read from URL first, fall back to cookie for returning visitors
const gclid = getParam('gclid') || getCookie('gclid');
if (gclid) {
  setCookie('gclid', gclid, 90); // 90-day persistence
  const f = document.getElementById('gclid_field');
  if (f) f.value = gclid;
}
⚠️

Safari ITP — Client Cookies Cap at 24 Hours

Safari ITP 2.3+ limits JavaScript-set cookies to 24 hours when the URL contains ad parameters like gclid. Most B2B leads take longer than a day to convert. Fix: set cookies via server-side HTTP headers or use a Server-Side GTM container mapped to a first-party subdomain.

03 CRM Integration

Keeping the GCLID Alive Inside Your CRM

Salesforce

Create a custom text field on the Lead object — GCLID__c — with a character limit of at least 255. The step most teams miss: map this field during Lead Conversion. When a rep converts a Lead to an Opportunity, Salesforce doesn't carry custom fields unless you explicitly configure field mapping in Admin settings. Skip this and the GCLID is orphaned on the dead Lead record — your Opportunity has zero attribution data.

Enable Field History Tracking on Opportunity Stage. This gives you an auditable timestamp when the stage moves to "Closed Won," which the upload payload requires.

Also cleaning up spam and dupe leads in Salesforce? See our Salesforce lead quality and deduplication guide — those problems directly undermine GCLID integrity.


HubSpot

HubSpot's deduplication logic is the main threat. When two records share an email address, HubSpot merges them. If the surviving record has an older or empty GCLID field, your new click data is silently overwritten.

Fix: create two custom properties — First_Touch_GCLID and Recent_GCLID. Build a workflow that copies incoming GCLID values into these properties immediately on form submission, before any merge logic can run.

04 Upload Methods

Getting Data Back to Google

Manual CSV

Export from CRM, format to spec, upload in Google Ads UI. Proof of concept only.

Zero dev High latency Error-prone

Native CRM Connector

Built-in Salesforce / HubSpot integrations inside Google Ads.

Automated Silent failures Low flexibility

Zapier / Make.com

CRM webhook triggers automation that pushes to the Google Ads API.

Flexible Cost scales Fragile at scale

Direct Google Ads API

Custom backend sends UploadClickConversionsRequest payloads directly.

Full control Best error handling Requires dev

BigQuery Pipeline

GA4 + CRM joined in BigQuery. Data Manager pulls on a schedule.

Single source Needs data eng

Required Upload Fields

  • 📌Click identifier: Exactly one of gclid, gbraid, or wbraid
  • 📌Conversion name: Exact character-for-character match to the name in Google Ads — case-sensitive
  • 📌Conversion time: ISO 8601 with timezone offset — e.g. 2025-03-10 14:30:00+00:00
  • 📌Conversion value + currency: Required for value-based bidding — e.g. 1500.00 / USD
  • 📌Order ID: Prevents duplicate conversions when the same event is uploaded more than once

Critical Timing Constraints

Uploads within 4–6 hours of the click fail — Google hasn't indexed it yet. Uploads more than 90 days after the click fail — the GCLID has expired. Your pipeline needs a minimum-delay queue for the lower bound.

Valid upload window (relative to ad click) 90-day hard limit
0–30 days — ideal 31–75 days — still valid 76–90 days — at risk. Past 90: rejected

For tag-level issues, attribution gaps, and GCLID stripping on redirect, see our Google Ads conversion tracking guide. For a full measurement audit, visit the tracking and analytics integrity service.

05 Failure Modes

Common Error Codes and What Causes Them

Most pipeline failures are silent. Uploads appear to succeed, match rates drop, and no one notices for weeks. Here is the full breakdown.

Where GCLID Data Gets Lost

Root cause breakdown when offline conversions fail to attribute

Error / IssueRoot CauseHow to Spot It
CONVERSION_PRECEDES_CLICKServer exported a local timestamp but formatted it as UTC. Google places the event before the click.High failure rate. Conversions in CRM but zero in Google Ads.
EXPIRED_GCLIDConversion uploaded more than 90 days after the original click.Long-cycle enterprise deals consistently fail. ROAS looks artificially low.
GCLID_DECODE_ERRORCRM forced the field to lowercase, or URL decoding modified characters.GCLIDs look corrupted in exports. Entire rows rejected.
NO_CONVERSION_ACTION_FOUNDTypo in the conversion name, or the action belongs to a different Google Ads account.Total upload failure. Zero conversions recorded despite a 200 response.
INVALID_CLICK_IDENTIFIERGCLID was truncated by CRM character limit, from a different account, or from a test.Specific leads fail — usually test records or cross-account traffic.
Duplicate ConversionsSame CRM event uploaded twice with no unique order_id. Both get processed.Google Ads conversion count exceeds actual closed deals in CRM.
GCLID Stripped by RedirectA 301/302 redirect removes URL parameters before the user hits the landing page.GCLID fields blank in CRM despite auto-tagging being enabled.

06 Diagnostic Framework

Finding the Break in Your Pipeline

Work through these six tiers in order. Each one rules out a category of failure before moving downstream.

  1. 1
    Verify URL parameters survive redirects

    Append ?gclid=TEST12345 to your landing page URL. If it disappears after load, a redirect or server rule is stripping query strings. Test in both Chrome and Safari.

  2. 2
    Inspect browser storage — DevTools → Application → Cookies

    Confirm a gclid cookie exists with the correct value. If missing, open the Console tab and check for TypeError or Content Security Policy blocking errors.

  3. 3
    Check DOM injection on the form

    Right-click the form → Inspect. Find the hidden input. Its value attribute must show the GCLID string. If blank, the injection script is running before the form renders.

  4. 4
    Submit a test lead and inspect the CRM record

    Verify the GCLID arrived intact — no truncation, no lowercase conversion, no special character changes. Check the character limit on your custom field is at least 255.

  5. 5
    Validate the upload payload format

    Three checks: (1) conversion name matches Google Ads exactly, (2) timestamp is ISO 8601 with correct timezone offset, (3) no row is within 6 hours of its click timestamp.

  6. 6
    Check the Google Ads Diagnostics tab

    Tools → Conversions → select your offline action → Diagnostics. Match rate below 70% means a systemic data quality issue. The tab shows exact error codes for every rejected row.

07 Long Sales Cycles

Working Around the 90-Day GCLID Limit

Enterprise B2B deals take 6 to 12 months to close. GCLIDs expire after 90 days. The solution: upload intermediate pipeline milestones so the algorithm has data to learn from within the active window.

Multi-Stage Upload Strategy — B2B Example

  • MQL — Marketing Qualified Lead: Upload within 1–7 days. Proxy value: $100
  • SAL — Sales Accepted Lead: Upload within 14–30 days. Proxy value: $500
  • Demo Completed / SQL: Upload within 30–60 days. Proxy value: $1,000
  • Closed Won: Upload within 90 days. Pass actual deal value.

Proxy values should reflect your historical close rate at each stage. If 20% of demos close at $10,000, each demo is worth roughly $2,000 as a proxy. Smart Bidding gets continuous signals to learn from rather than waiting months for the final close.

08 Advanced: ECL & Consent Mode

Enhanced Conversions and GDPR Compliance

Enhanced Conversions for Leads

ECL captures the user's email at form submission, hashes it with SHA-256, and sends it to Google. When the CRM outcome happens, you upload the same hashed email — no GCLID required. Google matches via signed-in account data.

💡

Use ECL Alongside GCLID Uploads, Not Instead Of

GCLID-based uploads are more deterministic. ECL recovers conversions lost to Safari ITP, cookie clearing, and cross-device journeys. Running both maximises your match rate. Use a unique order_id on all uploads to prevent double-counting when both methods match the same event.


Consent Mode v2 (EU / GDPR)

Every API upload payload must include two consent parameters. Missing either one — or setting it to DENIED — causes Google to drop the entire record at ingestion.

  • 🔒ad_user_data: GRANTED or DENIED — consent to send data to Google
  • 🔒ad_personalization: GRANTED or DENIED — consent for remarketing

Your CMP must record consent state at form submission, store it in the CRM alongside the GCLID, and pass it through to every upload. If a user later withdraws consent under GDPR, your pipeline must stop uploading data for that user entirely.

09 Validation

How to Confirm It Is Actually Working

A successful upload is not the same as a successful attribution. A 40% match rate is a broken pipeline. Here is what to check post-launch.

  • Match rate ≥ 70%: Diagnostics tab. Below 70% = data quality issue. Below 50% = critical failure requiring immediate investigation.
  • Attribution delay: Allow 24–72 hours after upload for conversions to appear in the Google Ads UI.
  • CRM vs Google Ads count: Compare closed deals in CRM against uploaded conversions. Within ~15–20% is healthy given expected match-rate loss.
  • No CONVERSION_PRECEDES_CLICK errors: Any of these in upload history means your timezone handling is broken.
  • Smart Bidding shifts: Within 2–3 weeks, bid adjustments by device, keyword, and audience should change meaningfully. Flat bidding = algorithm not using the data.
  • Volume monitoring: Set a weekly alert — if uploaded conversion count drops more than 50% from a 4-week average, a silent failure has occurred.
Stop Your Conversion Data From Leaking

Your offline conversion pipeline
needs a technical owner.

If your CRM and Google Ads numbers don't match — or you've never validated your match rate — you're optimizing on incomplete data. The Revenue Infrastructure Review maps every failure point in your tracking chain and gives you a prioritized fix plan.

Best for teams spending $30k+/month on paid media.