Skip to main content

Advertising Platform Integration

Integrate GA4 with major advertising platforms (Google Ads, Meta, LinkedIn, Microsoft) for unified measurement and optimization.

Platform Overview

Integration Methods

| Platform | Native GA4 | Server-Side | API Import | |----------|------------|-------------|------------| | Google Ads | Yes (linked) | Yes | Yes | | Meta Ads | No | Yes (CAPI) | Yes | | LinkedIn Ads | No | Yes | Yes | | Microsoft Ads | No | Yes | Yes | | TikTok Ads | No | Yes | Yes |

Why Integrate?

| Benefit | Description | |---------|-------------| | Cross-platform attribution | Unified view across channels | | Audience sharing | Use GA4 segments for targeting | | Offline conversion import | Report CRM conversions to ad platforms | | Better optimization | Platform algorithms use your data |

Google Ads Integration

Linking GA4 to Google Ads

  1. GA4 Admin → Product Links → Google Ads links
  2. Click Link
  3. Select Google Ads account
  4. Enable Personalized advertising and Auto-tagging

Auto-Tagging Benefits

When enabled, Google Ads appends gclid to URLs:

https://yoursite.com/landing-page?gclid=abc123xyz

This enables:

  • Automatic campaign data in GA4
  • Cross-device attribution
  • Offline conversion import
  • Better bidding signals

Import GA4 Conversions to Google Ads

  1. GA4 Admin → Product Links → Google Ads links
  2. Click on linked account
  3. Select Import tab
  4. Choose conversion events to import

Best practice: Import both primary (purchase) and micro (add_to_cart) conversions.

Enhanced Conversions for Leads

For lead gen, use enhanced conversions with server-side:

// In server-side GTM
const conversionData = {
  conversionAction: 'AW-CONVERSION_ID/LABEL',
  conversionDateTime: new Date().toISOString(),
  userIdentifiers: [{
    hashedEmail: sha256(event.user_data.email.toLowerCase()),
    hashedPhoneNumber: sha256(normalizePhone(event.user_data.phone))
  }]
};

Meta Ads Integration

Conversions API (CAPI)

Server-side is essential for Meta attribution accuracy:

Browser          Server             Meta
   │                │                 │
   │  Pixel Event   │                 │
   │────────────────│─────────────────│
   │                │                 │
   │    Blocked?    │   Server Event  │
   │       ⚠        │────────────────▶│
   │                │                 │
   └────────────────┴─────────────────┘

Server-Side GTM Setup

  1. Install Meta CAPI tag template
  2. Configure:

| Field | Value | |-------|-------| | Pixel ID | Your 15-16 digit ID | | Access Token | System user token | | Event Name | From client | | User Data | Map from event |

Event Deduplication

Use the same event_id in both browser pixel and CAPI:

