Facebook Offline Conversion Tracking: Complete Setup Guide

The iOS 14.5 update in April 2021 fundamentally changed Facebook advertising. Overnight, the wealth of user data from iPhone users disappeared, crippling campaign performance for most of that year.

Facebook’s response was twofold: modeled data to fill attribution gaps, and Conversions API to bypass browser limitations. While these solutions helped, they also opened the door to more sophisticated tracking methods—including offline conversion imports.

Over the years, a host of use cases have evolved using Conversions API, referred to as offline conversion importing. We’ll review some of these use cases and how to set it up, but first, a refresher on offline conversion importing.

Skip straight to the setup guide

TL;DR

iOS 14.5 killed Facebook’s tracking accuracy, but offline conversion imports can restore it. By capturing Facebook’s tracking parameters (FBC/FBP) plus customer data (email, phone) in your forms, then uploading conversions via API, you get dramatically better attribution.

Useful for lead qualification, long sales cycles, cross-channel tracking, and revenue attribution.

Setup involves: capture data → format for Meta → connect via API.

Understanding Facebook Offline Conversion Tracking

Offline conversion tracking captures customer actions that happen outside the browser—phone calls, in-store purchases, sales meetings. By uploading this data to Meta, you can attribute these conversions back to your original ad campaigns.

Similar to importing offline conversions with Google Click ID (GCLID), Meta’s Conversions API ingests data about a customer and uses that to match to user profiles on their platform.

The difference is in matching. Whereas Google uses GCLID, Meta uses Facebook Browser ID (fbp) and Facebook Click ID (fbc) to track users sessions and ad clicks.

The Power of FBC/FBP

Facebook browser ID (fbp) is stored in the user’s browser and acts as a user ID that’s generated regardless of whether an ad click occurs.

Facebook click ID (fbc), similar to GCLID, is generated only when a user clicks and is stored in the URL. This is the core method for attributing conversions back to an ad interaction.

Alone, these identifiers are able to match back to users on the Meta platform. Together, match rates improve significantly.

This transforms what is typically a probabilistic attribution model—where Meta ‘thinks’ it knows what happened and creates a correlative connection—into a more deterministic model where Meta knows exactly what happened.

Customer Identifiers: Connect Across Devices

Beyond tracking IDs, customer identifiers provide another crucial piece of the attribution puzzle. Customer identifiers are information provided at the point of sale or data submission, such as in a lead form on site or during a phone call with a call center.

The key forms of customer identifiers are email address and phone number, but Meta also tracks:

  • First and last name
  • City, state, and country
  • Date of birth
  • Gender
  • External ID (your internal customer ID)

These act as additional data points to tie back to customer profiles and, most importantly, facilitate matching across time and devices. When a customer interacts with your ad on their phone but converts on their laptop days later, these identifiers help Meta connect the dots.

Attribution: Tying it all together

Together with Facebook’s tracking IDs (fbc/fbp), customer identifiers create a comprehensive graph of anchor points for attribution. With shifts towards privacy over the last 5 years, setting up these redundant tracking methods has become increasingly necessary. These steps take a probabilistic measurement system and move it closer to being deterministic.
Two key points to keep in mind:

  • User data must be shared in a privacy-safe manner (hashed when required)
  • Storing identifiers requires proper setup in forms and CRM environments

This comprehensive approach to data collection sets the foundation for successful offline conversion tracking implementation.

How To Setup Meta Offline Conversion Tracking

Setting up offline conversion tracking starts with capturing the right data. While some fields are required, others can improve match rates and attribution accuracy.

Required Fields:

  • Email Address (hashed)
  • Phone Number (hashed)
  • fbc/fbp (not hashed)

Optional but Recommended Fields:

  • First Name (hashed)
  • Last Name (hashed)
  • City (not hashed)
  • State (not hashed)
  • Country (not hashed)

For a complete list of all supported customer identifiers and their formatting requirements, see Meta’s Customer Information Parameters documentation.

For the purpose of this example, we’ll focus on capturing the tracking parameters (FBC/FBP) and form data. The user will fill in their name, email address, and phone number, while we automatically capture the Facebook tracking parameters.

However, we don’t want to include fields for FBC and FBP that will cause confusion. To solve for this, we’ll create hidden fields and use JavaScript to populate them automatically.

Creating Hidden Form Fields

