The Ad Tracking and Attribution Book / Connect / Meta (Facebook) Conversions API

Meta (Facebook) Conversions API

Meta (formerly known as Facebook) had what can only be described as an existential crisis around 2016-2021. It wasn’t just Apple’s iOS 14.5 that caused the panic — though that certainly didn’t help. The real existential threat was the gradual, inexorable deprecation of third-party cookies across browsers.

You see, the Meta Pixel had always relied on being able to set and read cookies from Facebook’s domain—third-party cookies from your website’s perspective. As Safari and Firefox began restricting these, the Pixel could no longer reliably track users across sessions or attribute conversions back to ad clicks. Meta’s entire advertising empire — built on the assumption that they could track users across the internet with impunity — faced an uncomfortable reality: the technical foundation was crumbling.

The result? Meta pivoted harder and faster than a startup running out of runway, pushing their Conversions API (CAPI) from “nice-to-have technical option” to “implement this or watch your campaign performance collapse.”

Meta’s strategy is refreshingly straightforward: get conversion data directly from your server, bypass the browser entirely, and stop pretending that client-side tracking is anything but deprecated.

How Meta’s Conversions API works

The concept is elegantly simple: instead of the Meta Pixel (that JavaScript snippet you’ve had on your website since 2015) sending events to Facebook when someone purchases something, your server sends those events instead. No browser involvement. No cookies required. No ad blockers to circumvent.

When someone clicks a Facebook ad and lands on your website, Meta appends click identifiers to your URL — specifically the fbclid (Facebook Click ID) parameter. Your job is to:

  1. Capture these identifiers when the user arrives
  2. Store them alongside whatever customer information you collect (email, phone number, etc.)
  3. Send conversion events to Meta’s Conversions API from your server when something meaningful happens — a purchase, a subscription, a lead form submission
  4. Include both the click identifiers AND customer data in those events

Unlike Google Ads, which forces you to choose between click IDs and customer data, Meta wants both. The click identifiers provide deterministic attribution for direct clicks. The customer data (email, phone, etc.) allows Meta to attribute conversions even when no direct click was recorded — such as view-through conversions, where someone saw your ad but didn’t click it, then purchased later.

The two types of identifiers Meta wants

Click IDs: fbclid and fbc

The fbclid is Meta’s click tracking parameter, appearing in your URLs like this: https://yoursite.com/product?fbclid=IwAR3X8K...

The fbc cookie contains the fbclid alongside a timestamp, looking like: fb.1.1234567890.IwAR3X8K...

If you’re capturing click data properly, you’ll grab both from the URL and store them. When you send a conversion event to Meta’s API, you’ll include them in the fbc and fbp fields. (The fbp is Meta’s first-party cookie value, which you should also capture if it exists, though it’s less critical than the click identifiers.)

The practical reality: If you have these click IDs, Meta can attribute the conversion with certainty. This is the gold standard for Meta attribution.

Customer Information Parameters

Meta also wants “customer information parameters"—which is marketing speak for “personal data”:

  • Email address (hashed with SHA-256)
  • Phone number (hashed)
  • First name and last name (hashed)
  • City, state, postal code, country (hashed)
  • Date of birth and gender (if you have them, though most e-commerce sites sensibly don’t ask)

Unlike Google’s Enhanced Conversions, which you use instead of click IDs when you don’t have them (but actually have to capture click IDs with Google Tag in order for Enhanced Conversions to work properly), Meta wants you to send customer information alongside click IDs. Always. Both together.

Why? Because Meta uses this data for multiple purposes:

  1. Attribution enhancement - Matching conversions back to ad impressions when no click occurred
  2. Cross-device tracking - Connecting a mobile click to a desktop purchase
  3. Signal improvement - Helping Meta’s algorithms understand who your customers are for better targeting

Send both the click IDs and the customer data. Meta will figure out how to use them.

Where this makes a night-and-day difference

Here’s the critical insight that many people miss: the Conversions API isn’t just “Pixel, but from the server.” It fundamentally changes what you can track.

