Back to Blog
GuidesJan 18, 2026|8 min read

Meta CAPI (Conversions API) Setup Guide

EA
Eduard Andrei

Founder at Adship

Meta CAPI (Conversions API) Setup Guide

The Meta Pixel alone is no longer sufficient for accurate conversion tracking. iOS privacy changes, ad blockers, and browser cookie restrictions have degraded pixel accuracy to 40–70% of actual events for most advertisers.

Meta Conversions API (CAPI) solves this by moving conversion data from the browser to your server, bypassing the privacy restrictions that break pixel tracking. This guide walks you through the complete CAPI setup — from Events Manager configuration through testing and validation.


What You'll Need Before Starting

Before configuring CAPI, confirm you have:

  • Meta Business Manager access — Admin or developer role
  • Ad account — Active account linked to your Business Manager
  • Facebook Page — Associated with your business
  • Server access — Ability to add code to your web server or ecommerce platform
  • Pixel installed — Existing browser pixel recommended (for dual-tracking with deduplication)
  • Access token — System user token or page token (covered in setup steps below)

Step 1: Create or Locate Your Dataset in Events Manager

Meta's Conversions API sends events to a dataset (previously called a pixel). If you have an existing pixel, your CAPI events should use the same dataset ID to enable deduplication between browser and server events.

  1. Go to Events Manager at business.facebook.com/events_manager
  2. Select your ad account from the top-left dropdown
  3. Click + Connect Data Sources if creating new, or select your existing pixel/dataset
  4. If creating new: choose WebConversions API → name your dataset
  5. Note the Dataset ID (also called Pixel ID) — you'll need it for all API calls

Step 2: Generate a System User Access Token

CAPI requires a long-lived access token. System user tokens are the recommended approach — they don't expire when users change passwords or revoke app permissions.

Create a System User

  1. In Business Manager, go to Business SettingsUsersSystem Users
  2. Click Add → name the system user (e.g., "CAPI Integration") → set role to Employee
  3. Click Add Assets → select your ad account → grant Advertiser access
  4. Click Add Assets → select your pixel/dataset → grant Analyze and Upload access

Generate the Token

  1. On the System User page, click Generate New Token
  2. Select your app (or create one at developers.facebook.com)
  3. Required permissions: ads_management, ads_read, business_management
  4. Set expiration: Never (for server-side automation)
  5. Copy and securely store the token — you won't be able to see it again

Step 3: Understand the CAPI Event Structure

Before implementing, understand what you're sending. Each CAPI event is a JSON payload sent to:

POST https://graph.facebook.com/v26.0/{dataset-id}/events

Minimum required fields:

{
  "data": [
    {
      "event_name": "Purchase",
      "event_time": 1741478400,
      "action_source": "website",
      "event_id": "order_12345_1678901234",
      "user_data": {
        "em": ["a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"],
        "ph": ["7c4a8d09ca3762af61e59520943dc26494f8941b"],
        "client_ip_address": "192.168.1.1",
        "client_user_agent": "Mozilla/5.0..."
      },
      "custom_data": {
        "value": 59.99,
        "currency": "USD",
        "order_id": "12345",
        "content_ids": ["SKU-001", "SKU-002"],
        "content_type": "product"
      }
    }
  ],
  "access_token": "YOUR_ACCESS_TOKEN"
}

Key fields explained:

FieldRequiredDescription
event_nameYesStandard event name (Purchase, Lead, etc.)
event_timeYesUnix timestamp when event occurred
action_sourceYeswebsite, app, phone_call, email, other
event_idDedupUnique ID — must match pixel eventID for deduplication
user_data.emRecommendedSHA-256 hashed email
user_data.phRecommendedSHA-256 hashed phone
client_ip_addressRecommendedUser's IP address (from request headers)
client_user_agentRecommendedUser's browser agent string

Step 4: Hash User Data Correctly

Meta requires PII to be SHA-256 hashed. Incorrect hashing is the most common setup error.

Hashing rules:

  • Lowercase before hashing
  • Remove whitespace before hashing
  • Phone numbers: E.164 format without + (e.g., 14155551234)
  • Email: user@example.com → lowercase → hash
  • Names: lowercase, no leading/trailing spaces

Python example:

import hashlib

def hash_data(value):
    return hashlib.sha256(value.lower().strip().encode()).hexdigest()

hashed_email = hash_data("User@Example.com")
# Result: correct lowercase hash

Node.js example:

