Overview

Meta Conversions API (CAPI) creates a direct connection between your server and Meta’s systems, helping optimize ad targeting, decrease cost per action, and improve measurement accuracy. By implementing CAPI through Server-Side Google Tag Manager (sGTM) you can maintain data privacy and control.

We highly recommend implementing Meta CAPI with Hardal before setting up Meta CAPI via sGTM.

Prerequisites

Before proceeding with this integration, ensure you have:

  • A Google Tag Manager account with administrative access
  • Google Analytics 4 (GA4) properly configured
  • A Meta Business Manager account with a Pixel ID

If your system uses a version older than GA4, you’ll need to upgrade your existing tag manager setup to use GA4 before proceeding with this integration.

Step-by-Step Implementation

1

sGTM Setup

2

Configure Meta Browser ID and Click ID

To ensure proper tracking and deduplication, you’ll need to pass Meta’s browser ID and click ID to your server:

  1. In your web container, create two User-Defined Variables
  • Meta Browser ID:
    • Variable Type: 1st-Party Cookie
    • Cookie Name: _fbp
  • Meta Click ID:
    • Variable Type: 1st-Party Cookie
    • Cookie Name: _fbc
  1. In your GA4 Configuration tag (Google Tag), add these fields:
    • Field Name: x-fb-ck-fbp Value: Your Meta Browser ID variable
    • Field Name: x-fb-ck-fbc Value: Your Meta Click ID variable

If you’ve set up a custom domain for your server container, these IDs may be passed automatically. However, it’s still recommended to explicitly configure them to ensure proper tracking.

3

Set Up User Data Parameters

First, you’ll need to create variables in your Google Tag Manager web container for each user data parameter you want to track:

  1. Go to your GTM web container dashboard
  2. Navigate to Variables in the left sidebar
  3. Click New under “User-Defined Variables”
  4. Select Data Layer Variable as the variable type
  5. Set the Data Layer Variable Name according to the mapping table (see below)
  6. Set an appropriate name for the variable (e.g., “User Email”)
  7. Save the variable
4

Follow the Parameter Mapping Structure

Use this mapping structure to correctly set up your variables:

Meta ParameterGA4 Field NameData Layer Variable Name
email (em)user_data.email_addresseventModel.user_data.email_address
phone (ph)user_data.phone_numbereventModel.user_data.phone_number
external_idx-fb-ud-external_idN/A
first_name (fn)user_data.address.first_nameeventModel.user_data.address.first_name
last_name (ln)user_data.address.last_nameeventModel.user_data.address.last_name
city (ct)user_data.address.cityeventModel.user_data.address.city
state (st)user_data.address.regioneventModel.user_data.address.region
zip (zp)user_data.address.postal_codeeventModel.user_data.address.postal_code
country (country)user_data.address.countryeventModel.user_data.address.country

After adding all Data Layer Variables to your web container, the Variables section should look like following:

Focus on implementing the high-priority parameters first: email, phone number, and external ID provide the best match rates for Meta’s systems.

5

Add Variables to Your Google Tag Configuration

Once you’ve created these variables, you need to add them to your Google Tag:

  1. Open your Google Tag
  2. Under Configuration settings, click Add parameter
  3. For each parameter, enter the GA4 Field Name from the table above as the Configuration Parameter
  4. Set the Value to the corresponding variable you created
6

Implement Data Collection in Your Website

You’ll need to ensure your website is collecting and passing this data to the data layer. For example:

// When collecting user information (e.g., during checkout)
dataLayer.push({
  'event': 'user_data_collected',
  'user_data': {
    'email_address': 'example@domain.com', // This should be hashed in production
    'phone_number': '+15551234567', // This should be hashed in production
    'address': {
      'first_name': 'John', // This should be hashed in production
      'last_name': 'Doe', // This should be hashed in production
      'city': 'New York', // This should be hashed in production
      'region': 'NY', // This should be hashed in production
      'postal_code': '10001', // This should be hashed in production
      'country': 'US' // This should be hashed in production
    }
  }
});
7

Consider Important Privacy Requirements

Always handle user data with care and in compliance with privacy regulations like GDPR, CCPA, and others.

When implementing user data parameters:

  • Always hash personally identifiable information (PII) before sending it to Meta
  • While GA4 and the Meta Conversions API tag will automatically hash this data, it’s best practice to hash it yourself before pushing to the data layer
  • Implement proper consent management to comply with privacy regulations
  • Only collect and send data that you have permission to use for advertising purposes

These user data parameters will significantly improve the effectiveness of your Meta advertising campaigns by providing better data for attribution and audience targeting.

8

Create GA4 Event Tags

Set up GA4 Event tags to track specific user actions:

  1. In your web container, create a new GA4 Event tag
  2. Select your GA4 Event tag
  3. Set the Event Name to match one of Meta’s standard events:
