Sending offline conversions to Facebook through the API is how you tell Meta what happened after the click: the phone sale, the CRM deal, the in-store purchase the pixel never saw.

Without it, Meta only knows about the online steps, so it optimizes toward cheap leads instead of the ones that turn into revenue.

The old way and the new way

Offline event sets were the original route, uploaded as spreadsheets. Today those flow into the Conversions API, so offline conversions go through the same CAPI as your web events, just with a different action_source.

You set action_source to something like physical_store, phone_call, or system_generated, and Meta treats it as an offline conversion rather than a web one.

Setup, step by step

  1. Export the conversions you want from your CRM or POS, each with a timestamp, a value, and whatever identifiers you hold.
  2. Hash the identifiers, email, phone, name, with SHA-256 after normalizing them.
  3. Send each event via CAPI with the right action_source, the real event_time, and the value.
  4. Batch them on a schedule, since offline data usually arrives daily, not in real time.

Matching is what makes it work

Offline events have no cookies, so matching leans entirely on the identifiers you send. The more you provide, the higher the match rate:

  • Hashed email and phone, the strongest signals.
  • First and last name, and location where you have it.
  • Any external_id you already use to tie the customer to an online event.

Mind the attribution window

A deal that closes weeks after the click falls outside Meta's attribution windows, so Meta attributes what it can and no more. Treat offline CAPI as optimization signal and value upload, not as a clean claim on every sale.

Where it breaks

  • The wrong action_source, so Meta files a phone sale as a web conversion.
  • Unhashed identifiers, which Meta rejects, so matching collapses.
  • No event_time, so Meta can't place the event in a window.
  • Test data sent into the live dataset, quietly polluting your real numbers.

Deduplicate against online events

Offline and online can describe the same person, and sometimes the same sale. If a customer buys online and you also upload the order from your POS, you can double count, so decide which system owns which conversion.

Where an offline event maps to an online one, reuse the same event_id and let Meta dedupe, exactly as you do between pixel and CAPI.

Cadence and freshness

Offline data is usually a daily export, so build a scheduled job rather than a one-off upload. The fresher the data, the better it lands inside attribution windows, and the less manual work you carry each week.

Automate the export from your CRM or warehouse, hash on the way out, and send on a schedule. A pipeline you don't have to babysit is one you'll actually keep running.

What good looks like

A healthy offline setup shows a reasonable match rate on the uploaded events, values that tie out to your CRM, and no suspicious doubling against online purchases. Check the match rate first, because offline matching lives or dies on the identifiers you send.

If the match rate is poor, add identifiers before you blame the platform. Email plus phone plus name will almost always beat email alone. And a scheduled export that always includes those fields beats a hand-built one that quietly forgets half of them on a busy week.

Offline conversions through the API close the loop the pixel can't: they tell Meta what actually became revenue. Send them with real identifiers and the right action_source, and optimization shifts from cheap leads to closed deals.

Want a stronger data analyst role or a raise? Grab the FREE Product Analyst Playbook and get the exact roadmap to your next offer.