const crypto = require('crypto')

function hashData(value) {
  return crypto.createHash('sha256')
    .update(value.toLowerCase().trim())
    .digest('hex')
}

Never send unhashed PII. Meta will reject events that appear to contain plain-text email addresses or phone numbers.


Step 5: Generate Event IDs for Deduplication

If you're running both pixel and CAPI (recommended), deduplication prevents Meta from counting the same conversion twice.

How deduplication works:

  1. Your browser pixel fires with eventID: "order_12345_ts_1678901234"
  2. Your server sends the same event with event_id: "order_12345_ts_1678901234"
  3. Meta sees matching IDs → counts as one event

Event ID generation strategy:

// Generate a stable, unique event ID for each conversion
function generateEventId(orderId) {
  const timestamp = Math.floor(Date.now() / 1000)
  return `order_${orderId}_${timestamp}`
}

// Pass to both pixel and CAPI:
const eventId = generateEventId(order.id)

// Pixel (browser):
fbq('track', 'Purchase', { value: 59.99, currency: 'USD' }, { eventID: eventId })

// CAPI (server):
// Send event_id: eventId in your API call

Important: Generate the event ID server-side and pass it to the browser for pixel use, not the other way around. This ensures consistency even if the browser is slow or blocks the pixel.


Step 6: Implement CAPI Events

Option A: Direct API Integration (Any Platform)

Send events directly from your server using HTTP:

// Node.js example
async function sendCapiEvent(eventName, orderData, userData) {
  const DATASET_ID = process.env.META_PIXEL_ID
  const ACCESS_TOKEN = process.env.META_ACCESS_TOKEN

  const payload = {
    data: [{
      event_name: eventName,
      event_time: Math.floor(Date.now() / 1000),
      action_source: 'website',
      event_id: generateEventId(orderData.id),
      user_data: {
        em: [hashData(userData.email)],
        ph: userData.phone ? [hashData(userData.phone)] : [],
        fn: [hashData(userData.firstName)],
        ln: [hashData(userData.lastName)],
        ct: [hashData(userData.city)],
        st: [hashData(userData.state)],
        zp: [hashData(userData.zip)],
        country: [hashData(userData.country)],
        client_ip_address: userData.ipAddress,
        client_user_agent: userData.userAgent,
        external_id: [hashData(userData.userId)]
      },
      custom_data: {
        value: orderData.total,
        currency: orderData.currency,
        order_id: orderData.id,
        content_ids: orderData.items.map(i => i.sku),
        content_type: 'product',
        num_items: orderData.items.length
      }
    }],
    access_token: ACCESS_TOKEN
  }

  const response = await fetch(
    `https://graph.facebook.com/v26.0/${DATASET_ID}/events`,
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload)
    }
  )

  if (!response.ok) {
    const error = await response.text()
    throw new Error(`CAPI error: ${error}`)
  }

  return response.json()
}

Option B: Shopify (Native Integration)

  1. In Shopify Admin → AppsFacebook & Instagram
  2. Under Data Sharing, enable Maximum level
  3. This activates Shopify's native analytics integration for purchase and checkout events

Note: Shopify's native integration sends purchase events but may miss other conversion events (add-to-cart, view content). For full coverage, supplement with a custom integration.

Option C: WooCommerce

  1. Install Official Meta for WooCommerce plugin (free from WordPress.org)
  2. Go to WooCommerceSettingsIntegrationFacebook
  3. Connect your Business Manager and enable CAPI
  4. Configure which events to send server-side

Step 7: Set Up Test Events

Before going live, verify your implementation sends correctly using Meta's Test Events tool.

  1. In Events Manager, select your dataset
  2. Click Test Events tab
  3. Copy the Test Event Code (format: TEST12345)
  4. Add test_event_code: "TEST12345" to your API payload temporarily:
{
  "data": [...],
  "access_token": "YOUR_TOKEN",
  "test_event_code": "TEST12345"
}
  1. Trigger test conversions on your website
  2. In Test Events, you should see events appear within 30–60 seconds
  3. Verify: event name, event parameters, user data fields received, deduplication working

What to check in test results:

  • ✅ Event appears with correct name
  • ✅ Custom data (value, currency) shows correctly
  • ✅ Match quality indicator — should show at least 3–4 matching parameters
  • ✅ If pixel is also firing: deduplication count shows > 0
  • ⚠️ If events don't appear after 2 minutes: check your access token and dataset ID

