Short answer: CRM revenue attribution links every won deal back to the marketing source that produced it. Capture UTMs and click IDs on the website, store them on the contact as a write-once first source and an overwritable latest source, copy a frozen source snapshot onto each deal when it is created, and report won revenue by source on lead-creation cohorts. HubSpot, Salesforce and Zoho each provide part of this natively; the field design and the "never overwrite first source" rule are what make the numbers trustworthy.
Need this done for you? GrowthSparx offers a fixed-scope lead tracking and attribution setup: GA4, Google Ads, Meta, WhatsApp, calls and CRM wired into one dashboard, usually live in 2–3 weeks.
What is CRM revenue attribution?
CRM revenue attribution answers one question: of the money we actually closed, how much came from each campaign? Ad platforms answer a different question (how many conversions they can claim within their own attribution window) and GA4 answers a third (which channels drive sessions and key events). Only the CRM sees the signed booking form, the paid admission fee or the invoice, so only the CRM can tie spend to revenue.
It rests on three layers. Get any one wrong and the report misleads:
- Capture: the website records where the visitor came from and passes it with the enquiry.
- Persistence: the CRM stores that source on the contact in fields that do not get overwritten by the next email click.
- Attribution to revenue: each deal or opportunity inherits a source, and won value is reported against it.
Which credit rule to use (first touch, last touch, U-shaped) is a separate decision covered in our attribution models guide. This guide is about building the plumbing so any of those rules can be applied.
Which source fields should the CRM have?
Create these as custom properties on the contact or lead object. Use dropdowns where values are known and plain text for raw UTMs. Names below are what we use; match your CRM's naming style.
| Field | Type | Written when | Overwrite? |
|---|---|---|---|
| First touch source / medium / campaign / content | Text | First form submission, from the first-touch cookie | Never |
| First touch landing page, first touch date | Text, date | Same | Never |
| Latest touch source / medium / campaign | Text | Every form submission or tracked return visit | Yes, each time |
| Lead creation source (channel) | Dropdown: Google Ads, Meta Ads, Organic search, Direct, Referral, WhatsApp, Portal, Event, Partner, Offline | Record creation, derived from latest touch at that moment | Never (admin only) |
| GCLID, GBRAID, WBRAID | Text | Form submission | Keep the first; store later IDs in a second field |
| Meta fbc / fbp / Meta lead ID | Text | Form or Instant Form webhook | Keep the first |
| Offline source detail | Dropdown + text | Manually by sales for walk-ins, calls, referrals | Only if no digital source exists |
| Source locked | Checkbox | Set by workflow once first-touch fields are filled | Admin only |
Two design rules matter more than the exact list. First, keep a fixed channel dropdown separate from the raw UTM text, because raw UTMs drift ("facebook", "fb", "Facebook") while a dropdown can be reported cleanly. Second, the channel dropdown should be set by a workflow from UTMs and click IDs, not chosen by a salesperson; when sales picks the source, "Direct" and "Reference" quietly swallow paid leads.
The UTM values themselves need a naming convention before any of this works. See our UTM parameters guide for the conventions and validation rules.
How do you persist first and latest source?
Most lost attribution happens between the ad click and the form. A visitor lands from a Meta ad on the project page, reads the floor plans, opens the pricing page, and submits there. The form page has no UTMs in its URL, so a form that reads only the current URL records "direct". The fix is to store the touch in a first-party cookie on landing and read the cookie at submission.
A minimal script, loaded on every page (via GTM or the site template). It writes the first touch once, and updates the latest touch whenever the visitor arrives with new campaign parameters, keeping both for 90 days:
(function () {var p = new URLSearchParams(location.search);var keys = ['utm_source','utm_medium','utm_campaign','utm_content','utm_term','gclid','gbraid','wbraid','fbclid'];var touch = {};keys.forEach(function (k) { if (p.get(k)) touch[k] = p.get(k); });var isCampaign = Object.keys(touch).length > 0;if (!isCampaign) {touch.referrer = document.referrer ? new URL(document.referrer).hostname : '(direct)';}touch.landing_page = location.pathname;touch.ts = new Date().toISOString();var save = function (name, val) {document.cookie = name + '=' + encodeURIComponent(JSON.stringify(val)) + ';path=/;max-age=7776000;SameSite=Lax';};var has = document.cookie.indexOf('gs_first_touch=') > -1;if (!has) save('gs_first_touch', touch);if (isCampaign || !has) save('gs_latest_touch', touch);})();
Then:
- Add hidden fields to every form (
ft_source,ft_medium,ft_campaign,lt_sourceand so on) and populate them from the two cookies just before submit. The GTM side of this is in our form tracking guide. - Map each hidden field to its CRM property in the form integration. A field that is filled on the website but unmapped in the CRM is the commonest silent failure we find in audits.
- Add a CRM workflow: if First touch source is empty, copy the submitted first-touch values; otherwise leave them. Then tick "Source locked". The website cookie protects first touch for one browser; the workflow protects it across devices and repeat enquiries.
- Write latest-touch values on every submission without conditions.
- For leads that never touch your website (Instant Forms, click-to-WhatsApp ads, portal leads from 99acres or MagicBricks, IndiaMART enquiries), set the source fields in the integration that creates the record: the Meta lead webhook writes "Meta Ads / Instant Form / campaign name", the portal parser writes "Portal / 99acres / project". Click-to-WhatsApp leads need the ad referral data from the chat webhook written to the same fields.
Keep cookie consent in mind: if you run a consent banner, set these cookies only under the consent category that covers analytics or marketing, and describe them in your privacy notice under the DPDP Act 2023.
How should deals and opportunities be attributed?
A contact can create several deals over time: a parent who enquires for one child this year and a second child in two years, or a company that buys an audit and then a retainer. If the deal report reads source from the contact record live, every deal inherits whatever the contact's fields say today. Deal attribution needs its own frozen copy.
- Snapshot on creation. When a deal or opportunity is created, a workflow copies the contact's lead creation source, first-touch campaign and latest-touch campaign into deal-level fields ("Deal source channel", "Deal source campaign"). Those fields are then locked.
- Choose the deal-creating touch for repeat deals. For a second deal from an existing customer, the latest touch before the deal was created is usually more useful than the original first touch from two years ago. Record both and decide in the report.
- Use contact roles or associations. In B2B, several contacts touch one deal. Associate all of them so touch history from every buyer counts, not only the person who filled the form.
- Separate value stages. Store deal amount (expected), won amount (booked), and collected amount (cash) as separate fields. Revenue attribution should use won or collected, never the expected amount on open deals.
- Mark renewals and upsells. A deal type field (New, Renewal, Upsell) stops renewal revenue being credited to the Google Ads click that created the first deal three years ago.
What do HubSpot, Salesforce and Zoho provide natively?
| CRM | Native source fields | Revenue attribution | What you still build |
|---|---|---|---|
| HubSpot | Original and Latest Traffic Source, set automatically from tracked interactions, with two drill-down fields; values include Paid search, Paid social, Organic social, Email marketing, AI Referrals and Offline sources. Associated deals and companies mirror them. | Attribution reports on Marketing Hub Professional or Enterprise; deal-create and revenue attribution are Enterprise only. Models include first, last, linear, U-shaped, W-shaped, time decay and full path. | On lower tiers, deal-level snapshot fields and a revenue-by-source custom report. Hidden UTM fields if forms are not HubSpot forms. |
| Salesforce | Lead Source picklist; Campaign Members; Primary Campaign Source on the opportunity | Customizable Campaign Influence: the default model gives 100% to the Primary Campaign Source; Account Engagement users can add First-Touch, Even Distribution and Last-Touch. Influence records are created only for campaign members with a contact role on an open opportunity. | Custom UTM and click-ID fields on Lead and Contact, field mapping on lead conversion, and discipline about contact roles. |
| Zoho CRM | Lead Source picklist; Google Ads integration captures the GCLID through Zoho web forms and adds Ad Network, Keyword, Search query, Device type and Cost per click to leads, contacts and deals (populated about 24 hours after lead creation). | Standard reports such as "Leads by Google Campaign"; lead creation can be pushed back to Google Ads as a conversion. | Meta and other non-Google sources need custom fields and your own capture script; first-source protection needs a workflow rule. |
Indian CRMs used for high-volume lead gen (LeadSquared, TeleCRM, Kylas and similar) generally let you create custom fields and workflows; the same field design applies, and you build the reports yourself.
Which revenue attribution reports should you build?
Four reports cover most decisions. Build them on lead creation date cohorts: October's leads, whatever month they close, compared with October's spend. Reporting closed revenue by close month against spend in the same month mixes campaigns that are no longer running with ones that have not had time to close.
| Report | Rows | Columns | Decision it supports |
|---|---|---|---|
| Channel revenue cohort | Lead creation channel | Spend, leads, qualified, deals created, deals won, won value, cost per won deal, revenue ÷ spend | Budget split between Google, Meta, portals, SEO |
| Campaign revenue cohort | Deal source campaign | Same as above, filtered to one channel | Which campaigns to scale or cut |
| First vs creation vs latest | Channel | Won value under first touch, lead creation source and latest touch | How much a channel's value depends on the credit rule |
| Time to revenue | Channel | Median days from lead to won, share of won value closed within 30/60/90 days | How long to wait before judging a new campaign |
Pull spend into the CRM or a dashboard from Google Ads and Meta exports; most teams do it weekly in a sheet or Looker Studio. Our guide to a marketing dashboard for leads, pipeline and revenue shows the layout.
Worked example: one quarter of real estate leads
Illustrative numbers, not client data. A Noida developer's Q3 cohort (leads created July–September), tracked to 31 December:
| Lead creation channel | Spend | Leads | Site visits | Bookings | Booked value | Spend ÷ booking | Booked value ÷ spend |
|---|---|---|---|---|---|---|---|
| Google Ads (search) | ₹9,00,000 | 600 | 90 | 6 | ₹5.4 crore | ₹1,50,000 | 60x |
| Meta Ads (lead forms) | ₹7,50,000 | 1,500 | 75 | 3 | ₹2.4 crore | ₹2,50,000 | 32x |
| Property portals | ₹4,00,000 | 400 | 40 | 2 | ₹1.7 crore | ₹2,00,000 | 42.5x |
| Organic and direct | – | 150 | 30 | 2 | ₹1.9 crore | – | – |
What the CRM shows that ad dashboards cannot: Meta produced the cheapest leads (₹500 per lead against ₹1,500 for Google) but the most expensive bookings. Judged on CPL, you would move money to Meta; judged on bookings, the opposite. Before cutting Meta, run the "first vs creation vs latest" report: if many Google bookings had Meta as first touch, Meta is feeding the search demand and the right move is to fix Meta's lead quality, not to stop it. Real ratios vary widely; for reference, the ILeadGuru programme our founder ran in-house reached a 30% lead-to-deal rate once lead quality and follow-up were fixed.
Once the CRM holds this data, feed it back to the ad platforms so they bid for bookings, not form fills: offline conversion tracking for Google Ads and Meta CRM event tracking.
What breaks CRM revenue attribution?
- Imports overwrite source. A bulk upload of event attendees or an old database sets "Lead Source = Import" on existing contacts. Fix: the "Source locked" checkbox and import rules that skip filled source fields.
- Duplicate contacts. The same buyer enquires on Meta, then calls from another number; two records, two sources, one deal attached to the wrong one. Fix: dedupe on normalised phone and email at creation, and merge rules that keep the oldest first-touch values.
- Sales picks the source. Covered above: derive channel by workflow, let sales add only offline detail.
- Expected deal value counted as revenue. Report won or collected amounts only.
- No owner. Someone must check each week that new leads have a non-empty source. A rising share of "unknown" is the earliest sign a form or integration broke. Our lead tracking audit checklist lists the checks.
Sources
- HubSpot Knowledge Base: Understand traffic source properties (Original and Latest Traffic Source, drill-downs, source values)
- HubSpot Knowledge Base: Understand attribution reporting (report types, models, subscription tiers)
- Salesforce: Campaign Influence implementation guide (Primary Campaign Source model, auto-association, contact roles)
- Zoho CRM Help: Zoho CRM for Google Ads (GCLID capture, fields added, reports, conversion push)
