Meta offline conversions: the CRM upload path

Meta retired its standalone offline conversions tool, so CRM uploads now run through the Conversions API. Here's what your export has to send for events to match, and how to reuse the exact pipeline you already built for Google Ads instead of starting over.

Kay Vink
Kay Vink

You follow a guide to set up Meta offline conversions and the screen it names isn't there. Meta's standalone offline conversions tool is gone: offline outcomes that close away from the browser (CRM deals, phone sales, in-person purchases) now upload through the Conversions API offline events path, keyed by hashed customer identifiers and matched against ad exposure, so campaigns get credited for revenue the pixel never saw.

If you've already built the Google version of this pipeline (Offline conversion tracking: send CRM deals back to Google Ads), most of your work transfers: same CRM export, same lifecycle discipline, and only the matching key changes. That sameness is the whole point of this page.

#The migration: where offline events went

Offline events folded into the Conversions API, so stop following instructions that reference the standalone tool. Meta deprecated the legacy Offline Conversions API and its separate offline event sets in favor of Conversions API datasets: one API, one event container, browser and offline events side by side. A lot of what ranks for this query still walks the old Events Manager screens, which is why the walkthrough and your UI so often disagree. The surface moved. What that means for you:

  • New pipelines target the Conversions API with offline-appropriate parameters (below), sent to a dataset in Events Manager.
  • Old integrations built on the legacy offline endpoint needed migrating. If a connector or script from years past has gone quiet, this migration is the first suspect.
  • The concepts survived. Hashed identifiers, event time, match quality: the mental model transfers intact, and only the plumbing address changed.

What CAPI is and how it relates to the pixel is its own decision (Conversions API vs the Meta Pixel: what actually changes), and the full Meta setup task end to end is Meta conversion tracking end to end: pixel, CAPI, and events that dedup.

#What Meta needs from your CRM

Four fields decide whether an uploaded event matches, and each has a sharp edge:

FieldWhat it isThe sharp edge
Hashed identifiersSHA-256 email, phone (send several per event)Matching is probabilistic on Meta's side: more identifiers, higher match rate. Hash exactly per spec (lowercase, trimmed, then hash), because a casing slip zeroes matches silently
event_timeWhen the outcome actually happenedTimezone drift pushes events outside attribution windows; use epoch time from the CRM's close timestamp, not the export run time
Value + currencyDeal value per eventWithout it you've rebuilt count-only optimization: the same argument as Value-based bidding needs values you can trust
Action sourceWhere the conversion occurred (physical store, phone, CRM/other)Required honesty flag; misdeclaring it is a policy problem, not a shortcut

The identifiers do the work the GCLID does on the Google side: they're the matching key. Which is the whole story of the next section.

#The worked example: one CRM export, two platforms

The CRM-side work you did for Google Ads is this same pipeline, re-keyed. Same lifecycle stage defining what counts as a conversion, same close timestamp, same value column, same daily export cadence. One column swaps: where the Google upload carries the GCLID captured at click time, the Meta upload carries hashed identifiers the CRM already holds.

The reuse is the argument: conversion data is a pipeline, not a per-platform chore. Build the CRM discipline once (stage definitions, timestamps, values, cadence) and each platform is an export mapping, not a new project. This is exactly how Buron's CRM feeds treat it: your leads and revenue matched once in the warehouse, then fanned out per destination. The same closed-won deal, exported twice (illustrative row, the reuse is the point):

DestinationMatching keyEventValue
Google Adsgclid=Cj0K…qualified_lead€4,200
Metahashed email + phoneoffline Lead€4,200

Same stage, same timestamp, same value, and only the matching key changes.

#The upload paths: manual vs automated

Manual uploads are for backfills and tests; a pipeline runs on the API. Events Manager supports uploading offline event files against a dataset, which is right for a one-time backfill or for validating your export format before automating. For the standing pipeline, send events through the Conversions API (direct integration, a CRM connector, or your sGTM container's Meta tag, using Server-side tagging with sGTM: setup, costs, and when it's not worth it if that's your relay), on a daily cadence. The lag logic from the Google side applies unchanged: late uploads land against past dates and rewrite recent reports, so a manual-upload habit is an import-lag generator.

#Match quality: how to read it, what moves it

Where Google's GCLID match is deterministic (one ID, one click), Meta's identity match is graded: Events Manager shows match quality for your uploaded events, reflecting how often Meta could resolve your identifiers to an account. Three levers move it:

  1. Identifier count. Email + phone beats email alone; every additional hashed identifier is another chance to match.
  2. Recency. Upload close to the event: stale events meet expired attribution windows and match into nothing.
  3. Hashing correctness. Normalize exactly as specified before hashing: whitespace, case, phone formatting. Wrong normalization looks identical to low match rates, with no error anywhere.

#Failure modes

The Meta-flavored versions of the failures that kill every import pipeline:

  • Stale uploads. The export job quietly stops and conversions vanish with no error. Upload recency is a number someone must watch.
  • Timezone drift on event_time. Edge events fall outside windows, so totals sag mysteriously at month boundaries.
  • Consent scope. Customers who declined tracking don't belong in the upload; your CRM export needs a consent filter, not just a stage filter.
  • Event-name collisions with pixel events. If your offline Purchase can describe the same real-world sale as a pixel Purchase (phone order placed while browsing), you need the dedup discipline from Conversions API vs the Meta Pixel: what actually changes or that sale counts twice.

Then verify on a schedule, not once: upload received, match quality trending where it should, campaign-level totals in a sane band. The weekly routine is The conversion tracking QA checklist: test it like you'd test code, and if Meta's reported totals drift from your CRM's, the triage is Why Facebook Ads conversions don't match Shopify for ecom or the discrepancy playbook generally.

Step back and the Meta-specific part barely mattered. You built one CRM discipline (a clear closed-won definition, a real close timestamp, a value column, a daily cadence), and every ad platform after this is an export mapping, not a new project. That's the payoff worth protecting: the next network you add is a day of work, not a quarter.

What it isn't is set-and-forget. Offline pipelines fail quietly, with the export stopping or the match rate decaying while nothing throws an error and a slice of revenue goes uncredited. That watching is the part worth handing off. Buron matches your leads to revenue once in the warehouse and monitors upload freshness and match quality per destination, so a stalled Meta export shows up as a dated finding in your inbox instead of a gap you catch at the quarterly review. *[Connect your CRM →]

Frequently asked questions

How does offline conversion tracking work for Meta?

You export outcomes that closed away from the browser (CRM deals, phone sales) with hashed customer identifiers (email, phone), an event time, and a value, then upload them to Meta via the Conversions API. Meta matches the hashed identifiers against its accounts to find who saw or clicked your ads, and credits the campaigns.

What is the use of the Conversions API for offline events?

It's the current home for offline conversion uploads: the same server-to-server API that carries website events also accepts offline events, keyed by hashed identifiers instead of browser signals. Meta retired its standalone offline conversions tool in favor of this path, so new CRM upload pipelines should target Conversions API datasets.

What does Meta need in an offline conversion upload?

Per event: one or more hashed identifiers (email and phone are the workhorses, and more identifiers means better matching), the event name, the event_time when the outcome actually happened, a value and currency if you want value optimization, and an action source declaring where the conversion occurred.

Related