Step 8: Monitor Event Match Quality

After going live, track your Event Match Quality (EMQ) score in Events Manager.

Where to find it: Events Manager → Select dataset → Overview tab → Event Match Quality column

Score interpretation:

  • 6.0–7.0 — Excellent. Maximum attribution accuracy.
  • 4.0–5.9 — Good. Solid attribution, room for improvement.
  • 2.0–3.9 — Fair. Missing key match parameters.
  • Below 2.0 — Poor. Attribution significantly degraded.

How to improve low EMQ:

Missing parameterImpactFix
EmailHighEnsure you're capturing and hashing email from checkout
PhoneMediumAdd phone field to checkout, hash before sending
First/last nameMediumPass from order data
City/state/zipLow-MediumInclude from shipping address
External IDMediumPass your internal user ID (hashed)

Step 9: Validate Deduplication

In Events Manager, check that deduplication is working between your pixel and CAPI:

  1. Go to Events Manager → select your dataset
  2. Click Overview → find the Purchase event row
  3. Look at the Deduplicated column — this should show a percentage > 0% if both pixel and CAPI are sending the same events

Deduplication rate benchmarks:

  • 60–80% — Normal for dual-tracking setup (some pixel events block, some don't)
  • 90–100% — Both systems working perfectly with matching event IDs
  • 0% — Event IDs don't match or only one system is sending

If deduplication shows 0%, your event IDs are not matching. Check that:

  • Both pixel and server use the same event ID generation logic
  • The pixel receives the server-generated event ID before firing
  • Event IDs are unique per conversion (not reused)

Common Errors and Fixes

Error: "Invalid access token"

Cause: Token expired, permissions insufficient, or wrong token type. Fix: Regenerate system user token. Verify the system user has dataset access with "Upload" permission.

Error: "Invalid pixel ID" / "Dataset not found"

Cause: Wrong dataset ID, or system user doesn't have access to the dataset. Fix: Verify dataset ID in Events Manager URL. Add dataset to system user's assets.

Error: Events not appearing in Events Manager

Cause: Test event code not set (for test mode), events sent > 7 days ago, or API errors swallowed silently. Fix: Use test_event_code during testing. Log API responses in your server code. Check event_time is current Unix timestamp (not milliseconds).

Error: Low event match quality despite sending parameters

Cause: Incorrect hashing format (not lowercase, wrong encoding). Fix: Verify hashing: email must be lowercase before SHA-256. Phone must be digits only in E.164 format.

Error: Duplicate conversions in reporting

Cause: Deduplication not configured — both pixel and CAPI counting same event. Fix: Implement event_id on both pixel and CAPI calls. Confirm matching IDs using Test Events tool.


How Adship Simplifies CAPI Setup

Adship's tracking integration handles CAPI configuration without custom development:

  • No-code CAPI setup — Connect your store in the Tracking page and Adship handles the server-side event pipeline automatically
  • Automatic hashing — All PII is SHA-256 hashed before transmission; you never expose raw customer data
  • Deduplication built-in — Event IDs are generated server-side and passed to both pixel and CAPI automatically
  • EMQ optimization — All available match parameters collected and sent to maximize attribution quality
  • Real-time monitoring — Event Match Quality scores and event volume visible in your Adship dashboard
  • Multi-platform support — Same tracking infrastructure for Meta CAPI, TikTok Events API, and Google enhanced conversions

For advertisers without dedicated engineering resources, Adship eliminates the implementation complexity while delivering the same accuracy as a custom CAPI integration.


Next Steps After CAPI Setup

Once your implementation is live and validated:

  1. Monitor for 48–72 hours — Watch event volumes and EMQ scores in Events Manager
  2. Compare pixel vs CAPI volumes — CAPI should capture significantly more events than pixel alone
  3. Update campaign optimization — If using value-based bidding, expect ROAS reporting to improve as more conversions are attributed
  4. Expand to other events — Add CAPI for Lead, ViewContent, AddToCart after Purchase is working
  5. Review attribution windows — With accurate server data, you may be able to use shorter attribution windows confidently

Meet the AI Ad Operating System

Scan, spy, create, and launch Meta and TikTok ads with guarded actions taken with your approval.

Start Free
Share this article

Research. Create. Launch. Learn.

Adship connects Agent, Ad Spy, Canvas, and Learning Loop across Meta and TikTok, with bulk launch and guarded actions built in.

Get Started: It's Free