What Meta CAPI is and isn't
Meta Conversions API is the server-side path for sending web, app, offline, and CRM events to Meta. In a web commerce setup, it usually complements the Meta Pixel rather than replacing it. The Pixel observes browser behavior directly: page views, click IDs, cookie identifiers, user agent, and immediate client-side interactions. CAPI sends a parallel event from your server or tracking layer, enriched with first-party identifiers and protected from many browser-side failures.
The distinction matters because Pixel and CAPI solve different parts of the signal problem. Pixel is fast and close to the user session, but it can be weakened by consent state, browser privacy controls, ad blockers, network loss, single-page app routing, and third-party checkout jumps. CAPI is more durable and can include order data from the source of truth, but it only performs well when the event contract, identifiers, timing, and consent policy are wired carefully.
CAPI is also not magic signal boosting. It does not manufacture consent, bypass platform policy, or fix a messy event taxonomy by itself. Meta rewards clean, comparable events: same event names, stable event IDs, fresh timestamps, useful match keys, and consistent value fields. Treat CAPI as a controlled transport for first-party conversion evidence, not as a black box that inflates reported ROAS.
Prerequisites
Meta Business Manager admin access for the business that owns the Pixel.
The production Pixel ID and confirmation that it is the Pixel used by active campaigns.
Server, tag gateway, or TrackLayer access to receive browser event IDs and order events.
A verified domain in Meta Business Settings with Aggregated Event Measurement priorities reviewed.
Getting your access token
The cleanest production pattern is a dedicated System User token. It avoids personal-account dependency, gives your team a clear audit trail, and makes token rotation a planned operational task instead of an emergency when an employee leaves.
Open Business Settings
Go to Meta Business Suite, choose the business that owns the ad account, then open Business Settings. Use the business that owns the production Pixel, not an agency sandbox.
Create or choose a System User
In Users → System Users, create a user named TrackLayer CAPI with admin access. A dedicated System User keeps audit trails clean and makes rotation safer than using a personal account token.
Assign the Pixel asset
Open Data Sources → Pixels, select the production Pixel, and assign it to the System User. Grant the System User permission to manage the Pixel so the token can send events.
Generate the token
Select the System User, choose Generate New Token, pick the app connected to your business, and include the business_management and ads_management permissions. Copy the token once it appears.
Store it in TrackLayer
Paste the token and Pixel ID into TrackLayer → Destinations → Meta. TrackLayer validates the token, stores it encrypted, and shows the connected Pixel name before any live traffic is forwarded.
Required event fields
Meta's API will accept sparse events, but sparse events rarely perform well. Use the table as the production payload checklist. Required means the API or event type expects it; recommended means the event can technically send without it, but quality, deduplication, or diagnostics will suffer.
| Field | Type | Required | Purpose | Example |
|---|---|---|---|---|
| event_id | string | Recommended | Deduplicates matching browser and server events. | ord_9821_purchase |
| event_name | string | Yes | Names the conversion Meta should process. | Purchase |
| event_time | integer | Yes | Unix timestamp in seconds when the action happened. | 1776943226 |
| user_data.em | sha256 string[] | Conditional | Hashed email for deterministic matching. | 6b3a55e0261b... |
| user_data.ph | sha256 string[] | Conditional | Hashed phone number in normalized E.164 format. | b49f9168e8a8... |
| user_data.fbp | string | Recommended | Browser identifier from the _fbp cookie. | fb.1.1776942000000.1234567890 |
| user_data.fbc | string | Recommended | Click identifier from fbclid or _fbc. | fb.1.1776942100000.AbCdEf |
| user_data.client_ip_address | string | Recommended | Helps Meta validate the browser context. | 203.0.113.42 |
| user_data.client_user_agent | string | Recommended | Pairs the event with device and browser context. | Mozilla/5.0... |
| user_data.fn | sha256 string[] | Optional | Hashed first name for additional match quality. | 2bd806c97f0e... |
| user_data.ln | sha256 string[] | Optional | Hashed last name for additional match quality. | 81b637d8fcd2... |
| user_data.country | sha256 string[] | Optional | Hashed two-letter country code. | 79adb2a2fce5... |
| user_data.ct | sha256 string[] | Optional | Hashed city name, normalized to lowercase. | 96d3d641db74... |
| user_data.zp | sha256 string[] | Optional | Hashed postal code without spaces where appropriate. | 5994471abb01... |
| user_data.external_id | sha256 string[] | Recommended | Stable customer or account identifier. | cust_34982 hashed |
| custom_data.value | number | For Purchase | Conversion value used in optimization and reporting. | 129.95 |
| custom_data.currency | string | For Purchase | ISO 4217 currency for value interpretation. | EUR |
| custom_data.contents | object[] | Recommended | Line items for catalog attribution and value checks. | [{ id: "SKU-1", quantity: 2 }] |
Deduplication deep dive
Deduplication is the mechanism that lets you send the same conversion through Pixel and CAPI without counting it twice. Meta compares event_name and event_id, then uses timing and browser context to decide that two payloads represent one user action. The event_id should be created once at the moment the event is produced, passed to the Pixel call, and sent with the server event.
The fbp value adds another layer of confidence. event_id tells Meta which two events should merge; fbp helps Meta understand that the server event belongs to the same browser context as the Pixel event. For paid traffic, fbc is also important because it carries click identity from fbclid. TrackLayer captures these values from the browser request, attaches them to the server event envelope, and keeps the event_id stable through checkout completion.
const eventId = crypto.randomUUID();
fbq("track", "Purchase", {
value: 129.95,
currency: "EUR",
contents: [{ id: "SKU-481", quantity: 1 }],
}, {
eventID: eventId,
});
await fetch("/api/tracklayer/meta-capi", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
event_id: eventId,
event_name: "Purchase",
event_time: Math.floor(Date.now() / 1000),
user_data: {
em: [sha256(normalizeEmail(customer.email))],
ph: [sha256(normalizePhone(customer.phone))],
fbp: readCookie("_fbp"),
fbc: readCookie("_fbc"),
client_user_agent: navigator.userAgent,
},
custom_data: {
value: 129.95,
currency: "EUR",
contents: [{ id: "SKU-481", quantity: 1 }],
},
}),
});Avoid generating one ID in the browser and a different ID on the server. Also avoid reusing the same event_id across different purchases. A good event_id is unique per action, stable across transports, and short enough to inspect in diagnostics.
Consent Mode v2 forwarding
Consent Mode v2 is often discussed as a Google requirement, but the underlying implementation discipline applies to Meta CAPI as well: consent state must travel with the event. If your CMP says ad storage or ad personalization is denied, your server pipeline cannot ignore that just because the server can still see the order.
TrackLayer's recommended pattern is to collect CMP state at the edge of the event, store it in the event envelope, and evaluate destination rules before sending. A purchase event can still be recorded internally for analytics or fulfillment checks, while the Meta forwarding decision remains purpose-aware. This prevents the common failure where the browser tag respects consent but the server tag forwards everything.
Capture
Read consent from your CMP after initialization and whenever the user changes preferences. Persist only the minimal consent state needed to evaluate destinations.
Attach
Add consent state to each TrackLayer event envelope together with region, timestamp, source, and CMP version. Do not infer consent later from a global variable that may have changed.
Evaluate
Before Meta CAPI dispatch, apply your region policy. If advertising consent is denied, suppress or transform the event according to your legal basis and platform configuration.
Testing with Events Manager
Events Manager is the fastest way to catch broken CAPI wiring before real budget depends on it. Test a complete journey, not a single synthetic Purchase, because many CAPI issues appear only when browser identifiers are created upstream and reused later.
Open the Test Events tab
In Events Manager, choose your Pixel, open Test Events, and copy the test event code. Paste it into TrackLayer's Meta destination test field for the current environment.
Trigger a complete journey
Run PageView, ViewContent, AddToCart, InitiateCheckout, and Purchase from a real browser session. Testing only Purchase hides upstream field gaps that later weaken matching.
Compare browser and server events
Each key event should appear twice before deduplication: once from Browser and once from Server. The event_id should match, and the server event should include fbp plus client context.
Promote after a clean ten-minute window
Wait for ten minutes with no missing field warnings, token errors, or dedup warnings. Then remove the test code and watch production diagnostics for the next 48 hours.
Common test errors and fixes
Pass the same event_id from Pixel to TrackLayer and into the CAPI payload.
Check consent status, event_name casing, event_time freshness, and whether the Pixel is assigned to the token's System User.
Normalize email, phone, city, postal code, and country before hashing. Do not hash fbp, fbc, IP address, or user agent.
Send custom_data.value as a number and custom_data.currency as a three-letter ISO currency code.
Match quality optimization
Event Match Quality is a directional diagnostic, not a revenue guarantee. Still, it is useful because it tells you whether Meta receives enough identifiers to associate events with people and ad interactions. The largest gains usually come from deterministic identifiers and careful normalization, not from adding every field indiscriminately.
Hashed email
Highest-confidence deterministic identifier when captured at login, checkout, or newsletter signup.
Hashed phone
Especially useful in commerce flows where customers provide mobile numbers for shipping alerts.
external_id
Stable customer ID helps Meta recognize repeat purchasers even when browser cookies rotate.
fbp
Connects server events back to a browser session created by the Pixel.
fbc
Preserves click identity from Meta ads and is strongest when captured on landing pages.
client IP + user agent
Improves context validation, particularly for anonymous upper-funnel events.
City, postal code, country
Useful secondary identifiers when normalized consistently and hashed correctly.
Estimated lift depends on traffic mix, login rate, checkout design, geography, and consent rates. Use the percentages as a prioritization model: email and phone first, persistent customer ID second, browser and click identifiers third, then address fragments and context fields.
Troubleshooting
Most Meta CAPI problems are not platform mysteries. They are contract failures: wrong token, wrong Pixel, missing permission, stale event_time, invalid hash format, duplicate event generation, or a field that looks right in code but is malformed in the final JSON body.
Event has a deduplication conflict or missing event_id pairing.
Generate event_id once in the browser, reuse it for Pixel and CAPI, and keep it stable through checkout redirects.
Invalid parameter in the request payload.
Validate field names, event_name casing, Unix event_time, currency format, and custom_data structure.
Access token is invalid, expired, or revoked.
Regenerate the System User token, confirm permissions, and update the encrypted TrackLayer destination secret.
Permission denied for the Pixel or business asset.
Assign the Pixel to the System User and verify the token was generated under the correct Business Manager.
Rate limit exceeded.
Batch lower-priority events, retry with backoff, and avoid duplicate server sends from multiple containers.
Missing or invalid customer information parameter.
Send at least one strong user_data key and normalize values before hashing.
Event time is too old or too far in the future.
Use server-side Unix seconds from the actual event moment and keep queue delays under Meta's allowed window.
Unsupported post request or destination mismatch.
Check Graph API version, Pixel ID, token app ownership, and whether the request is sent to the correct endpoint.
FAQ
Can Meta CAPI replace the Pixel?
For most advertisers, no. Meta still needs browser events for fast optimization signals, on-page behavior, click identifiers, and deduplication context. CAPI makes the signal more durable, but the strongest setup uses both channels together.
Do I need to hash every user_data field?
Hash personally identifiable fields such as email, phone, first name, last name, city, postal code, country, and external ID. Do not hash fbp, fbc, client_ip_address, or client_user_agent because Meta expects those as raw context values.
How long until Event Match Quality improves?
Diagnostics often show field changes within hours, but stable EMQ usually needs 24 to 48 hours of production volume. Purchase can take longer if order volume is low.
Should every event include value and currency?
Purchase should always include both. AddToCart and InitiateCheckout should include them when the cart total is known. PageView and ViewContent can omit value unless you have a clear business reason.
What happens if Pixel and CAPI disagree?
Meta may keep one event, drop one event, or mark diagnostics with dedup warnings. The best fix is to make the event contract deterministic: same event_id, same event_name, similar event_time, and aligned custom_data.
Can TrackLayer forward consent changes in real time?
Yes. TrackLayer reads CMP state, maps it to destination policies, and only forwards Meta CAPI events when the required consent state is present for that region and event category.