# Tracking

Course: [Google Ads for B2B Teams](https://www.devtutorials.ai/learn/google-ads) · Section: Measure and Protect
Source: https://www.devtutorials.ai/learn/google-ads/measure-and-protect/tracking

> Stage one is live in a day: the conversion tag, GA4, UTMs and consent. Stage two sends CRM outcomes back as offline conversions.

<aside className="gads-glance" aria-label="At a glance">
<p className="gads-glance-title">At a glance</p>
<ul>
<li>Stage one can be live in a day: the Google tag on every page, one primary conversion action, GA4 linked, auto-tagging on, consistent UTMs, and the GCLID and UTMs saved with each lead.</li>
<li>Fire the conversion when the lead is actually created (thank-you step), never on a button click.</li>
<li>Consent comes first for EU/UK visitors: a consent banner sending Google Consent Mode v2 signals, defaulting to denied.</li>
<li>Form fills aren't the result. Stage two sends CRM outcomes (qualified leads, opportunities, won deals) back into Google Ads with a CSV upload, so bidding learns what pipeline looks like.</li>
<li>GA4 is the default because it links to Google Ads in minutes. Your CRM is the source of truth for pipeline.</li>
</ul>
</aside>

## The five things to understand

<dl>
<dt><strong>Conversion action</strong></dt>
<dd>Something you tell Google Ads to count. You'll have one <em>primary</em> conversion (used for bidding) and maybe a few <em>secondary</em> ones (reported, not bid on).</dd>
<dt><strong>Google tag</strong></dt>
<dd>One script on every page that sends data to Google Ads and GA4. An event snippet fires the conversion.</dd>
<dt><strong>Auto-tagging and GCLID</strong></dt>
<dd>With auto-tagging on, Google adds <code>gclid=...</code> to every ad click's URL. Save it with the lead; it's the key that links a CRM outcome back to the click.</dd>
<dt><strong>UTMs</strong></dt>
<dd>Readable tags (<code>utm&#95;source=google&amp;utm&#95;medium=cpc&amp;utm&#95;campaign=...</code>) that tell GA4 and your CRM where a visit came from. Use them alongside auto-tagging.</dd>
<dt><strong>Offline conversion</strong></dt>
<dd>An outcome that happens later, in your CRM (SQL, opportunity, closed deal), uploaded back to Google Ads.</dd>
</dl>

## Decide what to count

<div className="gads-var" data-goal="demo">
<p><strong>Demo request goal.</strong> Primary conversion at launch:</p>
<ul>
<li><em>Demo request submitted</em>.</li>
<li>Counted once per lead ("One" counting).</li>
<li>Fired on the thank-you page after the server accepted the form.</li>
</ul>
<p>Secondary: contact-sales or pricing page form fills if you have them. Later (stage two), add <em>SQL</em> and <em>Opportunity created</em> as offline conversions and make SQL the primary for bidding once you upload enough of them.</p>
</div>

<div className="gads-var" data-goal="trial">
<p><strong>Free trial goal.</strong> Primary conversion at launch:</p>
<ul>
<li><em>Trial account created</em> (not "sign-up form started").</li>
<li>Counted once per lead.</li>
<li>Fired after the account exists.</li>
<li>For example on the first in-app page or a confirmation page.</li>
</ul>
<p>Secondary: email verified. Later (stage two), add <em>Activated trial</em> (reached your key product action) and <em>Converted to paid</em> as offline conversions, and make activation the primary once you upload enough of them.</p>
</div>

<p>Give conversions a value even at stage one, roughly what each is worth on average: <em>value = average deal value × the share of these leads that become customers</em>.</p>
<p>If deals average <span className="gads-money" data-usd="20000">$20,000</span> and 5% of demo requests close, each request is worth about <span className="gads-money" data-usd="1000">$1,000</span>. A rough value lets you move to value-based bidding later without restructuring.</p>

## Stage one: live in a day

<div className="gads-callout gads-callout-tip">
<p className="gads-callout-title">Order matters</p>
<p>If your region needs consent handling, set up the consent banner and Consent Mode defaults <em>before</em> the Google tag, so the first tag load already respects the visitor's choice. See <a href="#consent-and-privacy-for-your-region">Consent</a> below.</p>
</div>

### 1. Add the Google tag to the Astro base layout

<p>In Google Ads, go to Goals, then Conversions, then Settings (or the Google tag screen) to find your tag ID (<code>AW-XXXXXXXXX</code>). In GA4, find the measurement ID (<code>G-XXXXXXX</code>).</p>
<p>Add both to the shared layout so every page loads the tag once. In Astro, inline scripts need <code>is:inline</code> so Astro leaves them as written.</p>

```html readonly title="src/layouts/BaseLayout.astro"
---
// src/layouts/BaseLayout.astro (your site's shared layout)
const GOOGLE_ADS_ID = 'AW-XXXXXXXXX';
const GA4_ID = 'G-XXXXXXX';
---
<html lang="en">
  <head>
    <!-- Consent Mode defaults go here first if you need them (see Consent) -->
    <script is:inline async src={`https://www.googletagmanager.com/gtag/js?id=${GA4_ID}`}></script>
    <script is:inline define:vars={{ GOOGLE_ADS_ID, GA4_ID }}>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      window.gtag = gtag;
      gtag('js', new Date());
      gtag('config', GA4_ID);
      gtag('config', GOOGLE_ADS_ID, { allow_enhanced_conversions: true });
    </script>
  </head>
  <body><slot /></body>
</html>
```

### 2. Create the conversion action and fire it on success

<p>In Google Ads: Goals, then Conversions, then New conversion action, then Website. Choose "Submit lead form" (demo) or "Sign-up" (trial) as the category, set the value, set counting to "One", and set it as primary.</p>
<p>Google gives you a <code>send&#95;to</code> label like <code>AW-XXXXXXXXX/AbCdEfGh</code>. Fire it on the thank-you page:</p>

```html readonly title="src/pages/thank-you.astro"
---
// src/pages/thank-you.astro  (or the first page after a trial account is created)
---
<BaseLayout>
  <h1>Thanks, we'll be in touch within one business day.</h1>
  <script is:inline>
    gtag('event', 'conversion', {
      send_to: 'AW-XXXXXXXXX/AbCdEfGh',
      value: 1000,          // your average value per lead
      currency: 'USD'
    });
    gtag('event', 'generate_lead');   // GA4 event, mark it as a key event in GA4
  </script>
</BaseLayout>
```

<p>Make sure the thank-you page is only reachable after a successful submission, and isn't linked anywhere else, or people who bookmark it will count as conversions.</p>

### 3. Link GA4, turn on auto-tagging

<ul>
<li>In Google Ads, Tools, then Data manager (or Linked accounts): link the GA4 property. Turn on auto-tagging in Account settings (it's on by default for new accounts; check it).</li>
<li>In GA4, mark <code>generate&#95;lead</code> (or <code>sign&#95;up</code>) as a key event. You can import it into Google Ads as a secondary conversion for comparison; keep the Google Ads tag conversion as primary to avoid counting twice.</li>
</ul>

### 4. Consistent UTMs

<p>Auto-tagging handles Google's own reporting; UTMs make the source readable in your CRM and other tools. Add one account-level <strong>Final URL suffix</strong> so every ad gets them automatically:</p>

```text readonly title="Final URL suffix"
utm_source=google&utm_medium=cpc&utm_campaign={campaignid}&utm_content={adgroupid}&utm_term={keyword}
```

<p>If you'd rather have readable campaign names, set the suffix at campaign level with the name written in (for example <code>utm&#95;campaign=us-search-core</code>). Use lowercase and hyphens, always. The <a href="/learn/google-ads/toolkit/templates-and-tools#utm-builder">UTM builder</a> enforces this.</p>

### 5. Save the GCLID and UTMs with every lead

<p>This is the step teams skip, and it is the one that makes stage two possible.</p>
<p>Capture the values when the visitor lands, keep them for the session (people browse before converting), and send them in hidden form fields that map to CRM fields.</p>

```html readonly title="Astro / HTML"
<!-- in your form component -->
<input type="hidden" name="gclid" />
<input type="hidden" name="utm_source" />
<input type="hidden" name="utm_medium" />
<input type="hidden" name="utm_campaign" />
<input type="hidden" name="utm_term" />
<input type="hidden" name="utm_content" />

<script is:inline>
  (function () {
    var keys = ['gclid', 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];
    var params = new URLSearchParams(location.search);
    var stored = {};
    try { stored = JSON.parse(localStorage.getItem('attribution') || '{}'); } catch (e) {}
    // First touch wins within 90 days; a new ad click (new gclid) replaces it.
    if (params.get('gclid') || !stored.ts || Date.now() - stored.ts > 90 * 864e5) {
      var fresh = { ts: Date.now() };
      keys.forEach(function (k) { if (params.get(k)) fresh[k] = params.get(k); });
      if (Object.keys(fresh).length > 1) { stored = fresh; localStorage.setItem('attribution', JSON.stringify(stored)); }
    }
    document.querySelectorAll('form input[type=hidden]').forEach(function (input) {
      if (stored[input.name]) input.value = stored[input.name];
    });
  })();
</script>
```

<p>Create matching custom fields in your CRM (for example <em>GCLID</em>, <em>UTM Source</em>, <em>UTM Campaign</em>) and map the form fields to them.</p>
<p>In the EU/UK, only store these after consent if your legal team treats them as tracking identifiers; your CMP can gate this script.</p>

### 6. Turn on enhanced conversions for leads

<p>In the conversion settings, turn on enhanced conversions for leads and choose the Google tag method.</p>
<p>(Google is merging enhanced conversions for web and for leads into one on/off setting, and since April 2026 accepts user-provided data from the tag, Data Manager and the API at the same time, so you may see a single "Enhanced conversions" switch instead.) The tag then sends a hashed copy of the email from the form with the conversion.</p>
<p>This is Google's recommended basis for later CRM uploads, because it matches leads even when the GCLID is lost.</p>
<p>The <code>allow&#95;enhanced&#95;conversions</code> line in the tag above enables it; Google can detect the email field automatically, or you can specify it. <span className="gads-asof" title="Google Ads changes often. Re-check this against Google's help pages.">As of October 2026</span></p>

### 7. Test it

<ol>
<li>Open your landing page with <code>?gclid=test123&amp;utm&#95;source=google&amp;utm&#95;medium=cpc&amp;utm&#95;campaign=test</code> added.</li>
<li>Use Google Tag Assistant (<a href="https://tagassistant.google.com/" target="_blank" rel="noopener noreferrer">tagassistant.google.com</a>) to confirm the tag loads and the conversion event fires on the thank-you page.</li>
<li>Check the lead in your CRM has <code>test123</code> and the UTM values.</li>
<li>In GA4, check DebugView or Realtime for the <code>generate&#95;lead</code> event.</li>
<li>In Google Ads, the conversion status should move from "Unverified" to "No recent conversions" or "Recording conversions" within a day.</li>
</ol>

## Consent and privacy for your region

<p>This isn't legal advice; your legal or privacy team decides what you need. It's the practical version of what affects your tracking setup. <span className="gads-asof" title="Google Ads changes often. Re-check this against Google's help pages.">As of October 2026</span></p>

<div className="gads-var" data-region="eu">
<h3>EU/UK (and Switzerland)</h3>
<p>Under GDPR, the ePrivacy rules and the UK's PECR, you need prior consent for non-essential cookies, including advertising and analytics tags.</p>
<p>Google's <a href="https://www.google.com/about/company/user-consent-policy/" target="_blank" rel="noopener noreferrer">EU user consent policy</a> applies to users in the EEA, the UK and Switzerland, and Google requires <strong>Consent Mode v2</strong> signals for that traffic.</p>
<p>From 21 July 2025, Google began switching off conversion tracking, remarketing and personalisation for advertisers not sending those signals, according to its notices to affected accounts.</p>
<p>If your account was caught, setting up Consent Mode restores measurement from then on. It does not bring back the data you missed.</p>
<p>What you need:</p>
<ul>
<li>A consent banner (CMP) that supports Consent Mode v2. Google-certified CMPs integrate directly; open-source options such as Klaro or Orestbida's CookieConsent work if you wire up the four signals yourself.</li>
<li>All four signals set to <code>denied</code> by default, before the Google tag loads, then updated when the visitor chooses.</li>
<li>Your privacy notice listing Google Ads, GA4 and any form protection services.</li>
</ul>

```html readonly title="Astro / HTML"
<!-- In the <head>, BEFORE the Google tag -->
<script is:inline>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('consent', 'default', {
    ad_storage: 'denied',
    analytics_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
    wait_for_update: 500
  });
  // Optional: default to granted outside the EEA/UK/CH, if your legal team agrees
  // gtag('consent', 'default', { ad_storage: 'granted', ... , region: ['US'] });
</script>

<!-- Your CMP calls this when the visitor accepts -->
<script is:inline>
  function onConsentAccepted() {
    gtag('consent', 'update', {
      ad_storage: 'granted',
      analytics_storage: 'granted',
      ad_user_data: 'granted',
      ad_personalization: 'granted'
    });
  }
</script>
```

<p>The two v2 signals, <code>ad&#95;user&#95;data</code> and <code>ad&#95;personalization</code>, are the ones most often missing. Check them in Tag Assistant: the consent tab shows the default and updated states.</p>
<details className="gads-deeper">
<summary><span className="gads-deeper-tag">Go deeper</span> Basic vs advanced Consent Mode</summary>
<div className="gads-deeper-body">
<p>In <em>basic</em> mode, Google tags don't load at all until consent is given. In <em>advanced</em> mode, tags load with consent denied and send cookieless pings, which Google uses to model conversions it can't observe.</p>
<p>Advanced mode recovers more measurement; some legal teams prefer basic. Either is valid for Google's requirement. Ask your privacy team which you use, and write it down.</p>
</div>
</details>
</div>

<div className="gads-var" data-region="us">
<h3>US/Canada</h3>
<p>The US uses an opt-out model for most marketing tracking.</p>
<p>California (CCPA/CPRA) and a growing list of other states give people the right to opt out of "sale" or "sharing" of personal data, including for targeted advertising, and several require you to honour the Global Privacy Control (GPC) browser signal.</p>
<p>You don't need a pre-consent banner for US traffic in most states, but you do need a privacy notice that discloses advertising cookies and a working "Do not sell or share" mechanism.</p>
<p>In Canada, PIPEDA expects meaningful consent, usually satisfied by notice for analytics; Quebec's Law 25 requires opt-in consent for tracking technologies, so Quebec visitors need a consent banner.</p>
<p>Practical setup: a CMP that shows an opt-in banner where required (Quebec, and any EU/UK visitors) and an opt-out link elsewhere, honouring GPC.</p>
<p>Consent Mode defaults can be granted for US regions and denied for Quebec and the EEA using the <code>region</code> parameter.</p>
</div>

<div className="gads-var" data-region="india">
<h3>India</h3>
<p>The Digital Personal Data Protection (DPDP) Act 2023 is in force, and the DPDP Rules were notified on 13 November 2025 with a phased rollout. The rules for registered consent managers start on 13 November 2026.</p>
<p>The notice-before-consent rule (Rule 3) and most other obligations apply from 13 May 2027, 18 months after notification.</p>
<p>The rules require consent that is free, specific and informed, with withdrawal as easy as giving consent.</p>
<p>Practical setup now: a clear privacy notice covering advertising and analytics, and a consent banner for non-essential tags if your legal team wants to get ahead of the deadline (many do, since it's cheaper to build once).</p>
<p>If you get EU/UK traffic, you need Consent Mode v2 for those visitors anyway.</p>
</div>

<div className="gads-var" data-region="apac">
<h3>Rest of APAC</h3>
<p>Rules differ a lot by country:</p>
<ul>
<li><strong>Australia:</strong> the Privacy Act (amended in late 2024, with more reforms expected) requires transparency about tracking; no blanket cookie-consent rule yet.</li>
<li><strong>Singapore:</strong> the PDPA requires notice and consent for collecting personal data, with some deemed-consent exceptions.</li>
<li><strong>Japan:</strong> the APPI, plus the Telecommunications Business Act's external transmission rule (since 2023), which requires you to notify users when tags send their data to third parties like Google. A clear cookie notice usually covers it.</li>
<li><strong>South Korea:</strong> PIPA is strict: explicit consent for collection and for overseas transfer. Treat Korea like the EU.</li>
</ul>
<p>Practical setup: a CMP configured per country, opt-in for Korea (and EU/UK visitors), notice-based elsewhere.</p>
</div>

<div className="gads-var" data-region="latam">
<h3>Latin America</h3>
<ul>
<li><strong>Brazil:</strong> the LGPD requires a legal basis for processing. The ANPD's cookie guidance says non-essential cookies such as advertising generally need consent, with a banner that makes rejection as easy as acceptance.</li>
<li><strong>Mexico:</strong> a new Federal Law on the Protection of Personal Data Held by Private Parties was published on 20 March 2025 and took effect the next day, replacing the 2010 law. Oversight moved from the INAI to the Secretaría Anticorrupción y Buen Gobierno. Privacy notices are mandatory, and secondary purposes such as advertising need a way to opt out.</li>
<li><strong>Chile:</strong> Law 21.719, published in December 2024, takes effect on 1 December 2026. It brings rules closer to GDPR and a new Personal Data Protection Agency that can impose fines.</li>
<li>Argentina and Colombia have older but active data protection laws based on notice and consent.</li>
</ul>
<p>Practical setup: an opt-in banner for Brazil (and Chile once in force), a clear notice with opt-out elsewhere, Spanish and Portuguese versions of both.</p>
</div>

<div className="gads-var" data-region="mea">
<h3>Middle East/Africa</h3>
<ul>
<li><strong>South Africa:</strong> POPIA requires a lawful basis and notice; direct marketing rules are strict.</li>
<li><strong>Saudi Arabia:</strong> the PDPL has been enforced since September 2024 and generally requires consent, with restrictions on transfers abroad.</li>
<li><strong>UAE:</strong> the federal PDPL applies, and free zones such as DIFC and ADGM have their own GDPR-style laws.</li>
<li>Nigeria (NDPA 2023), Kenya and others have consent-based laws with active regulators.</li>
</ul>
<p>Practical setup: an opt-in consent banner is the safe default across the region. Check data transfer rules with your legal team, since Google tags send data abroad.</p>
</div>

<div className="gads-callout gads-callout-later">
<p className="gads-callout-title">Re-checked 3 November 2026: consent changes in 2026</p>
<p>Since 15 June 2026, advertising data from the GA4 tag that is shared with a linked Google Ads account is controlled only by the Consent Mode <code>ad&#95;storage</code> signal.</p>
<p>Google Signals no longer limits it and now only controls whether Analytics links data to signed-in users for its own reports.</p>
<p>Google has also said that, later in 2026, <code>ad&#95;personalization</code> will become the only control over whether Analytics data is used for personalisation in Google Ads, and that IP addresses collected by the Google tag will be encrypted before they reach Google Ads.</p>
<p>Nothing in stage one changes: send all four Consent Mode signals from your consent banner. <span className="gads-asof" title="Google Ads changes often. Re-check this against Google's help pages.">As of November 2026</span></p>
</div>

## GA4 or something else?

<p>Use GA4 plus your CRM. GA4 links to Google Ads in a few clicks, imports conversions and audiences, and is free. The CRM is where pipeline lives, and it's what stage two reads from.</p>
<p>That combination covers what B2B teams need from Google Ads tracking.</p>

<p>Open-source analytics tools such as PostHog (product and web analytics, self-hostable), Plausible or Umami (simple, privacy-friendly web analytics) are good, and some teams prefer them for privacy or product analytics.</p>
<p>But none of them feeds Google Ads bidding, so they'd be <em>in addition to</em> the Google tag, not instead of it.</p>
<p>If you already use one, keep it for site analytics; for the first week, GA4 is the fastest route to working ad tracking.</p>

## Stage two: send CRM outcomes back to Google Ads

<div className="gads-callout gads-callout-later">
<p className="gads-callout-title">Start this in month two</p>
<p>Stage two needs a few weeks of leads with saved GCLIDs or emails. Start once stage one has been live for about a month.</p>
</div>

<p>Google's bidding only knows what you tell it. If it only sees form fills, it finds more form fills, including students and competitors.</p>
<p>Once you upload which leads became SQLs, opportunities and customers, it can bid for the searches that produce pipeline.</p>

<figure className="gads-fig gads-fig-wide">
<svg className="gads-anim gads-flow" viewBox="0 0 760 210" role="img" aria-label="Diagram: ad click to landing page form, lead saved in CRM with GCLID, CRM export to CSV, CSV uploaded to Google Ads, Google Ads bidding learns.">
<g className="gads-svg-text" fontSize="14">
<g className="gads-node gads-n1">
<rect x="10" y="60" width="130" height="70" rx="10" className="gads-svg-accent-soft" />
<text x="75" y="90" textAnchor="middle" className="gads-svg-ink" fontWeight="600">Ad click</text>
<text x="75" y="110" textAnchor="middle" className="gads-svg-muted" fontSize="12">gclid=Cj0K…</text>
</g>
<g className="gads-node gads-n2">
<rect x="165" y="60" width="130" height="70" rx="10" className="gads-svg-accent-soft" />
<text x="230" y="90" textAnchor="middle" className="gads-svg-ink" fontWeight="600">Form</text>
<text x="230" y="110" textAnchor="middle" className="gads-svg-muted" fontSize="12">hidden gclid, email</text>
</g>
<g className="gads-node gads-n3">
<rect x="320" y="60" width="130" height="70" rx="10" className="gads-svg-good-soft" />
<text x="385" y="90" textAnchor="middle" className="gads-svg-ink" fontWeight="600">CRM</text>
<text x="385" y="110" textAnchor="middle" className="gads-svg-muted" fontSize="12">lead → SQL → won</text>
</g>
<g className="gads-node gads-n4">
<rect x="475" y="60" width="120" height="70" rx="10" className="gads-svg-warn-soft" />
<text x="535" y="90" textAnchor="middle" className="gads-svg-ink" fontWeight="600">CSV</text>
<text x="535" y="110" textAnchor="middle" className="gads-svg-muted" fontSize="12">weekly export</text>
</g>
<g className="gads-node gads-n5">
<rect x="620" y="60" width="130" height="70" rx="10" className="gads-svg-accent-soft" />
<text x="685" y="90" textAnchor="middle" className="gads-svg-ink" fontWeight="600">Google Ads</text>
<text x="685" y="110" textAnchor="middle" className="gads-svg-muted" fontSize="12">offline conversions</text>
</g>
<g className="gads-arrows" strokeWidth="2" fill="none">
<path className="gads-svg-line gads-a1" d="M140 95 H165" />
<path className="gads-svg-line gads-a2" d="M295 95 H320" />
<path className="gads-svg-line gads-a3" d="M450 95 H475" />
<path className="gads-svg-line gads-a4" d="M595 95 H620" />
<path className="gads-svg-line gads-loop" d="M685 130 V175 H75 V130" strokeDasharray="5 5" />
</g>
<text x="380" y="196" textAnchor="middle" className="gads-svg-muted gads-loop-label" fontSize="12">bidding learns which searches lead to pipeline</text>
<circle className="gads-dot gads-svg-accent" r="6" cx="75" cy="95" />
</g>
</svg>
<button type="button" className="gads-anim-replay">Replay</button>
<figcaption>Stage two data flow: the click ID or email travels with the lead, and outcomes flow back to Google Ads as a CSV upload.</figcaption>
</figure>

### Choose your method

<p><span className="gads-asof" title="Google Ads changes often. Re-check this against Google's help pages.">As of October 2026</span></p>

<p>Google now recommends <strong>enhanced conversions for leads</strong> over the older GCLID-only import. You upload CRM outcomes keyed by the hashed email (and the GCLID if you have it), and Google matches them to the original click.</p>
<p>It is more reliable because it still works when the GCLID wasn't captured.</p>

<ul>
<li><strong>CSV upload through Data Manager</strong> (in Google Ads: Tools, then Data manager) works with any CRM and is what this course uses. Upload a CSV by hand, or schedule imports from Google Sheets, HTTPS or SFTP. Google now labels the older file import under Conversions, then Uploads as <em>legacy</em> and says enhanced conversions for leads only supports Data Manager files, so start in Data Manager. When you create the import, pick the template for <em>conversions from clicks (enhanced conversions for leads)</em>, which has the user-data columns.</li>
<li><strong>API integrations:</strong> since 15 June 2026, offline conversion and enhanced-conversions-for-leads uploads through the Google Ads API are blocked and must use the Data Manager API instead. This only matters if a developer or a connector tool uploads for you; check your connector has migrated. Uploading files through Data Manager in the interface isn't affected.</li>
<li><strong>Native CRM connectors</strong> (Salesforce, HubSpot and others link directly in Data Manager) are a good later improvement. They're quicker to maintain, but slower to set up than a CSV and need admin access on both sides.</li>
</ul>

### Set it up

<ol>
<li>In Google Ads, create an offline conversion action for each CRM stage you'll upload, for example <em>SQL</em> and <em>Closed won</em> <span className="gads-var" data-goal="trial">(or <em>Trial activated</em> and <em>Converted to paid</em>)</span>. Source: "CRM, files or other data sources". Set counting to "One".</li>
<li>Keep them secondary at first. Once you're uploading a steady volume (as a rule of thumb, 15 to 30 a month for the stage you want to bid on), make that stage the primary conversion and set the website form fill to secondary.</li>
<li>In your CRM, build a report: leads that reached the stage in the last 90 days, with GCLID, email, the date and time they reached the stage, and value.</li>
<li>Export it weekly as CSV, transform it to Google's template (or let your LLM do it), and upload. Use the <a href="/google-ads-kit/offline-conversions-template.csv">offline conversion template</a> from this site.</li>
<li>Check the upload diagnostics a day later: matched rows, errors, and the reasons.</li>
</ol>

### The upload file

<div className="gads-table-wrap">
<table>
<thead>
<tr>
<th>Column</th>
<th>Example</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>Google Click ID</td>
<td><code>Cj0KCQjw…</code></td>
<td>Exactly as captured. GCLIDs are case-sensitive; don't let a spreadsheet change them.</td>
</tr>
<tr>
<td>Email</td>
<td><code>jane@example.com</code></td>
<td>For enhanced conversions for leads. Lowercase and trimmed. Plain-text emails are only allowed for a one-time manual upload, where Google hashes them for you. Scheduled imports (Sheets, HTTPS, SFTP) need the email already hashed with SHA-256.</td>
</tr>
<tr>
<td>Conversion Name</td>
<td><code>SQL</code></td>
<td>Must exactly match the conversion action name in Google Ads.</td>
</tr>
<tr>
<td>Conversion Time</td>
<td><code>2026-10-14 15:30:00+0000</code></td>
<td>When the lead reached the stage, with time zone. Must be after the click.</td>
</tr>
<tr>
<td>Conversion Value</td>
<td><code>3000</code></td>
<td>Value of this stage (see below).</td>
</tr>
<tr>
<td>Conversion Currency</td>
<td><code>USD</code></td>
<td>ISO code.</td>
</tr>
</tbody>
</table>
</div>

<p>Timing limits, from Google's offline conversion guidelines: a conversion with a GCLID can be imported up to <strong>90 days</strong> after the click, but one matched only on email (enhanced conversions for leads) must be uploaded within <strong>63 days</strong> of the click.</p>
<p>Later rows are dropped. B2B deals that close after that can't be uploaded as "Closed won", which is one reason to bid on earlier stages such as SQL.</p>
<p>Google recommends uploading at least daily, or on a regular fixed schedule if you can't. A weekly manual upload is fine to start, as long as it is the same day every week. <span className="gads-asof" title="Google Ads changes often. Re-check this against Google's help pages.">As of October 2026</span></p>

<div className="gads-var" data-region="eu">
<p><strong>EU/UK:</strong> the upload template has <em>Ad User Data</em> and <em>Ad Personalization</em> consent columns.</p>
<p>For leads from the EEA, UK or Switzerland, fill them from the consent the person gave on your site (your CMP's record), rather than leaving them blank.</p>
</div>

### What value to give each stage

<p>Use expected value: <em>average deal value × the share of leads at this stage that eventually close</em>. Rough numbers are fine; update them each quarter.</p>

<div className="gads-table-wrap">
<table>
<thead>
<tr>
<th>Stage</th>
<th>Illustrative close rate from stage</th>
<th>Value if deals average <span className="gads-money" data-usd="20000">$20,000</span></th>
</tr>
</thead>
<tbody>
<tr data-goal="demo">
<td>Demo request (website)</td>
<td>5%</td>
<td><span className="gads-money" data-usd="1000">$1,000</span></td>
</tr>
<tr data-goal="trial">
<td>Trial sign-up (website)</td>
<td>3%</td>
<td><span className="gads-money" data-usd="600">$600</span></td>
</tr>
<tr data-goal="trial">
<td>Activated trial</td>
<td>10%</td>
<td><span className="gads-money" data-usd="2000">$2,000</span></td>
</tr>
<tr>
<td>SQL</td>
<td>15%</td>
<td><span className="gads-money" data-usd="3000">$3,000</span></td>
</tr>
<tr>
<td>Opportunity</td>
<td>25%</td>
<td><span className="gads-money" data-usd="5000">$5,000</span></td>
</tr>
<tr>
<td>Closed won</td>
<td>100%</td>
<td>Actual deal value</td>
</tr>
</tbody>
</table>
</div>

<p>The close rates are illustrative. Take yours from your CRM. If you use regional pricing, use the deal value for the lead's region; this is how bidding learns that some regions are worth more (see <a href="/learn/google-ads/measure-and-protect/geo-targeting">Geographic targeting</a>).</p>

<GadsPrompt title="Turn a CRM export into a Google Ads upload file" claude={"Attached is a CSV export from our CRM of leads that reached a sales stage in the last 90 days. Turn it into a Google Ads offline conversion upload file.\n\nCRM columns: [list the column names, e.g. \"Lead ID, Email, GCLID, Stage, Stage Date, Region, Deal Amount\"]\nStage mapping to Google Ads conversion names (must match exactly): [e.g. \"Sales Qualified\" -> \"SQL\", \"Closed Won\" -> \"Closed won\"]\nValues: SQL = [value], Opportunity = [value], Closed won = actual Deal Amount. Currency: [ISO code]. CRM time zone: [e.g. America/New_York].\n\nOutput columns, in this order: Google Click ID, Email, Conversion Name, Conversion Time, Conversion Value, Conversion Currency.\nRules:\n- Conversion Time format yyyy-mm-dd HH:mm:ss+zzzz in the CRM time zone.\n- Keep GCLIDs exactly as they are (case-sensitive). Lowercase and trim emails.\n- Drop rows that have neither GCLID nor email, and duplicates of the same lead + stage.\n- Drop rows where the stage date is more than 90 days after the first-touch date if there is a GCLID, or more than 63 days after it if there is only an email (Google won't import them). List what you dropped and why.\n- Don't invent values.\n\nThen tell me: how many rows in, how many out, how many dropped and why, and any data problems (for example many missing GCLIDs, which would mean our hidden form fields are broken).\nWrite the Python you used so I can re-run it next week."} chatgpt={"Attached is a CSV export from our CRM of leads that reached a sales stage in the last 90 days. Turn it into a Google Ads offline conversion upload file.\n\nCRM columns: [list the column names, e.g. \"Lead ID, Email, GCLID, Stage, Stage Date, Region, Deal Amount\"]\nStage mapping to Google Ads conversion names (must match exactly): [e.g. \"Sales Qualified\" -> \"SQL\", \"Closed Won\" -> \"Closed won\"]\nValues: SQL = [value], Opportunity = [value], Closed won = actual Deal Amount. Currency: [ISO code]. CRM time zone: [e.g. America/New_York].\n\nOutput columns, in this order: Google Click ID, Email, Conversion Name, Conversion Time, Conversion Value, Conversion Currency.\nRules:\n- Conversion Time format yyyy-mm-dd HH:mm:ss+zzzz in the CRM time zone.\n- Keep GCLIDs exactly as they are (case-sensitive). Lowercase and trim emails.\n- Drop rows that have neither GCLID nor email, and duplicates of the same lead + stage.\n- Drop rows where the stage date is more than 90 days after the first-touch date if there is a GCLID, or more than 63 days after it if there is only an email (Google won't import them). List what you dropped and why.\n- Don't invent values.\n\nThen tell me: how many rows in, how many out, how many dropped and why, and any data problems (for example many missing GCLIDs, which would mean our hidden form fields are broken).\nWrite the Python you used so I can re-run it next week."} claudeHow="Export the CRM report as CSV, attach it in a new chat and paste this. Claude will use Claude’s code execution (file analysis) to process it. Ask for the result as a downloadable CSV. Save the prompt in a Claude Project so each week is one upload and one message." chatgptHow="Export the CRM report as CSV, attach it in a new chat and paste this. ChatGPT will use ChatGPT’s data analysis to process it and give you a downloadable CSV. Save the prompt in a ChatGPT Project instructions so each week is one upload and one message." />

<details className="gads-deeper">
<summary><span className="gads-deeper-tag">Go deeper</span> Why not just optimise for form fills forever?</summary>
<div className="gads-deeper-body">
<p>Because cheap form fills and valuable leads come from different searches. A keyword like "free invoice template" can produce lots of form fills at a low CPA and almost no pipeline.</p>
<p>A keyword like "invoice approval software for manufacturing" produces fewer, more expensive leads that become deals. On form fills alone, Smart Bidding will shift money towards the first.</p>
<p>With SQL or pipeline values uploaded, it shifts towards the second. This is often the single biggest improvement in a B2B account.</p>
</div>
</details>

<div className="gads-var" data-budget="starter">
<div className="gads-callout gads-callout-region">
<p className="gads-callout-title">Starter budget</p>
<p>You may only have a handful of SQLs a month, which isn't enough to bid on. Upload them anyway as secondary conversions; they're your best quality report, and they build history.</p>
<p>Keep bidding on the website conversion until volumes grow.</p>
</div>
</div>

<div className="gads-var" data-budget="advanced">
<div className="gads-callout gads-callout-region">
<p className="gads-callout-title">Advanced budget</p>
<p>Automate uploads (scheduled from a Google Sheet or SFTP, or a native CRM connector) and add a daily or twice-weekly cadence, so bidding gets signals faster.</p>
<p>With enough volume, move to value-based bidding (Target ROAS) on pipeline values.</p>
</div>
</div>

<section className="gads-donow" aria-labelledby="donow-tracking">
<h2 id="donow-tracking">Do this now</h2>
<ul className="gads-checklist" data-module="tracking">
<li data-id="cmp-live" data-region="eu">Consent banner live with Consent Mode v2 defaults (all four denied) loading before the Google tag.</li>
<li data-id="consent-other" data-region="us india apac latam mea">Confirm with legal what consent or notice your countries need, and set the CMP for any EU/UK visitors.</li>
<li data-id="tag">Google tag (Google Ads + GA4) in the Astro base layout.</li>
<li data-id="conversion">One primary conversion action with a value, firing on the thank-you step.</li>
<li data-id="link">GA4 linked, auto-tagging on, Final URL suffix with UTMs set.</li>
<li data-id="hidden">GCLID and UTM hidden fields mapped to CRM fields; test lead verified.</li>
<li data-id="ec">Enhanced conversions for leads turned on.</li>
<li data-id="stage2">Calendar reminder for month two: create offline conversion actions and do the first CSV upload.</li>
</ul>
</section>

Next: **Geographic Targeting and Bidding**