Consider conversions that happen offline—someone clicks your Facebook ad, fills out a lead form on your website, and three weeks later your sales team closes a £50,000 deal over the phone. With Pixel-only tracking, Meta has no idea that conversion ever happened. The browser session ended weeks ago. The cookies expired. The connection is lost.

But if you captured the fbclid when they submitted that lead form and stored it in your CRM alongside their email address, you can send that conversion to Meta’s Conversions API weeks or even months later with the original click ID. Meta will attribute it back to the original ad with certainty.

This is transformative for businesses with:

  • Long sales cycles
  • Phone-based sales
  • In-store purchases (if you can connect online clicks to offline transactions)
  • Any conversion that doesn’t happen immediately in the browser

Yes, you could send these offline conversions using just the customer’s email and hope Meta matches it back to an ad interaction. And sometimes that works. But the match rate is probabilistic and considerably lower (around 50% in author’s experience) than when you include the actual click ID. It’s the difference between telling Meta “this person bought something, maybe you can figure out why” and “this person bought something because of click ID XYZ from campaign ABC.”

One gives Meta certainty. The other gives them homework.

What a Conversion Event Actually Looks Like

When you send a conversion to Meta’s Conversions API, you’re posting JSON that looks roughly like this:

{
  “data”: [
    {
      “event_name”: “Purchase”,
      “event_time”: 1696254600,
      “event_source_url”: “https://yoursite.com/",
      “action_source”: “website”,
      “user_data”: {
        “em”: [“7d5d3e5e...c2d3”],
        “ph”: [“a1..z6”],
        “fn”: [“hash_of_first_name”],
        “ln”: [“hash_of_last_name”],
        “ct”: [“hash_of_city”],
        “st”: [“hash_of_state”],
        “zp”: [“hash_of_postal”],
        “country”: [“gb”],
        “fbc”: “fb.1.1696254000.IwAR3X8K...”,
        “fbp”: “fb.1.1696250000.987654321”
      },
      “custom_data”: {
        “value”: 149.99,
        “currency”: “GBP”
      }
    }
  ]
}

Let’s break down what’s happening:

  • event_name: What happened (Purchase, Lead, Subscribe, etc.)
  • event_time: When it happened (Unix timestamp)
  • action_source: Where it happened (website, email, phone_call, physical_store, etc.)
  • user_data: Both the click identifiers (fbc, fbp) AND customer information (email, phone, etc.), all hashed
  • custom_data: The conversion value and any other relevant details

Notice that customer information is sent as arrays of hashes. Why arrays? Because you can send multiple versions — for instance, if someone provides both a work and personal email, you can include both to improve matching.

How Meta uses this data for attribution

When you send a conversion event, Meta doesn’t just blindly report it in your Ads Manager. Instead, it does something more sophisticated:

  1. Checks for direct attribution - Does the fbc or fbp match a click on one of your ads within the attribution window?
  2. Checks for view-through attribution - If no click match, does the customer data (hashed email, etc.) match someone who saw your ad?
  3. Applies attribution settings - Uses your configured attribution window (7-day click, 1-day view, etc.)
  4. Reports in Ads Manager - Only conversions that can be attributed to your ads appear in campaign reporting

This is why you’ll see different numbers in different places:

  • Events Manager shows all conversion events you’ve sent, regardless of whether they’re attributable to ads
  • Ads Manager shows only conversions that Meta successfully attributed to your ad campaigns

This isn’t a bug or a tracking error — it’s by design. Events Manager is showing you the total conversion volume. Ads Manager is showing you what your ads actually drove.

The other difference is how they use Acquisition vs transaction date. Events Manager displays events by the date when they were received and the figures should match the total conversions count in your back-office platform. Ads Manager displays events by the date when the user was shown an ad, which is more useful for understanding Return on Ad Spend.

UTM parameters: the thing Meta doesn’t care about (but you should)

Here’s something that trips people up constantly: Meta doesn’t use UTM parameters for attribution. Not at all. Ever.

You might be appending ?utm_source=facebook&utm_medium=cpc&utm_campaign=summer_sale to your URLs with great care, and Meta will completely ignore them. Meta uses click IDs and customer data. UTM parameters are for your analytics, not for Meta’s attribution.