We’ve reviewed setting up hidden fields in the Google Click ID tracking guide. For a quick refresher:

  1. Set up hidden fields in form builder
  2. Name hidden fields according to parameters
  3. Set up JavaScript to populate the fields

Setting up hidden fields is dependent on the platform used to build the form. Most have it as a built-in feature. 

Now that we’ve identified the required data fields, let’s walk through the technical implementation. We’ll start by setting up the tracking parameters that Meta needs for attribution.

Creating FBC in a Cookie

The first step in setting up the necessary data capture points is creating a cookie to translate fbclid into fbc.

The FBC format is: fb.1.[timestamp].[fbclid_value] where the timestamp represents when the click occured.

To do this a custom HTML tag extracts fbclid from the URL, appends the additional information, and stores it in a first-party cookie.

Note: We’re using localStorage because localStorage is the most persistent form of browser tracking and allows for better first-click attribution.

  • Tag Type: Custom HTML
  • Trigger: All Pages (or a specific Landing Page)
Google Tag Manager Custom HTML tag showing JavaScript code for storing Facebook Click ID (FBC) in cookies with FBCLID parameter extraction and formatting
Detailed Code
<script>
// Store FBC in cookie when FBCLID is present in URL
function storeFBC() {
  var urlParams = new URLSearchParams(window.location.search);
  var fbclid = urlParams.get('fbclid');
  
  if (fbclid) {
    // Check if FBC cookie already exists
    var existingFBC = null;
    var cookies = document.cookie.split(';');
    for (var i = 0; i < cookies.length; i++) {
      var cookie = cookies[i].trim();
      if (cookie.indexOf('fbc=') === 0) {
        existingFBC = cookie.substring(4);
        break;
      }
    }
    
    // Only create new FBC if one doesn't exist (preserves original timestamp)
    if (!existingFBC) {
      var fbc = 'fb.1.' + Math.floor(Date.now() / 1000) + '.' + fbclid;
      document.cookie = "fbc=" + fbc + "; path=/; max-age=" + (90 * 24 * 60 * 60);
    }
  }
}

// Run when page loads
storeFBC();
</script>

Once this is done, a tag is needed to push all the necessary variables into the hidden fields.

Automatically Populating Tracking Parameters

The key to successful offline conversion tracking is capturing Facebook’s tracking parameters (FBC and FBP) from cookies and URL parameters. Here’s the JavaScript code that handles this automatically:

  • Tag Type: Custom HTML
  • Trigger: Page View
Google Tag Manager Custom HTML tag configuration showing JavaScript code for Facebook tracking parameter capture with line numbers and syntax highlighting
Detailed Code
<script>
// Get FBCLID from existing cookie
function getFBCLID() {
  var cookies = document.cookie.split(';');
  for (var i = 0; i < cookies.length; i++) {
    var cookie = cookies[i].trim();
    if (cookie.indexOf('fbclid=') === 0) {
      return cookie.substring(7);
    }
  }
  return '';
}

// Format FBCLID as FBC
function getFBC() {
  var fbclid = getFBCLID();
  if (fbclid) {
    return 'fb.1.' + Math.floor(Date.now() / 1000) + '.' + fbclid;
  }
  return '';
}

// Get FBP from Meta's cookie
function getFBP() {
  var cookies = document.cookie.split(';');
  for (var i = 0; i < cookies.length; i++) {
    var cookie = cookies[i].trim();
    if (cookie.indexOf('_fbp=') === 0) {
      return cookie.substring(5);
    }
  }
  return '';
}

function populateTrackingFields() {
  // Get URL parameters for UTM
  var urlParams = new URLSearchParams(window.location.search);
  
  // Facebook tracking - read from existing cookies
  var fbp = getFBP();
  var fbc = getFBC();
  
  // UTM parameters (these come from URL)
  var utmSource = urlParams.get('utm_source');
  var utmMedium = urlParams.get('utm_medium'); 
  var utmCampaign = urlParams.get('utm_campaign');
  var utmContent = urlParams.get('utm_content');
  var utmTerm = urlParams.get('utm_term');
  
  // Populate Facebook fields
  var fbpField = document.querySelector('input[name="input_20"]');
  var fbcField = document.querySelector('input[name="input_24"]');
  
  if (fbpField && fbp) {
    fbpField.value = fbp;
  }
  
  if (fbcField && fbc) {
    fbcField.value = fbc;
  }
  
  // Populate UTM fields
  var utmSourceField = document.querySelector('input[name="input_23"]');
  var utmMediumField = document.querySelector('input[name="input_22"]');
  var utmCampaignField = document.querySelector('input[name="input_21"]');
  var utmContentField = document.querySelector('input[name="input_26"]');
  var utmTermField = document.querySelector('input[name="input_25"]');
  
  if (utmSourceField && utmSource) {
    utmSourceField.value = utmSource;
  }
  
  if (utmMediumField && utmMedium) {
    utmMediumField.value = utmMedium;
  }
  
  if (utmCampaignField && utmCampaign) {
    utmCampaignField.value = utmCampaign;
  }
  
  if (utmContentField && utmContent) {
    utmContentField.value = utmContent;
  }
  
  if (utmTermField && utmTerm) {
    utmTermField.value = utmTerm;
  }
}