// Generate unique event ID
const eventId = `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

// Browser pixel
fbq('track', 'Purchase', {
  value: 99.99,
  currency: 'USD'
}, { eventID: eventId });

// Data layer for server-side
dataLayer.push({
  event: 'purchase',
  event_id: eventId,  // Same ID
  value: 99.99,
  currency: 'USD'
});

GA4 + Meta Attribution

Compare in BigQuery:

-- Compare GA4 vs Meta attribution
WITH ga4_purchases AS (
  SELECT
    user_pseudo_id,
    traffic_source.source,
    (SELECT value.double_value FROM UNNEST(event_params) WHERE key = 'value') as revenue
  FROM `project.analytics.events_*`
  WHERE event_name = 'purchase'
    AND _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
)
SELECT
  CASE
    WHEN LOWER(source) LIKE '%facebook%' OR LOWER(source) LIKE '%fb%' THEN 'Meta'
    WHEN LOWER(source) LIKE '%google%' THEN 'Google'
    ELSE 'Other'
  END as platform,
  COUNT(*) as purchases,
  SUM(revenue) as total_revenue
FROM ga4_purchases
GROUP BY platform

LinkedIn Ads Integration

Insight Tag Setup

Install via GTM:

// LinkedIn Insight Tag (via GTM Custom HTML)
_linkedin_partner_id = "YOUR_PARTNER_ID";
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
window._linkedin_data_partner_ids.push(_linkedin_partner_id);

(function(l) {
  if (!l){window.lintrk = function(a,b){window.lintrk.q.push([a,b])};
  window.lintrk.q=[]}
  var s = document.getElementsByTagName("script")[0];
  var b = document.createElement("script");
  b.type = "text/javascript";b.async = true;
  b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
  s.parentNode.insertBefore(b, s);})(window.lintrk);

Conversion Tracking

// Track LinkedIn conversions
dataLayer.push({
  event: 'generate_lead',
  linkedin_conversion_id: 12345678
});

// In GTM, fire LinkedIn conversion pixel:
lintrk('track', { conversion_id: 12345678 });

Server-Side LinkedIn

For B2B with long sales cycles, import offline conversions:

// LinkedIn Conversions API
const linkedinConversion = {
  conversion: 'urn:lla:llaPartnerConversion:123456',
  conversionHappenedAt: Date.now(),
  user: {
    userIds: [{
      idType: 'SHA256_EMAIL',
      idValue: sha256(email)
    }]
  },
  conversionValue: {
    currencyCode: 'USD',
    amount: '50000'
  }
};

await fetch('https://api.linkedin.com/rest/conversionEvents', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'LinkedIn-Version': '202401'
  },
  body: JSON.stringify(linkedinConversion)
});

Microsoft Ads Integration

UET Tag Setup

// Microsoft UET Tag
(function(w,d,t,r,u){var f,n,i;w[u]=w[u]||[],f=function(){
var o={ti:"YOUR_TAG_ID"};o.q=w[u],w[u]=new UET(o),w[u].push("pageLoad")},
n=d.createElement(t),n.src=r,n.async=1,n.onload=n.onreadystatechange=function(){
var s=this.readyState;s&&s!=="loaded"&&s!=="complete"||(f(),n.onload=n.onreadystatechange=null)},
i=d.getElementsByTagName(t)[0],i.parentNode.insertBefore(n,i)
})(window,document,"script","//bat.bing.com/bat.js","uetq");

Conversion Events

// Microsoft Ads conversion
window.uetq = window.uetq || [];
window.uetq.push('event', 'purchase', {
  'revenue_value': 99.99,
  'currency': 'USD'
});

Offline Import

Microsoft supports offline conversion import via:

  1. Manual CSV upload
  2. API integration
  3. Google Ads import (mirror your Google setup)

Cross-Platform Attribution

The Attribution Challenge

Each platform claims credit differently:

| Platform | Default Model | Lookback | |----------|---------------|----------| | GA4 | Data-driven | 30-90 days | | Google Ads | Data-driven | 30 days | | Meta | 7-day click / 1-day view | 7/1 days | | LinkedIn | Last touch | 90 days | | Microsoft | Last click | 30 days |

Reconciliation Strategy

  1. Accept discrepancy - Each platform optimizes to its data
  2. Use GA4 for comparison - Cross-channel view
  3. Run incrementality tests - True lift measurement
  4. Focus on trends - Not absolute numbers

Unified Dashboard

Create cross-platform view:

-- BigQuery: Platform performance comparison
SELECT
  CASE
    WHEN REGEXP_CONTAINS(LOWER(source), r'facebook|fb|instagram|ig|meta') THEN 'Meta'
    WHEN REGEXP_CONTAINS(LOWER(source), r'google|cpc') AND medium = 'cpc' THEN 'Google Ads'
    WHEN REGEXP_CONTAINS(LOWER(source), r'linkedin|li') THEN 'LinkedIn'
    WHEN REGEXP_CONTAINS(LOWER(source), r'bing|microsoft') THEN 'Microsoft'
    ELSE 'Other'
  END as platform,
  COUNT(DISTINCT user_pseudo_id) as users,
  COUNT(DISTINCT session_id) as sessions,
  COUNTIF(event_name = 'purchase') as conversions,
  SUM(CASE WHEN event_name = 'purchase' THEN value END) as revenue
FROM (
  SELECT
    user_pseudo_id,
    traffic_source.source as source,
    traffic_source.medium as medium,
    event_name,
    (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') as session_id,
    (SELECT value.double_value FROM UNNEST(event_params) WHERE key = 'value') as value
  FROM `project.analytics.events_*`
  WHERE _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
)
GROUP BY platform
ORDER BY revenue DESC

Audience Sharing

GA4 to Google Ads

Automatic when linked:

  1. Create audience in GA4
  2. Appears in Google Ads shared library
  3. Use for targeting and bidding

GA4 to Meta (via Segment/mParticle)

// Example: Segment to Meta sync
analytics.identify(userId, {
  email: user.email,
  high_value: user.ltv > 500
});

// Segment syncs to Facebook Custom Audiences

Manual Export for All Platforms

-- Export audience for upload
SELECT
  email_hash,
  phone_hash
FROM (
  SELECT
    sha256(LOWER(TRIM(user_data.email))) as email_hash,
    sha256(REGEXP_REPLACE(user_data.phone, r'[^0-9+]', '')) as phone_hash
  FROM `project.analytics.user_data`
  WHERE segment = 'high_value'
)
WHERE email_hash IS NOT NULL

Best Practices

Consistent Naming

| Element | Format | Example | |---------|--------|---------| | Campaign | platform_objective_target | google_awareness_enterprise | | Ad Set | audience_placement | remarketing_feed | | Ad | creative_variant | video_v1 |

Measurement Hierarchy

┌─────────────────────────────────────────────────────────┐
│                 Measurement Strategy                     │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Level 1: Platform Reporting                            │
│  → Daily optimization, in-platform metrics              │
│                                                         │
│  Level 2: GA4 Cross-Platform                            │
│  → Weekly comparison, attribution analysis              │
│                                                         │
│  Level 3: Incrementality Testing                        │
│  → Monthly/quarterly, true lift measurement             │
│                                                         │
└─────────────────────────────────────────────────────────┘

Previous: Email Platform Integration Next: E-commerce Platform Integration