Meta Ads Data Layer Setup | OpsBlu Docs

Meta Ads Data Layer Setup

How data is structured and prepared before Facebook Pixel and Conversions API receive events.

Required Fields

  • Persist event-specific parameters: content_ids, content_type, content_name, currency, value for e-commerce events.
  • Include user matching data (hashed email, phone, external_id) for improved Event Match Quality.
  • Capture fbp (Facebook browser cookie) and fbc (Facebook click ID) from the browser to pass to Conversions API.
  • Normalize e-commerce objects: currency (ISO 4217 code), value (decimal), num_items (integer), and contents array with id and quantity.
  • Attach campaign attribution data (utm_source, utm_medium, utm_campaign, fbclid) for proper ad performance tracking.
  • Include event_id and event_time for deduplication between pixel and Conversions API events.

Data Layer Structure for GTM

Use a standard dataLayer push format to trigger Facebook Pixel events in Google Tag Manager:

dataLayer.push({
  'event': 'purchase',
  'ecommerce': {
    'currency': 'USD',
    'value': 79.99,
    'transaction_id': 'T123456',
    'items': [
      {
        'item_id': 'SKU_12345',
        'item_name': 'Blue Widget',
        'quantity': 2,
        'price': 39.99
      }
    ]
  },
  'user_data': {
    'email_hash': 'hashed_email',
    'phone_hash': 'hashed_phone',
    'external_id': 'user_123'
  }
});

Map dataLayer variables to Facebook Pixel event parameters in GTM:

  • ecommerce.currency → currency
  • ecommerce.value → value
  • ecommerce.items → contents (transform to Meta format)
  • ecommerce.transaction_id → event_id
  • user_data.email_hash → em (advanced matching)

User Data Hashing

Hash personally identifiable information (PII) before adding to the dataLayer or sending to Conversions API. Use SHA-256 hashing and normalize data before hashing:

  • Email: Lowercase, trim whitespace, hash with SHA-256.
  • Phone: Remove spaces, dashes, parentheses; use E.164 format (+1234567890); hash with SHA-256.
  • Name fields: Lowercase, remove special characters, trim whitespace, hash with SHA-256.
  • Geographic fields: Lowercase, use standard abbreviations (e.g., "ca" for California), hash with SHA-256.

Example hashing function (JavaScript):

async function hashSHA256(value) {
  const normalized = value.toLowerCase().trim();
  const encoder = new TextEncoder();
  const data = encoder.encode(normalized);
  const hashBuffer = await crypto.subtle.digest('SHA-256', data);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}

Conversions API Server-Side Data

When sending events from your server to Conversions API, structure the payload to include:

  • event_name: Standard or custom event name (e.g., "Purchase", "Lead").
  • event_time: Unix timestamp in seconds.
  • event_id: Unique identifier matching the pixel event for deduplication.
  • event_source_url: Full URL where the event occurred.
  • action_source: "website", "app", "email", "phone_call", etc.
  • user_data: Object containing hashed email, phone, fbp, fbc, and browser data.
    • em, ph, fn, ln, ct, st, zp, country (all hashed)
    • client_ip_address, client_user_agent (not hashed)
    • fbp (Facebook browser cookie, not hashed)
    • fbc (Facebook click ID, not hashed)
  • custom_data: Event-specific parameters (currency, value, content_ids, contents, etc.).

Example CAPI payload:

{
  "data": [
    {
      "event_name": "Purchase",
      "event_time": 1640000000,
      "event_id": "order_12345",
      "event_source_url": "https://example.com/checkout/success",
      "action_source": "website",
      "user_data": {
        "em": "hashed_email",
        "ph": "hashed_phone",
        "client_ip_address": "192.0.2.1",
        "client_user_agent": "Mozilla/5.0...",
        "fbp": "fb.1.1640000000.123456789",
        "fbc": "fb.1.1640000000.AbCdEfGh"
      },
      "custom_data": {
        "currency": "USD",
        "value": 79.99,
        "content_ids": ["SKU_12345"],
        "content_type": "product",
        "num_items": 2,
        "contents": [
          {"id": "SKU_12345", "quantity": 2}
        ]
      }
    }
  ]
}

Governance Notes

  • Document how consent modifies the dataLayer structure (e.g., do not send hashed PII if user rejects marketing cookies).
  • Version the dataLayer schema to keep GTM variables, pixel events, and CAPI payloads aligned after code releases.
  • Maintain a mapping document between your internal dataLayer and Meta's required parameters.
  • Establish data retention policies for event_id and event_time to support deduplication lookups.

Validation Steps

  • Check Facebook Pixel Helper to confirm parameters are populated correctly for each event.
  • Review Events Manager Test Events for both pixel and CAPI to verify parameter completeness and accuracy.
  • Validate Event Match Quality score (target 7.0+) by ensuring sufficient user_data fields are included.
  • Use GTM Preview mode to inspect dataLayer contents before and after event triggers.
  • Screenshot dataLayer snapshots and Events Manager payloads for compliance and audit documentation.
  • Test hashing functions with known inputs to confirm SHA-256 output matches expected values.