This means:

  • Your own analytics platform (Google Analytics, your CDP, internal reporting) uses UTM parameters to understand traffic sources
  • Meta’s Ads Manager uses click IDs and customer data matching to attribute conversions

Both can show different numbers because they’re using entirely different attribution methodologies. Neither is “wrong"—they’re measuring different things.

Deduplication: why you need it and why it doesn’t work as you would expect

If you’re implementing Meta’s Conversions API, you almost certainly still have the Meta Pixel installed on your website as well (for retargeting, if nothing else). This creates an obvious problem: when someone makes a purchase, both the Pixel and your server will send a Purchase event to Meta. Suddenly, one conversion looks like two.

Meta’s solution: event deduplication, using the event_id parameter.

When your Pixel fires a Purchase event, it includes an event_id—typically a hash of the transaction ID. When your server sends the same Purchase event via the Conversions API, you include the same event_id. Meta sees both events, recognizes the matching IDs, and counts it only once.

But be aware: Meta’s deduplication drops one of these events. If you’re sending more customer details in a server-side event, for example, it might be ignored in favour of Pixel event. The best solution in practice is to decide which is the better event and send each conversion only from one source. For example, use Pixel for sending PageView events, but send events like Purchase to CAPI with stored click ID and additional parameters to overcome browser tracking limitations.

The practical implementation pattern

A proper Meta Conversions API implementation typically works like this:

  1. User clicks Facebook ad → Meta appends fbclid to your URL
  2. Your website captures click data → Store fbclid, fbc, fbp, and any UTM parameters in a cookie or database
  3. User browses, perhaps abandons cart, returns later → Click data persists
  4. User makes purchase or submits lead form → Your checkout system or CRM collects email, phone, address
  5. Purchase completes or deal closes → Your server receives confirmation from payment processor, CRM, or sales team (could be weeks or months later)
  6. Your server associates the data → Matches the conversion to the stored click IDs and customer details
  7. Server sends to Meta CAPI → Posts the conversion event with both click IDs and customer data
  8. Meta attributes the conversion → Matches it back to the original ad click or impression with certainty (because you included the click ID)
  9. Ads Manager updates → The conversion appears in your campaign reporting

The critical insight: attribution is done entirely server-side, without relying on browser cookies or client-side tracking. Once you’ve captured the click ID and associated it with the customer’s email, everything else happens server-to-server. The conversion could happen three months later over the phone, and Meta will still know exactly which ad drove it.

This is precisely how customer data platforms operate when they implement server-side tracking for Facebook/Meta: they record click IDs when visitors arrive, associate them with customer emails at checkout or lead capture, store this relationship in their database, receive conversions from payment processors or CRMs server-side (potentially weeks or months later), and send attributed events to Meta’s Conversions API with the original click IDs. The browser is involved only in that initial click capture — everything else happens where ad blockers can’t touch it and where offline conversions can be properly attributed.

What you actually need to implement

To get Meta’s Conversions API working properly:

  1. Set up the Conversions API in Meta Events Manager and generate an access token
  2. Capture click identifiers (fbclid, fbc, fbp) when users arrive on your site
  3. Store these identifiers persistently (first-party cookie, database, CDP, CRM — whatever ensures they survive long enough to be matched with eventual conversions)
  4. Collect customer data (email, phone, etc.) at checkout or lead capture
  5. Associate conversions with click data in your backend when purchases/leads occur (even if it’s weeks or months later)
  6. Send conversion events from your server to Meta’s API with both click IDs and customer data (hashed)
  7. Implement deduplication if you’re still using the Meta Pixel alongside CAPI
  8. Monitor Events Manager vs. Ads Manager to ensure events are flowing and being attributed correctly

It requires more infrastructure than simply installing a pixel, certainly. But it’s also substantially more reliable, privacy-compliant, and — increasingly — the only way to give Meta’s algorithms the conversion data they need to optimize your campaigns effectively. Especially if your conversions don’t all happen immediately in the browser.

Sounds overly complicated? Try Able CDP Facebook (Meta) Server-Side Tracking that does all of it for you.

← Previous
Google Ads API
Next →
Measure