# 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.

Source: https://datacenter.so/guides/meta-conversions-api-explained
By the Datacenter team. Updated October 23, 2026.

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](https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/server-event)).

```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](https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/server-event)).
- **`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](https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/customer-information-parameters)):

| Field | What it is | Hash it? |
|---|---|---|
| `em` | Email, trimmed and lowercased | Yes, SHA-256 |
| `ph` | Phone, digits only, with country code | Yes, SHA-256 |
| `fn`, `ln`, `ct`, `st`, `zp`, `country` | Name and address parts | Yes, SHA-256 |
| `external_id` | Your own customer id | Recommended |
| `client_ip_address` | The buyer's IP address | Never |
| `client_user_agent` | The buyer's browser string | Never |
| `fbc` | The click id, as `fb.1.<ms>.<fbclid>` | Never |
| `fbp` | The pixel's browser id, from the `_fbp` cookie | Never |

`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](https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/fbp-and-fbc)). 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](https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events)).

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

- Meta for Developers: [Server event parameters](https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/server-event), [Customer information parameters](https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/customer-information-parameters), [fbp and fbc](https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/fbp-and-fbc), [Deduplicate pixel and server events](https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events). Checked October 2026.

## Where Datacenter fits

Datacenter sends goals you mark "send to Meta" from both the browser and your server with a shared event id, builds fbc from the fbclid, hashes email and phone, and keeps a delivery log with Meta's reply for every event. More: https://datacenter.so/docs/meta-conversions-api
