River
Y CombinatorBacked by Y Combinator

Marketing & GrowthFree

Offline Conversion and CRM Match Review

Every unmatched closed-won deal classified by cause, so a revenue-per-channel number arrives with the share of revenue it was built on.

Start here

Every offline-conversion guide ends at the upload. None of them tell you what share of your closed revenue actually arrived. On Marchmont Fleet Services' twelve months, 447 of 1,106 paid closed-won deals reconciled to a click. That is a 40.4% match, and the revenue-per-channel table built on it was wrong about which channel came second. The match rate is not a footnote on that table. It is the table's confidence interval, and it differs by channel.

This review joins the CRM export to the click data, then classifies every record that fails to match into one of seven causes. Some are hygiene: an email that was never trimmed and lowercased before hashing, a click identifier the form never captured, an identifier overwritten by a later organic session. Some are not. A deal that closed 140 days after the click cannot be uploaded against that click at all, and no amount of tagging work changes it.

Written for demand-gen leads who have been asked to defend a channel split, RevOps teams inheriting a half-built import, and agencies whose ROAS number rests on a match nobody measured. Pair it with the Google Ads account audit where the structure is the problem, and the funnel and landing-page review where the leak happens before the CRM ever sees a record. The creative read by attribute is the next question once the channel split holds up.

What a 40% match does to a channel ranking

Two of the four channels swapped places once the match rate was carried alongside. The platform-side table ranked Google Search first, LinkedIn second, Meta third. LinkedIn's matched revenue was 2.4 times Meta's. The CRM disagreed: Meta's paid closed-won revenue was $2,684,000 against LinkedIn's $2,081,000, so Meta came second and LinkedIn third. Nothing about performance produced that reversal. Meta's records matched at 18.4% and LinkedIn's at 58.9%, and the ranking was reading match quality as revenue.

So every channel gets a range instead of a number: matched revenue at the bottom, matched revenue divided by match rate at the top. Search's range is 1.79 times wide. Meta's is 5.43 times wide on 74 matched records. Because the CRM already holds the answer, the gross-up is checkable, so it gets checked. Three channels landed within 2%. Demand Gen was out by 107%, on 23 matched records, which is what a 3.70 times wide range was warning about.

One cause cannot be fixed by tagging work. Google requires a click-to-conversion cycle under 14 or 90 days depending on the data source, and 94.2% of these deals closed more than 14 days after the click. A file-drop import reaches 82.1% of them; a CRM connector on the 14-day rule reaches 5.8%. The formatting causes are cheaper. Meta requires contact information trimmed, lowercased and hashed, and 145 deals worth $876,300 failed on that alone. Google puts the lift from adding first-party keys at a median 10%.

How it works

  1. Send both exports

    The closed-won rows with their identifiers, and whatever click data the platforms will give you.

  2. Join and count

    Records are matched on every available key, and the match rate comes out per channel.

  3. Classify the misses

    Each unmatched record gets a cause, and the revenue behind every cause gets totalled.

  4. Report the range

    Each channel arrives as a bounded range with its match rate and record count attached.

What you get

  • The match rate reported first, per channel, before any revenue-per-channel number is printed.
  • Every unmatched record classified into one of seven causes, with the revenue behind each.
  • A range per channel rather than a point estimate, and the width stated plainly.
  • The gross-up checked against the revenue your CRM already holds, so the error is known.
  • Causes split into what capture work fixes, what normalisation fixes, and what neither does.
  • A Sheet of match rate by channel, plus a Doc of the capture fixes.

Common questions

Isn't a 40% match just how offline conversion tracking works?

Partly, and that is the argument for reporting it. Of the 659 unmatched deals here, 243 worth $1,665,700 failed on capture and 145 worth $876,300 on email formatting, which is 54.4% of the gap and all of it fixable. The remaining 241 are not. Knowing which is which is the point.

Why report a range instead of a best estimate?

Because the width tells you whether the number can carry a decision. Search's range is 1.79 times wide and Meta's is 5.43 times, and the difference is match rate alone, not performance. A single number hides that entirely. Reporting both ends forces the conversation about coverage before the budget conversation.

Can't you just divide matched revenue by the match rate?

You can, and it worked on three of four channels here, inside 2% of what the CRM held. On Demand Gen it overstated revenue by 107%, because 23 matched records happened to skew large. The division assumes unmatched deals resemble matched ones, and matched deals on this account ran 16.1% bigger.

My sales cycle is 61 days. Is an offline import even worth it?

For closed-won, barely. 94.2% of these deals closed more than 14 days after the click, so a connector on that rule sees 5.8% of them. The answer is to upload a mid-funnel event instead. There were 3,142 qualified opportunities at a 9-day median, worth $2,656 each at the account's close rate.

What if the CRM's own lead source is wrong?

It usually is somewhere, and the join catches some of it. Thirty deals worth $75,000 here were outbound work the CRM tagged paid on a last-touch rule, so they came out of the paid total rather than into it. A record that matches no click and has no capture failure is worth reading as a mis-tag.

Does this work outside Google and Meta?

Yes. The join needs a closed-won export with dates and identifiers, plus click data from wherever you buy. Most large platforms expose a click parameter on the landing URL and some route for uploading conversions after the fact. The cause list is the same everywhere, because so are the failure modes: capture, formatting and window.

What actually gets delivered?

A Sheet with match rate by channel, the matched and unmatched revenue side by side, and every unmatched record carrying its cause. Then a Doc with the capture fixes in revenue order, the range for each channel, and what the numbers cannot support. Query-level waste stays in the search term review.

Offline Conversion and CRM Match Review

Fill in the form and your workspace opens with the work already underway.