“We have a full campaign influence model.”
Then you have a good answer for the touches that are in it. This adds the ones that are not, and gives you a total that reconciles to the opportunity export rather than to the model.
For Salesforce
Export closed-won opportunities and reconcile them against your ad, call and partner exports — no campaign influence model required.
CloseRev reads a Salesforce export of closed-won opportunities — the contact's email or phone, the amount and the close date — and matches it against call tracking and lead exports held outside the CRM. The result is channel revenue that does not depend on every rep having set a lead source correctly two quarters ago. Where the origin is genuinely unknown, the report says so.
Page updated September 24, 2026.
The gap
Campaign influence needs every touch to be in Salesforce as a campaign member. The touches that matter most are the ones nobody ever loaded.
What was sold, to whom, and for how much.
The click, the keyword, the call, and what each one cost.
The file
Three things carry the match: who, how much, and when. Anything else is optional and only changes how the report can be sliced.
The primary contact on the opportunity, or the associated lead's contact detail. Email is usually cleanest in a Salesforce org.
The closed-won amount, or the recognized revenue figure if your finance team uses a different one.
The opportunity's close date, used consistently between uploads.
Separates lines of business that have no business sharing a cost per deal.
Step by step
Written for somebody with Salesforce open in the next tab. Report names vary by edition, so each step says what to look for.
Include amount, close date and the contact's email or phone. A standard opportunity report with the contact fields added is enough.
If deals take six months, export eighteen months. Anything shorter and the opportunities closing now have no inquiry in the file to match to.
This is the step most orgs miss. An opportunity report with account names and no contact email cannot be matched to anything.
Mapping is suggested, you confirm it, and manual mapping is always available for unusual headers.
Ad platform exports, call tracking, partner registrations, event lists, outbound sequences — in one lead file, with the source named on each row. Each is ranked on closed-won revenue.
What comes back
Revenue by channel, the count of sales behind each figure, and an honest bucket for the ones nobody could trace. Sample figures, from the worked example on the B2B SaaS page — not from a Salesforce account.
| Channel | Share | Sales | Revenue |
|---|---|---|---|
| Google Ads | 18 | $720,000 | |
| LinkedIn Ads | 21 | $930,000 | |
| Email marketing | 12 | $420,000 | |
| Direct / Unknown | 24 | $930,000 |
Unmatched sales stay in Direct / Unknown. They are never spread across the paid channels to make the total look better.
The argument
Salesforce can attribute properly, and in a well-run org it does. The mechanism is campaign influence: every touch has to exist as a campaign member on the contact, and the model then distributes credit across them. When the data is complete the output is good.
The data is rarely complete, and the incompleteness is not random. Digital touches land automatically if the integration is configured. A conference conversation, a partner introduction, an inbound call to a regional office, a customer referral — these arrive as a person, not as a campaign member, and somebody has to remember to load them. The channels that get left out are systematically the offline ones.
So the report tells you about the channels that were easy to instrument, and is silent on the ones that were not. That silence reads as absence, and budget follows the report.
Instead of modeling how much credit each touch deserves, this asks whether the person on a closed-won opportunity appears in a given source list. It is a coarser question, and that is the point: it has a definite answer and the answer can be checked by opening two files.
High-confidence matches — an exact phone or email after normalization — count automatically. A phone that agrees only once its country code is set aside waits for a person to accept or reject rather than being counted. And opportunities that appear in no source list at all are reported as unattributed, however large that number turns out to be.
Because the whole thing runs on exports, it needs no admin project, no new object, no field on the opportunity and no change to how the sales team works.
Large Salesforce orgs usually run several businesses through one instance: new business and renewals, direct and channel, several product lines with wildly different deal sizes. A single cost per closed-won opportunity across all of them is an average nobody owns.
A record type or business unit column splits the report along the lines the company is actually managed on. It is the difference between a chart that gets shown once and a chart a business unit leader asks for monthly.
Channel-led revenue is notoriously hard to attribute, because the partner owns the relationship and the end customer may never touch your website. Deal registration gives you a record of the partner, not of the marketing that produced the end customer.
Adding partner registrations to the lead file, under the partner program's own source name, puts them on the same revenue axis as direct demand generation: what the channel program produced against what paid search produced, on a single scale.
In an organization where the marketing number is contested, the important property is not accuracy — it is auditability. A figure somebody can challenge and you can trace to two rows in two exports is worth more than a more sophisticated figure nobody can open.
Every match here is inspectable and reversible. High-confidence matches on a normalized phone or email count automatically; a phone that matches only without its country code is queued for a person to accept or reject, and that decision is recorded. Growth and Enterprise carry more than one seat, so finance and marketing can look at the same queue.
That is a deliberately unglamorous design. It is also the reason the number survives the meeting where somebody asks where it came from.
Fair questions
Then you have a good answer for the touches that are in it. This adds the ones that are not, and gives you a total that reconciles to the opportunity export rather than to the model.
There is nothing to add. This reads a CSV report your team can already run.
Phones and emails are normalized before matching, which absorbs formatting differences. Nothing is guessed: what does not match exactly stays unattributed, and the one near case — the same number under a different country code — waits for a person.
Closed-won opportunities with a contact email or phone, the amount, and the close date.
No. This is deliberately independent of it — that is the point of reconciling exports instead.
Yes. A partner-sourced list goes into the lead file under its own source name and ranks on closed-won revenue beside direct channels.
At least two sales cycles. Eighteen months is a common starting point for a six-month cycle.
Yes — map the column as Product / service and the report cuts by it.
No. It works from a report export, so no org changes are required.
They carry the same contact, so they credit the channel that first produced the customer. Map a type column as Product / service to see them apart.
Then it cannot be matched and is reported as unattributed. We do not guess from the account name.
Yes, on plans with more than one seat, and every match is auditable and reversible.
An opportunity export with a contact detail, an amount and a close date. No activity history, no custom objects, no attachments. Your org stays where it is — nothing connects to it, because this reads a file you exported rather than holding a credential to your CRM.
Anyone with a seat in the workspace. Decisions are recorded and reversible, so finance and marketing can review the same queue.
The report exports to CSV. It is a summary by channel, campaign and month rather than a row per opportunity, so it suits a reporting layer better than the opportunity record.
By trade
What the report looks like once the export is in, written for each one.
Other systems
Running more than one system, or comparing? The method is the same and the columns are not.
Salesforce and the other product names and logos on this page belong to their owners and are shown to identify the software a file comes from. CloseRev is not affiliated with or endorsed by them, and connects to none of them: it reads a file you export.
From the blog
The export is the part of an attribution project that everyone treats as trivial and that determines whether the whole thing works. Here is the field list, the date-range trap, the deduplication rule, and the six columns to leave out on purpose.
Read the articleEvery attribution vendor quotes a match rate and none of them define it the same way. Here is what the number actually measures, what range is honest for a mid-market business, and the three ways the figure gets inflated before it reaches your slide.
Read the articleThe cheapest leads you buy can turn into your most expensive customers. Customer acquisition cost by channel divides what a channel cost by the new customers it actually produced, and for a business that closes by phone or in person those customers live in the sales records, not the ad dashboard. Here is the formula, which customers to count, fully loaded against paid-media CAC, blended against per-channel, untraced customers, payback and time lag, with a worked example where cost per lead and CAC rank four channels in different orders.
Read the articleStart today
Nothing to install in Salesforce, no API key, and no need to have been tracking anything until now. Last year works as well as this month.