Attribution and UTM Tagging
Some of this happens without you lifting a finger. The rest is a handful of tags on your links, and it is what turns "we spent a lot on ads last quarter" into "this campaign brought 41 leads and $9,190 in sales."
What works today. Attribution reporting is live for HighLevel funnels, forms and order forms, both the part your platform captures automatically and the tags you add (~84% of submissions arrive carrying some attribution). Support for WooCommerce, ThriveCart and Gravity Forms is being built. Tagging still pays off on those platforms in the meantime, because they keep the source on their own records and we pick it up when their connector lands.
Why this matters more than it sounds
Paid traffic has a habit of showing up as organic social, and it happens for two different reasons.
The first is obvious: if you do not tag your links, an ad click and an organic click look identical by the time they reach your site. Both came from Instagram.
The second catches people who are doing the work. On one real account we found 4,318 paid-tagged events in a single quarter sitting in "organic social" — not because the tags were missing, but because the funnel platform's own classifier only treats the literal words cpc and ppc as paid, so a perfectly good utm_medium=paid was read as organic. Their ad spend looked like it produced nothing, and their organic reach looked like a hero.
Tagging fixes the first problem. Adopting Google Analytics' channel rules, which is what Data Curator does, fixes the second.
The one thing to fix first: tag your paid ad links.
Two kinds of attribution
1. What your platform records by itself. The referring site, the landing page, the device, and the click identifier Facebook or Google attaches to an ad click. None of it needs anything from you, and it is enough to tell organic search from social from direct.
2. What your tags add. UTM tags name the specifics. A referrer says "Instagram." A tag says "the spring launch retargeting ad, second image." Tags are also the only reliable way to separate paid from organic.
On one real account over 90 days, only 28% of leads carried UTM tags yet 98% still ended up with a channel, so roughly seven in every ten attributed leads (71.6%) were classified from what the platform captured on its own.
The five parameters
| Parameter | Answers | Example |
|---|---|---|
utm_source | Who does this audience belong to? | fb, acme_main_list |
utm_medium | What kind of traffic? Decides your channel. | paid, email |
utm_campaign | Which push is this part of? | spring_launch_0426 |
utm_content | Which specific creative? | keyboard_img_copy1 |
utm_term | Paid search keywords only. | seo_for_photographers |
Google Analytics drops utm_content and utm_term from most standard reports. Data Curator stores all five.
First, check your tools can capture it
| Your tool | Captures attribution? | Can we read it? |
|---|---|---|
| HighLevel funnels, forms, order forms | Yes, automatically, on most submissions (~84%) | Yes, today |
| WooCommerce 8.5+ | Yes, records the source of every order | Coming soon |
| ThriveCart | Only with tags in its passthrough format | Coming soon |
| Gravity Forms | Only with hidden fields on each form | Coming soon |
| Kit | On the form paths that carry the tags through | Yes |
| ActiveCampaign, Flodesk, Teachable | Nothing they pass along with the contact | No |
- On HighLevel? Tag your links and the reports fill in within a day.
- On WooCommerce, ThriveCart or Gravity Forms? Tag now anyway. Those platforms store the source on their own records, so when we finish reading them your history comes with it.
- On ActiveCampaign, Flodesk or Teachable? Keep tagging. Your links still show up correctly in Google Analytics, which reads them off the page. They will not reach Data Curator, because these platforms do not pass the source along with the contact. Use the capture-point view instead.
Medium: the values that decide your channel
We are adopting Google Analytics' own channel rules rather than inventing our own, so one set of tags serves both tools. Only these count as paid: anything containing cp, or starting with paid. Note ppc and retargeting work only as those exact words (the GA4 regex is ^(.*cp.*|ppc|retargeting|paid.*)$, anchored).
| Medium | For | Lands in |
|---|---|---|
paid or cpc | Facebook, Instagram, TikTok, Pinterest ads | Paid Social |
paid or cpc | YouTube ads | Paid Video |
cpc | Google Ads, Bing Ads | Paid Search |
email | Broadcasts, sequences, newsletters | |
social | Organic posts, bio links | Organic Social |
affiliate | Partner and affiliate links | Affiliates |
referral | Guest posts, show notes, directories | Referral |
sms | Text messages, DMs | SMS |
audio | Podcast sponsorships | Audio |
content | Links inside your own membership or site | Unknown |
Lower case, no spaces. Facebook_Mobile_Feed as a medium reads as organic; cpc_Facebook_Mobile_Feed reads as paid.
Source: naming your audiences
For ads, source is the platform: fb, ig, google. For email, use whatever your platform fills in by default. A default utm_source=convertkit on every email beats hand-building perfect links and giving up after a fortnight. If you later want to tell your own list apart from someone else's traffic on the same platform, move to something unique like acme_main_list.
Campaign and content: think of it as a tree
utm_medium the big branches paid / email / social
└ utm_source smaller branches fb / ig / acme_main_list
└ utm_campaign the twigs spring_launch_0426
└ utm_content the leaves keyboard_img_copy1
Keep campaign names generic and append the date, so spring_launch becomes spring_launch_0426.
Recipes
Meta ads — paste into the URL parameters field at ad level. {{site_source_name}} returns fb, ig, msg or an.
utm_source={{site_source_name}}&utm_medium=paid&utm_campaign={{campaign.name}}&utm_content={{ad.name}}
Google Ads — leave auto-tagging on. Google attaches its own click identifier, and on HighLevel that already lands as paid search today, because HighLevel reads the identifier itself. Adding utm_medium=cpc as well costs nothing and makes it explicit.
Email — ?utm_source=acme_main_list&utm_medium=email&utm_campaign=spring_launch_0426
Organic social — ?utm_source=ig&utm_medium=social&utm_campaign=bio_link
Platform setup notes
Gravity Forms: add hidden fields. One per parameter. In the field's advanced settings, tick Allow field to be populated dynamically and set the Parameter Name to utm_source, utm_medium, utm_campaign or utm_content.
One limitation worth knowing. A hidden field only captures what is in the URL of the page the form sits on. If someone lands on a tagged blog post and then clicks through to your contact page to fill the form in, the tags are already gone. If most of your forms sit on the same page people land on, you are fine. If not, you need something that stores the tags in a cookie on arrival and replays them into the form later.
ThriveCart: the extra step. Your tags go on a second time in ThriveCart's own format, alongside the normal ones. Copy this exactly: the %5B and %5D are encoded square brackets and ThriveCart will not read the parameters with plain [ and ]. Only the {{ }} values change.
passthrough%5Butm_source%5D={{site_source_name}}&passthrough%5Butm_medium%5D=paid&passthrough%5Butm_campaign%5D={{campaign.name}}&passthrough%5Butm_content%5D={{ad.name}}
Mistakes worth avoiding
- Capital letters and spaces.
Spring Launchandspring_launchbecome two different campaigns. - Tagging links inside your own site. A button in your members area does not need a campaign tag. Tagging it makes an existing customer look like a brand new lead. Use
utm_medium=contentor leave them alone. - Tagging and then forgetting. Tags only work going forward. Nothing is applied retroactively.
Keeping links tidy
Tagged links get long. A shortener fixes that and lets you change the destination later. Rebrandly and Bitly both work fine.