MarTechQuick
Advanced

Meta CAPI Setup

15 min read

Learn
Quick Reading
Estimated 15 mins
Prereq
Advanced
Requires advanced math/coding
Interactive
Static Playbook
Static guide & reference tables

Why browser-side pixel isn't enough anymore

The Meta Pixel fires from the user's browser. It sends conversion events when a purchase completes, a form is submitted, a page is visited.

Three things are killing it:
1. Ad blockers: estimated 30–40% of desktop users block Meta's pixel
2. iOS 14.5+ App Tracking Transparency: users must opt in to tracking; most don't
3. ITP and browser privacy changes: cookies that the pixel relies on are short-lived or blocked

The result: Meta sees fewer conversions than actually happened. Its algorithm receives degraded signal. Your campaigns optimize toward the wrong audience. ROAS appears to drop.

Meta's Conversions API (CAPI) sends the same conversion events directly from your server — bypassing the browser entirely. The pixel stays for what it can capture. CAPI fills the gaps.

How CAPI works

CAPI is an HTTP API. You send POST requests to Meta's graph API endpoint with event data, customer information (hashed), and context about what happened.

`json
POST https://graph.facebook.com/v19.0/{pixel-id}/events
Authorization: Bearer {access-token}

{
"data": [{
"event_name": "Purchase",
"event_time": 1714000000,
"event_source_url": "https://yoursite.com/checkout/complete",
"action_source": "website",
"user_data": {
"em": ["<sha256 hash of lowercase email>"],
"ph": ["<sha256 hash of phone with country code>"],
"client_ip_address": "192.168.1.1",
"client_user_agent": "Mozilla/5.0...",
"fbc": "_fbp cookie value",
"fbp": "_fbc cookie value"
},
"custom_data": {
"currency": "USD",
"value": 149.00,
"contents": [{"id": "plan_pro", "quantity": 1}]
},
"event_id": "order_9234"
}]
}

Deduplication: the most important part

If both your browser pixel and CAPI fire a Purchase event for the same transaction, Meta counts it twice. Your attributed conversions double. Your reports are wrong. Your algorithm optimizes on garbage data.

Deduplication prevents this. Meta matches events by event_id. If it receives two events with the same event_id, it keeps one and discards the other.

Implementation:
1. Generate a unique ID for each conversion event on your server (order_id works perfectly for purchases)
2. Pass that same ID to the browser pixel: fbq('track', 'Purchase', {...}, {eventID: 'order_9234'})
3. Pass the same ID to CAPI: "event_id": "order_9234"
4. Meta deduplicates automatically

Without event_id, you have no deduplication. Every event is duplicated. This is the most common CAPI implementation mistake.

Event match quality

Meta needs to match your server-sent event to a specific Meta user account to attribute it to an ad. The more customer data you send, the better the match.

Match quality is scored in Events Manager. Target: "Good" or "Great."

Customer data to send (all must be SHA-256 hashed):
- Email (em) — most important. Highest match rate.
- Phone (ph) — include country code: +1 for US
- First name (fn), last name (ln) — lowercase, no spaces
- City (ct), State (st), ZIP (zp), Country (country)
- Date of birth (db) — format: YYYYMMDD
- External ID (external_id) — your internal user ID

Hash everything before sending. Never send PII in plaintext to Meta. SHA-256 is required. Meta's API will accept it but non-hashed PII violates their terms of service and your GDPR obligations.

Testing your implementation

Meta's Test Events tool (in Events Manager → Test Events) lets you verify CAPI events in real time.

1. Get your Test Event Code from Events Manager
2. Add "test_event_code": "TEST12345" to your CAPI payload
3. Fire a test conversion
4. Watch it appear in Test Events within seconds

Verify:
- Event appears with correct name (Purchase, Lead, etc.)
- Event parameters are populated (value, currency, content_ids)
- Customer data fields show (em, ph, etc.) — not the values, just that they're present
- Deduplication works: fire browser pixel + CAPI with same event_id → only 1 event appears

Remove the test_event_code before going to production.

Implementation options

Direct API calls: write your own server-side code to call the CAPI endpoint. Full control. Requires engineering work.

Server-side GTM: Meta has a CAPI tag for server-side GTM. Easiest if you've already set up server-side GTM. Meta's client automatically reads the pixel cookie values (_fbp, _fbc) for match quality.

Meta's CAPI Gateway: a self-hosted solution that proxies events to Meta. Keeps data on your infrastructure, privacy-friendly option.

Partner integrations: Shopify, WooCommerce, and most major e-commerce platforms have native CAPI integrations. If you're on a supported platform, use the native integration rather than building from scratch.

CAPI is not a replacement for the pixel

Run both. The pixel captures browser-side signals Meta uses for attribution (fbp cookie, click IDs). CAPI fills in the events the pixel misses. The combination is what Meta calls 'redundant signals' — higher event match quality, better campaign performance. Either alone is suboptimal.

I build these systems professionally.

Whether it's a RAG pipeline, analytics migration, or AI workflow — let's talk.

Need custom AI or MarTech setup? Let's build together.