Attribution

Meta Conversions API explained: setup, matching and deduplication

What the Meta Conversions API sends, which fields Meta needs, how deduplication with the pixel works, and the mistakes that double count or lose purchases.

On this page

The Meta Conversions API (often shortened to CAPI) lets your server tell Meta that a conversion happened: a purchase, a lead, a signup. The Meta pixel reports the same things from the browser. Running both, correctly joined, gives Meta a fuller count than the pixel alone, because a server is not stopped by ad blockers, closed tabs or checkout pages that never load the pixel.

This guide covers what an event contains, how Meta matches it to a person, and how to avoid the two classic mistakes: counting every purchase twice, or sending events Meta cannot use.

What a server event contains

Each event is a small JSON object sent to Meta's Graph API. The required fields are event_name, event_time, user_data and action_source, and event_source_url is required for website events (Meta).

JSON
{
  "event_name": "Purchase",
  "event_time": 1761200000,
  "event_id": "order-1042",
  "action_source": "website",
  "event_source_url": "https://yourshop.com/checkout/thank-you",
  "user_data": {
    "em": ["<sha256 of the lowercased email>"],
    "ph": ["<sha256 of the phone with country code>"],
    "client_ip_address": "203.0.113.7",
    "client_user_agent": "Mozilla/5.0 ...",
    "fbc": "fb.1.1761190000000.IwAR...",
    "fbp": "fb.1.1761100000000.123456789"
  },
  "custom_data": { "currency": "USD", "value": 120.0 }
}

A few rules that trip people up:

  • event_time is in seconds, GMT, and can be at most 7 days in the past. One older event makes Meta reject the whole request (Meta).
  • action_source says where the conversion happened: website, app, phone_call, physical_store, system_generated and others. Use website for a web checkout.
  • event_id is what lets Meta merge this event with the pixel's copy. More on that below.

How Meta matches an event to a person

Meta can only use an event it can tie to an account. The user_data fields are the keys (Meta):

FieldWhat it isHash it?
emEmail, trimmed and lowercasedYes, SHA-256
phPhone, digits only, with country codeYes, SHA-256
fn, ln, ct, st, zp, countryName and address partsYes, SHA-256
external_idYour own customer idRecommended
client_ip_addressThe buyer's IP addressNever
client_user_agentThe buyer's browser stringNever
fbcThe click id, as fb.1.<ms>.<fbclid>Never
fbpThe pixel's browser id, from the _fbp cookieNever

fbc is the strongest key for ad clicks: it names the exact click. If the _fbc cookie is missing, you can build it from the fbclid in the landing page address, as long as you kept it (Meta). That is why the landing page's click id should be saved with the order.

Events Manager rates each event type with an Event Match Quality score from 0 to 10. It shows which keys your events carry and which are missing, so it is the first place to look when matching seems low.

Deduplication: one purchase, counted once

If the pixel sends "Purchase" from the browser and your server sends "Purchase" for the same order, Meta needs to know they are one purchase. It merges them when:

  • the browser's eventID equals the server's event_id, and
  • the browser's event name equals the server's event_name,
  • and both arrive within 48 hours of the first one (Meta).
Pixel: PurchaseeventID 1042, from the browser
Server: Purchaseevent_id 1042, from your server
Meta keeps oneSame name and id within 48 hours
Deduplication: the browser and the server both report order 1042. Because the event name and id match, Meta counts one purchase.

The order id is the natural event id: the browser knows it on the thank-you page, the server knows it when the order is paid. Use the same string in both, such as order-1042, not 1042 in one place and #1042 in the other.

Meta also documents a second method, matching on fbp or external_id, but it only works for a browser event followed by a server event and does not remove duplicates within one source. Use event ids.

Mistakes that cost you purchases or double them

  1. No event id, or different ids. Every purchase counts twice. Ads Manager looks great until someone compares it with the store.
  2. Different event names. Purchase from the pixel and purchase or Order from the server are different events, so nothing is merged.
  3. Unhashed email or phone. Meta asks for SHA-256 after normalizing. A plain email is a privacy problem and may not match.
  4. Hashed IP address or user agent. These must be sent as they are. A hashed IP matches nothing.
  5. Events older than 7 days in a batch. The whole request fails, including the good events in it.
  6. Server events with no browser keys at all. An event with only a hashed email can match when that email is on the buyer's Meta account. Adding fbc, fbp, IP address and user agent gives Meta more ways to match it.
  7. Ignoring consent. Where the law requires consent for ad tracking, a server event for a buyer who declined is still ad tracking. Respect the same choice server-side.

Testing before you trust it

  1. In Events Manager, open your dataset, then Test events, and copy the test code.
  2. Send one server event with test_event_code set to that code.
  3. Confirm it appears as received from the server, and that the browser and server events show as deduplicated.
  4. Remove the test code before going live. Test events do not count as real conversions.

Common questions

Do I still need the Meta pixel if I use the Conversions API?

Meta recommends running both. The pixel sees browsing, such as ViewContent and AddToCart, and sets the _fbp and _fbc cookies that improve matching. The server catches purchases the pixel missed.

Is the Conversions API GDPR compliant?

The API is a transport. Whether a given event is lawful depends on your consent and legal basis. Many EU and UK sites need consent before sending ad conversion events with personal data, in either direction.

Why does Events Manager say my events are not deduplicated?

The event name or event id differs between browser and server, or one of them is missing. Compare a single order's events side by side in Test events.

What is a good Event Match Quality score?

Meta does not publish a single target. Higher is better. Sending hashed email and phone, fbc, fbp, IP address and user agent for every event is the practical maximum for most sites.

Sources

Spotted something wrong or out of date? Email hello@sporetag.com and we will fix it.