Meta Event NameGA4 Event Name
PageViewpage_view
AddToCartadd_to_cart
AddPaymentInfoadd_payment_info
AddToWishlistadd_to_wishlist
CompleteRegistrationsign_up
InitiateCheckoutbegin_checkout
Leadgenerate_lead
Purchasepurchase
Searchsearch
ViewContentview_item
  1. Add event parameters based on your tracking needs
  2. Configure the event_id parameter for deduplication (see below)
  3. Set appropriate triggers for each event
  4. Save and publish your tags
9

Set Up Deduplication

To prevent duplicate events when using both Pixel and CAPI, implement event_id deduplication:

  1. Create a custom JavaScript variable to generate unique IDs:
function() {
  var gtmData = window.google_tag_manager[{{Container ID}}].dataLayer.get('gtm');
  return gtmData.start + '.' + gtmData.uniqueEventId;
}
  1. Create a Data Layer Variable (e.g., FBEventIdVar) with Data Layer Variable Name: eventModel.event_id
  2. In your Meta Pixel tag:
fbq('track', 'Purchase', {/* parameters */}, {eventID: {{FBEventIdVar}} });
  1. In your GA4 Event tag, add an event parameter:
    • Parameter Name: event_id
    • Value: Your event ID variable

Use the same trigger for both your Meta Pixel tag and GA4 Event tag to ensure consistent firing and proper deduplication.

10

Configure the GA4 Client in Server Container

In your server container, ensure the GA4 Client is set up correctly:

  1. Go to your server container
  2. Navigate to “Clients”
  3. Edit the “GA4” client (or create it if it doesn’t exist)
  4. Enable “Default GA4 paths”
  5. Enable “Default gtag.js paths” and add your GA4 Measurement ID(s)
  1. Save the client configuration

The GA4 Client is responsible for processing incoming data from your web container and transforming it into a format that other server-side tags can use.

11

Install Meta Conversions API Tag

The final step is to set up the Meta Conversions API Tag:

  1. In your server container, navigate to “Tags”
  2. Click “New” and navigate to “Discover More”. Search for “Conversions API Tag by facebookincubator”
  1. Generate Meta Access Token
    • Log into your Meta Business Manager
    • Go to Events Manager
    • Select your Pixel
    • Navigate to the Settings tab
  • Copy Dataset ID and save it (marked as step 3)

  • Find the “Conversions API” section

  • Click “Generate access token”

  • Copy the generated token

  1. Create a trigger that fires on events from the GA4 Client
  1. Save and publish the tag

Keep your access token secure. It provides direct access to your Meta account and should never be exposed in client-side code.

Testing Your Implementation

  1. Enable Preview mode in your web container
  2. Enable Preview mode in your server container
  3. Navigate to your website and perform actions that should trigger events
  4. Verify that:
  • GA4 events are firing in the web container
  • Events are being received by the server container
  • Meta Conversions API tag is firing in the server container

Custom Data Parameters

To send additional event data to Meta, use these parameter mappings in your GA4 Event tags:

Meta ParameterGA4 Parameter
valuevalue
currencycurrency
search_stringsearch_term
order_idtransaction_id
content_idsx-fb-cd-content_ids
content_typex-fb-cd-content_type
content_namex-fb-cd-content_name
content_categoryx-fb-cd-content_category
contentsitems OR x-fb-cd-contents
num_itemsx-fb-cd-num_items
predicted_ltvx-fb-cd-predicted_ltv
statusx-fb-cd-status
delivery_categoryx-fb-cd-delivery_category

For array or object parameters like contents and custom_properties, remember to JSON.stringify them before sending.

Sample Event Implementation

Here’s an example of a purchase event with all recommended parameters:

gtag('event', 'purchase', {
  'event_id': generateEventId(),
  'transaction_id': 'ORDER_12345',
  'currency': 'USD',
  'value': 125.99,
  'user_data': {
    'email_address': '<HASHED_EMAIL>',
    'phone_number': '<HASHED_PHONE>',
    'address': {
      'first_name': '<HASHED_FIRST_NAME>',
      'last_name': '<HASHED_LAST_NAME>',
      'city': '<HASHED_CITY>',
      'region': '<HASHED_STATE>',
      'postal_code': '<HASHED_ZIP>',
      'country': '<HASHED_COUNTRY>'
    }
  },
  'items': [
    {
      'item_id': 'SKU_12345',
      'item_name': 'Premium Blue Jeans',
      'item_category': 'Apparel',
      'price': 70.99,
      'quantity': 1
    },
    {
      'item_id': 'SKU_67890',
      'item_name': 'Casual White T-Shirt',
      'item_category': 'Apparel',
      'price': 25.99,
      'quantity': 2
    }
  ]
});

Frequently Asked Questions