Loading tutorials…
Loading tutorials…
The browser pixel alone loses 20-30% of conversions on iOS. CAPI sends events from your server to Meta, recovering most of it. Three install paths: Shopify-native, server-side GTM, and direct API. We cover all three.
Who this is forAnyone running Meta Ads with iOS-heavy traffic (US e-commerce, US lead-gen) who needs to recover post-iOS-14 attribution. Especially important if you've noticed reported conversions diverging from your actual order count over the last 12-18 months.
What you'll need
Step 1
Every CAPI install requires an Access Token tied to your pixel. Generate it once and treat it like a password.
In Events Manager → select your pixel → Settings tab → scroll to "Conversions API."
Click "Generate access token." A long string appears (looks like EAAxxx...).
Copy and save it securely (1Password, etc.). This token gives anyone full event-posting rights to your pixel.
If you ever suspect the token leaked, revoke it from the same screen and generate a new one. You'll need to update wherever it's used.
For audit trails, name the token (Settings → Token Manager → rename). Examples: "Stape sGTM Production," "Shopify Channel App."
Step 2
If you run Shopify with the Facebook & Instagram by Meta channel app, CAPI is already configured. You only need to verify Maximum data sharing is selected.
Shopify admin → Settings → Apps → Facebook & Instagram by Meta → Settings.
Scroll to "Customer Information Sharing." Confirm it is set to "Maximum."
If it shows "Standard" or "Enhanced," click to change → select "Maximum" → confirm.
Maximum enables CAPI for all standard Shopify events: PageView, ViewContent, AddToCart, InitiateCheckout, Purchase. Lower tiers disable CAPI events for some of these.
Go to Events Manager → Overview. Each event row should show a 'Server' badge alongside 'Browser.' If you only see Browser, the channel app setting did not propagate — uninstall and reinstall the channel app.
Step 3
sGTM gives you full control over CAPI — custom events, custom parameters, event modification. Stape hosts the container so you don't manage infrastructure.
Sign up at stape.io. Free tier covers ~10k requests/month; paid plans scale linearly.
Create a new container. Stape provides a custom subdomain like data.example.com.
In Google Tag Manager → Admin → Server Container → set the URL to your Stape subdomain.
Add a "Conversions API" tag (from the template gallery, Meta-published).
Configure it: Pixel ID, Access Token (from Step 1), Event Name (use a variable that maps from the client-side event name).
Trigger: "Custom" → match on incoming client events (e.g., trigger when the incoming hit has event_name=purchase).
Make sure to pass eventID, currency, value, user data (hashed email/phone/name). These are all standard variables in the sGTM Meta template.
Publish the sGTM container. Then on your site/client-side GTM, configure your existing Meta browser pixel events to ALSO send to Stape (Conversions API → Endpoint = your Stape subdomain).
Step 4
If you can't run sGTM and aren't on Shopify, post events directly to Meta's CAPI endpoint from your backend.
Endpoint: POST https://graph.facebook.com/v18.0/{PIXEL_ID}/events?access_token={TOKEN}
Payload: { "data": [{ "event_name": "Purchase", "event_time": unix_timestamp, "event_id": "evt_xyz", "user_data": { "em": [hashed_email], "ph": [hashed_phone], ... }, "custom_data": { "value": 99.99, "currency": "USD", "content_ids": [...], "content_type": "product" }, "action_source": "website", "event_source_url": "https://example.com/order/123" }] }
All user_data fields (em, ph, fn, ln, ct, st, zp, country) must be SHA256-hashed and lowercased before posting. Meta cannot use unhashed PII.
eventID MUST match the eventID passed in the browser pixel for the same event. Otherwise dedupe fails.
Test with the Test Event Code parameter first (Events Manager → Test Events → generate code). Send events with "test_event_code": "TEST123" in the payload. Events appear in Test Events tab without affecting production data.
Once verified, remove test_event_code from production posts.
Step 5
Every browser event and its matching server event MUST share an eventID. Without it, Meta counts the same conversion twice.
In Events Manager → Settings → 'Event deduplication.' Status should read 'Set up.'
If it reads 'Not set up' or shows yellow warnings: at least some of your events lack matching eventIDs.
Generate eventID on the client (e.g., 'evt_' + Date.now() + '_' + random()). Pass it to the browser fbq() call as eventID. Push it to the dataLayer for server-side use. Pass it in the CAPI POST as event_id.
For Shopify channel app: dedupe is handled automatically using Shopify customer event IDs. Verify in Events Manager → the badge should appear next to events.
For Stape: in your Meta CAPI tag, the eventID field must reference {{Event Data - eventID}} (the incoming hit's eventID). Stape auto-forwards it from the client-side event.
Wait 24 hours after configuration. Check Diagnostics for any 'Duplicate event ID' or 'Missing event ID' warnings. Resolve all of them before trusting reports.
Step 6
CAPI's biggest win is sending hashed email/phone/name with server events. This lifts Event Match Quality and recovers iOS attribution.
For every CAPI event, include user_data with as many fields as available: em (email), ph (phone), fn (first name), ln (last name), ct (city), st (state), zp (zip), country, external_id (customer ID).
All fields MUST be SHA256-hashed and lowercased. Most CAPI integrations (Stape, Shopify channel app) handle hashing automatically — but verify in Test Events that user_data is being sent and that the hash format is correct.
Aim for Event Match Quality (Events Manager → Diagnostics → EMQ score) of 8+/10 on Purchase events. Below 6/10 means you are leaving significant attribution unrecovered.
Best practice: collect email at the earliest funnel step possible (newsletter signup, account creation) so it's available for ALL downstream events, not just Purchase.
Step 7
Use Events Manager Test Events to verify a complete event flow: browser fires → server fires → eventID matches → user_data populated → dedupe successful.
Events Manager → Test Events → "Test Events Tool." Generate a Test Event Code if posting directly via API, or use your browser test ID if firing via Stape/channel app.
Open your site in incognito. Trigger the event you want to test (purchase, add to cart). Within 60 seconds, the event should appear in Test Events with TWO rows: one Browser, one Server.
Click the event to expand. Verify: eventID matches between Browser and Server rows. Status reads "Deduplicated."
In the Server event, expand user_data. You should see at least em (hashed email) and ph (hashed phone). Empty user_data = Advanced Matching is broken.
After validation, monitor Diagnostics tab for 7 days. Address every warning (low EMQ, missing parameters, event delays).
Common mistakes
Misconfigured eventID dedupe
What goes wrong: Browser pixel and CAPI both fire for the same purchase but with different eventIDs (or one missing). Meta counts the same purchase twice. Reported ROAS reads 2x reality. Advantage+ scales the wrong creatives for 30-60 days. Typical attributed waste: 30-50% of budget.
How to avoid: Generate one eventID per event firing. Pass it to BOTH fbq() and the CAPI POST. Verify in Events Manager → Settings → Event deduplication that status reads "Set up."
Not hashing user_data fields
What goes wrong: You POST email/phone as plain text. Meta rejects the user_data fields silently (you don't see an error). Server events fire but with empty user matching. EMQ drops to 2-3/10. iOS attribution recovery drops to near zero. CAPI investment is effectively wasted.
How to avoid: SHA256-hash all PII fields before sending. Lowercase first. Most CAPI integrations (Stape, channel apps) handle this automatically — but verify in Test Events that the user_data shows hashed strings, not plain text.
Leaving Test Event Code in production
What goes wrong: All your CAPI events route to Test Events tab and never count toward production reporting or optimization. Advantage+ sees no Purchase events and de-prioritizes the campaign. CPL/CPA can climb 50-100% within 14 days.
How to avoid: Remove 'test_event_code' from your CAPI POST payload before going live. Test thoroughly using the Test Events tool, then strip the test code for production.
Sending events from a non-verified domain
What goes wrong: If your CAPI events come from a domain not verified in Business Manager → Brand Safety → Domains, Meta deprioritizes signal from those events. You think CAPI is working but campaign performance still degrades.
How to avoid: Business Manager → Brand Safety → Domains → verify your domain via meta-tag, DNS, or HTML file. Required before AEM (next tutorial) and required for full CAPI value.
Stape free tier overflow without alerting
What goes wrong: Free tier covers ~10K requests/month. Once you exceed, requests are throttled or dropped silently. Reported conversions decline 30-50% over the month. You blame iOS, not Stape.
How to avoid: Set up usage alerts in Stape dashboard. Upgrade to a paid tier ($20-50/mo) when monthly events exceed 8K. The cost is trivial vs the data loss.
Posting events with wrong event_time
What goes wrong: event_time should be a Unix timestamp at the moment the event occurred. If you post events with the time of the API call (which can be hours later for batched events), Meta treats them as delayed and weights them lower in optimization.
How to avoid: Always set event_time to when the event happened (e.g., for a purchase, when the order was placed — not when your batch job ran). Use Date.now() / 1000 at the moment of the event, store it, and include it in the eventual CAPI POST.
Recap
Done — what's next
How to install the Meta Pixel on Shopify the right way
Read the next tutorial
Hand it off
CAPI is the highest-leverage Meta install in 2026 — and the one most likely to be misconfigured silently. A Meta Ads specialist on EverestX can stand up CAPI on Shopify, WordPress, custom stacks, or sGTM, audit dedupe, and validate EMQ — typically in 3-4 hours. Setup: $80-160. Ongoing monitoring: $200-400/mo.
See specialist rates
Almost always missing or mismatched eventID. The browser fbq() call and the CAPI POST for the same event must share an identical eventID string. Generate it once on the client, pass it to BOTH. Check Events Manager → Settings → Event deduplication for the current status.
Yes. CAPI alone misses browser-only signals like ViewContent on landing pages (especially for users who bounce without converting). The recommended setup is both, with eventID dedupe. Meta also weighs the combination higher than either alone for Advantage+ optimization.
CAPI Gateway = Meta-hosted lightweight relay (limited customization, free, easy). sGTM = Google-hosted server container you control (most flexible, ~$20-50/mo via Stape). Direct API = your own backend posts events to Meta (full control, requires developer time). Most accounts use sGTM in 2026 because it consolidates Meta + GA4 + LinkedIn + TikTok in one server-side layer.
Event Match Quality starts improving within 24 hours of correctly-configured CAPI. Reported conversions typically lift 10-30% within 7-14 days. Advantage+ takes 14-30 days to re-learn with the better signal — campaign performance lift usually visible by week 4.
You can run CAPI without user_data, but Event Match Quality will be near zero and you lose most of the value. The point of CAPI is matching server events to user profiles via hashed PII. If you're concerned about privacy, the answer is to ensure proper consent (Consent Mode v2) and hash PII before sending — not to strip user_data.
Yes — and it actively improves Lookalikes. Lookalikes are built from your existing pixel events (e.g., 'people who Purchased in the last 180 days'). CAPI recovers events the browser pixel missed, so source audiences are larger and more representative. Better source = better Lookalike.
Meta Ads
Shopify deprecated the old pixel-in-theme.liquid path. The modern install runs through the Facebook & Instagram by Meta channel app and pulls in CAPI for free. Here's how to do it without double-counting purchases.
Meta Ads
GTM is the right tool for a multi-platform tracking stack. One container, one consent layer, every pixel — Meta, GA4, LinkedIn, TikTok — coexisting cleanly. This walks through the Meta Pixel install inside GTM specifically.
Meta Ads
Meta's response to iOS 14.5 — Aggregated Event Measurement — caps you at 8 prioritized events per domain and forces you to rank them. Get the order wrong and your most important conversion (Purchase) silently drops out of iOS reporting.
Meta Ads
Your pixel was working last month. Now Events Manager shows zero. Or it shows events but not the ones you need. This is the diagnostic sequence specialists run.