// Run when page loads
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', populateTrackingFields);
} else {
  populateTrackingFields();
}
</script>

To use this script:

  1. Update the TRACKING_CONFIG object with your form’s actual field names
  2. Add the script to your landing page (and any pages with conversion forms)
  3. The script will automatically populate the hidden fields when the page loads

Finding Hidden Field Names

To find the field names, simply Inspect Element (right click + Inspect or ctrl + shift + i) – find the HTML that corresponds to each field and the input name.

HTML form field inspection showing email input element with highlighted name attribute 'input_1' and various field properties like type, class, and validation settings

In this case, the name was ‘input_1’. Each DOM element variable needs to be created with this input name. This will vary based on the form setup.

Google Tag Manager DOM Element variable configuration showing CSS Selector method with 'input[name='input_1']' selector and 'value' attribute setting

Once these are created for each user-provided variable (email, phone, etc.), the data needs to be hashed for privacy compliance purposes.

Hashing User Data

Facebook requires sensitive user data to be hashed using SHA-256 encryption before uploading. This can be down through two means:

  • In the CRM or backend system (recommended)
  • In the browser (less secure)

Note: FBC and FBP values should not be hashed- they are already anonymized.

Once your form captures both the user data and tracking parameters, you’ll be ready to import conversions back into Meta Ads Manager.

Importing Offline Conversions into Meta Ads

Now that the data is all captured in your backend system, it’s time to import it back into Meta using Conversions API.

Creating a Conversions API dataset

The following steps outline how to create a new dataset for offline conversion data:

1. Navigate to Events Manager in your Meta Business Account

Meta Business Manager navigation menu with Events Manager highlighted in blue, showing other options like Campaigns, Ads Reporting, and Audiences

2. Click on ‘Datasets’ and then on the left hand side ‘Add Events’

Events Manager sidebar navigation showing Connect Data section with Overview, Datasets, Custom Conversions, and Partner Integrations options
Events Manager datasets overview page with red highlighted 'Add Events' button and table showing existing events, their status, and integration details

3. Select Your Pixel to Connect Conversions API

Add new event dialog box showing three integration options: Conversions API, Conversions API Integrations (Lead Ads), and Meta Pixel with expandable arrows

4. Click Get Started, and ‘Generate Access Token’

Generate Access Token page with blue 'Generate Access Token' button and explanation text about API access requirements and security

Configuring Event Parameters

Event parameters needs to be sent in a specific format to meet Meta’s requirements. What you’ll need:

Required Parameters:

  • event_name: The conversion event (name this anything)
  • event_time: Unix timestamp when the conversion occurred
  • user_data: Object containing customer identifiers (email, phone, etc.)
  • custom_data: Object containing any conversion specific data (optional)

These parameters will be formatted into a json object structure:

Example Payload

[
  {
    “event_name”: “[CREATE YOUR NAME]”,
    “event_time”: 1678888888,
    “user_data”: {
      “em”: “2816913d80cf0d796df32130e527025816922b115b8134370d06173004e028b0”,
      “ph”: “96b6379555c4d29193267d3e098801530932822a988d87a716c174360e2a2221”,
      “fbc”: “fb.1.1678888888888.xxxx”,
      “fbp”: “fb.1.1678888888888.yyyy”,
      “client_ip_address”: “192.168.1.1”,
      “client_user_agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36”
    },
    “action_source”: “crm”
  }
]

From here, the API call is ready to be setup in your CRM or backend system.

API Endpoint and Authentication

Your backend system will need to send POST requests to Meta’s Conversions API endpoint.

Endpoint: https://graph.facebook.com/v18.0/{dataset_id}/events

