What does the Conversions API actually do?
The Conversions API (CAPI) sends conversion events from your server straight to Meta, so a purchase or lead still gets counted when the browser Pixel fails to fire. Meta’s best practices page is explicit that it should run alongside the Pixel, not replace it: send the same events through both, and let Meta deduplicate.
This matters more than it sounds. Meta’s delivery system optimizes toward the events you send. Meta’s documentation says only matched events (ones tied to a Meta account) are used for attribution and ad delivery optimization. A setup that sends lots of server events with thin customer data adds volume to your reports without improving the signal the algorithm learns from.
Which setup route should you choose?
Choose by who will maintain it. All three routes can work. What separates them is how much control you have over what gets sent.
| Route | Who hosts it | What you control | Watch for |
|---|---|---|---|
| Commerce platform or tag manager integration | The platform | Little: you get whatever fields it sends | Confirm it passes event_id, email, phone, fbp and fbc, not just the event |
| Conversions API Gateway | A server in your own cloud account (AWS or Google Cloud) | Pixels and domains connected, via an admin UI | Hosting cost and keeping the instance updated; it mirrors web events, not your CRM |
| Direct integration (Meta Business SDK or raw API calls) | Your backend | Everything: which events, which fields, when | Engineering time; you own hashing, retries and monitoring |
Two practical notes. The Gateway is built for web events and mirrors what the Pixel sees, so it won’t send a subscription renewal or a closed deal from your CRM. If your real conversion happens after the click (a qualified lead, a trial that converts to paid), you need a direct integration, or a CRM integration that can post to the API. And Meta does not charge for the Gateway itself; you pay the cloud provider.
How does deduplication work?
Meta treats a browser event and a server event as the same action when both the event ID and the event name match. Per Meta’s deduplication guide, the Pixel’s eventID must equal the server’s event_id, and the Pixel’s event must equal the server’s event_name. When both reach the same Pixel ID within 48 hours, Meta keeps one.
The sequence that works:
- Generate one unique ID when the action happens (for a purchase, the order ID is a natural choice).
- Pass it to the Pixel call:
fbq('track', 'Purchase', {...}, {eventID: 'ORDER_ID'}). - Send the same value as
event_idin the server event, withevent_nameset to exactlyPurchase. - Check in Events Manager that the event shows both browser and server sources and is being deduplicated.
Meta also documents a fallback that matches on fbp and/or external_id plus the event name. It is designed for the browser event arriving first. Meta notes that a server event is not discarded if no browser event arrived in the previous 48 hours, even if one shows up later. Use event_id whenever you can.
What should every server event contain?
Send the required fields plus as much customer information as you lawfully hold. Meta’s server event parameters and customer information parameters set the rules:
| Field | Send as | Notes |
|---|---|---|
event_name, event_time, event_id |
Plain | event_time can be at most 7 days in the past, or the whole request errors |
action_source |
Plain | Required; website for site events |
event_source_url |
Plain | Required for website events |
client_user_agent |
Plain | Required for website events |
client_ip_address |
Plain, never hashed | IPv4 or IPv6 |
fbp, fbc |
Plain, never hashed | Read from the _fbp and _fbc first-party cookies |
em (email), ph (phone) |
SHA-256 after normalizing | Email trimmed and lowercased; phone digits only, with country code |
fn, ln, ct, st, zp, country |
SHA-256 after normalizing | Country as a lowercase two-letter ISO code |
external_id |
Hashing recommended | Your stable customer ID |
Normalization is where most custom builds go wrong. A phone number hashed as “(650) 555-1212” will never match the same number hashed as “16505551212”. Meta’s Business SDK hashes for you; anything hand-rolled needs its normalization tested against Meta’s rules.
Two optional fields worth knowing. opt_out: true tells Meta to use the event for attribution only, not delivery optimization. data_processing_options with LDU flags Limited Data Use, which then requires a country (and in some cases a state) to be set.
How do you raise Event Match Quality?
Send more of the identifiers Meta can match on, on more of your events. Event Match Quality (EMQ) is a score out of 10 shown per event in Events Manager. Per Meta’s best practices, it estimates how effective your server event’s customer information is for matching, and as of October 2026 it is available only for web events.
What moves it, in rough order of effort:
- Pass
fbcandfbpfrom the browser to your server at checkout or form submit. They are first-party cookies, and Meta notes the values change, so read them fresh rather than storing them once. - Send hashed email and phone on every event where you have them, not only on Purchase. Lead and InitiateCheckout often have an email too.
- Send client IP and user agent on every server event. The browser adds them to Pixel events automatically; on the server you have to forward them yourself.
- Send events promptly. Meta asks for real time or batches close to it.
For accounts with many datasets, the Dataset Quality API returns EMQ, event coverage (the share of Pixel events the API also covers with deduplication keys), dedupe key feedback, data freshness and Meta’s estimate of additional conversions reported. It is worth wiring into a weekly check.
What order should you do this in?
Fix definitions before volume. The order we use:
- Decide which events matter. Usually Purchase or Lead plus one or two upstream events. Map each to a business outcome. If a “Lead” includes spam, fix the form first (see landing pages for paid traffic).
- Confirm consent handling with whoever owns privacy. Meta reminds advertisers to have lawful permission before sharing customer data.
- Implement event_id on the Pixel and the server together. Shipping one side first creates a window of double counting.
- Validate in the Test Events tool with your own real details. Meta notes unmatched test events may be discarded.
- Check deduplication and EMQ per event after a few days of live traffic.
- Only then change optimization or scale budget.
What are the common traps?
- Mismatched event names.
purchaseon the server andPurchaseon the Pixel are two different events. - A new event_id on every page load. If the thank-you page generates a fresh ID on refresh, the server and browser never pair.
- Hashing IP or user agent. These must be sent in plain text.
- Batching once a day. Anything older than seven days is rejected, and delays hurt matching.
- Sending a server-only event Meta can’t match. Some combinations, such as first name plus gender alone, are too broad to be valid.
If CAPI is in place and you still don’t trust the numbers, the next question is incrementality, not more tracking. See incrementality testing.
How MSG approaches this
We treat tracking as part of the build, not an afterthought. Before scaling any Meta account, we write down which events count as conversions and why, implement the Pixel and Conversions API together with shared event IDs, and check deduplication and Event Match Quality per event. Where the real sale happens later, in a CRM or a subscription system, we plan for those events too. The work happens inside your own ad accounts and datasets, so the setup stays yours. See Meta Ads management and measurement.
Sources
- Meta for Developers: Conversions API best practices
- Meta for Developers: Handling duplicate Pixel and Conversions API events
- Meta for Developers: Customer information parameters
- Meta for Developers: Server event parameters
- Meta for Developers: Conversions API Gateway
- Meta for Developers: Dataset Quality API
Platform features and policies change. This guide reflects the sources above as of October 7, 2026.