This can be found in the Payload Helper section of Conversions API setup

Meta Conversions API documentation page showing API endpoint, POST request instructions, and Launch Payload Helper button for building event payloads

Certain headers may also be required detailing the format and authorization. The can be customized as follows:

  • Authorization: Bearer {access_token}
  • Content-Type: application/json

Once the API call is set up, it’s time to test that the payload is successfully being delivered.

Testing Your Event Setup

Start by accessing the ‘Test Events’ tab in the Meta Events Manager. Here you can select to test from web or CRM.

Meta Events Manager Test Events tab showing CRM testing interface with dropdown to select marketing channel and test event validation message

For this test, choose CRM and then the Page you want to test. A Lead ID will be generated.

Meta Test Events interface for CRM testing showing Page and Instant Form dropdowns, 'Create test lead' button, and generated Lead ID with copy functionality

This Lead ID needs to be added to the payload, and a test lead needs to be submitted.

Example Payload

[
  {
    “event_name”: “[CREATE YOUR NAME]”,
“test_event_code”: “108244730457035”,  // Added manually for testing
    “event_time”: 1678888888,
    “user_data”: {
      “em”: “2816913d80cf0d796df32130e527025816922b115b8134370d06173004e028b0”,
      “ph”: “96b6379555c4d29193267d3e098801530932822a988d87a716c174360e2a2221”,
      “fbc”: “fb.1.1678888888888.xxxx”,
      “fbp”: “fb.1.1678888888888.yyyy”,
      “client_ip_address”: “192.168.1.1”,
      “client_user_agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36”
    },
    “action_source”: “crm”
  }
]

A lead should show up in the ‘Test Events’ section, though it may take up to 30 minutes. This will help verify that all data is formatted properly.

Once this is confirmed, the test code can be removed from the payload. Just be sure keep everything else in the payload the same, or risk misconfiguring.

Why Implement Offline Conversion Tracking?

With iOS updates and privacy changes reducing browser tracking signals, Meta needs better data to match conversions back to ad interactions. Offline conversion tracking provides this through two key methods:

  • FBC/FBP Tracking: Connects conversions to original ad clicks or browser sessions
  • User Data Matching: Links cross-device engagement using email, phone, and other identifiers

Combined, these dramatically improve match rates and attribution accuracy. This solves for specific business challenges.

Lead Qualification

Import only qualified leads after your sales team has vetted them, giving Meta higher-quality conversion signals for optimization instead of all form submissions.

Key Takeaway: Solves for lead quality issues which can be problematic in Meta Ads

Long Sales Cycle Tracking

Bridge the gap between early engagement (like downloading a guide) and final purchase months later. Essential for B2B companies where consideration periods extend weeks or months.

Key Takeaway: This bridges the gap between early engagement and last click conversion.

Cross-Channel Integration

Track offline conversions from retail stores, phone sales, or in-person meetings by matching customer data back to original ad engagement.

Key Takeaway: Useful particularly for businesses that have retail stores or call centers.

Revenue Attribution

Connect actual purchase amounts to marketing campaigns, especially valuable when sales happen offline or through sales teams long after initial ad interaction.

For example, conversion lag can be up to 30 days for longer sales cycles, making short term optimization more difficult.

Key Takeaway: Improves ability to tie ROI to marketing efforts

Starting With Offline Conversion Importing

The key to successful offline conversion tracking is first identifying a clear business need. While browser tracking can be quite effective on its own, the real value of offline conversion imports lies in establishing enhanced conversion tracking methods.

Rather than simply using OCT imports as redundant conversion tracking (server side implementation can act as redundant tracking), establishing a new conversion tracking method is the real value.

Set up may seem technical at first, but can be boiled down to three key steps:

  1. Capture comprehensive data – Collect user data and browser tracking parameters in forms
  2. Format data for Meta – Structure conversion data according to API requirements
  3. Establish API connection – Set up automated data flow between your CRM and Meta Ads

With this framework, businesses can bridge the gap between online engagement and offline conversions. Start with one use case, test thoroughly, and expand as you see results. In today’s privacy-focused landscape, comprehensive attribution isn’t just helpful, it’s essential for maintaining competitive advantage.

Share:

Don't Miss New Posts
Get new articles directly to your inbox as soon as they're published.

Table of Contents

Continue Reading

Sign Up for Weekly Updates

Get new articles directly to your inbox as soon as they’re published.