At a glance
- Level
- Beginner
- Time
- 11 min
Prerequisites
- Admin access to GA4 and your ad platforms
- Agreement from channel owners on a shared convention
- A place to host the vocabulary file and link builder (a sheet is fine)
You will end up with
A controlled UTM vocabulary, a parseable campaign naming pattern, automated tagging per platform, a cleanup layer and a monthly audit that keeps Unassigned traffic under 5%.
Connectors used
What is a UTM taxonomy, and why does it break?
UTM parameters are query-string tags such as ?utm_source=linkedin&utm_medium=paid_social&utm_campaign=2026q4_demand_webinar-ai-search_emea that tell your analytics where a visit came from. A UTM taxonomy is the written set of rules for which values are allowed in each parameter, how campaign names are built, and who maintains the lists.
Taxonomies break for predictable reasons. Different people build links in different tools. Agencies bring their own conventions. Someone types LinkedIn once and linkedin the next time. A scheduling tool appends its own medium. Within a year, the same channel appears under a dozen spellings and the cross-channel dashboard shows a growing "Unassigned" bar. The fix is not a longer document; it is fewer free-text decisions.
Which UTM parameters should you use?
GA4 supports more than the classic five parameters. utm_source, utm_medium and utm_campaign populate session source, medium and campaign in the Traffic acquisition report; utm_id, utm_term, utm_content and utm_source_platform are also supported, while utm_creative_format and utm_marketing_tactic are listed but not currently reported in GA4 properties1Source 1 · Google Analytics Help[GA4] URL builders: Collect campaign data with custom URLssupport.google.com.
| Parameter | Meaning | Rule | Example |
|---|---|---|---|
| utm_source | Who sent the visit | Controlled list, lowercase | linkedin, google, newsletter |
| utm_medium | How it was sent (the channel type) | Controlled list matching channel rules | paid_social, cpc, email, social |
| utm_campaign | Why: the campaign or initiative | Fixed pattern, see below | 2026q4_demand_webinar-ai-search_emea |
| utm_id | Campaign ID for cost import or joins | Use platform campaign ID when available | 23847561 |
| utm_content | Which creative or link | Short, descriptive, lowercase | carousel-v2, hero-cta |
| utm_term | Keyword or audience | Paid search keyword or audience name | lookalike-1pct |
| utm_source_platform | Buying platform | Optional; for multi-platform buys | dv360 |
Controlled vocabularies for source and medium
Medium is the most important parameter for channel reporting, because GA4’s default channel group rules mostly key off it. Paid Social requires a social source and a medium matching ^(.*cp.*|ppc|retargeting|paid.*)$; Organic Social accepts mediums such as social, social-network, social-media and sm; Email matches email, e-mail, e_mail or e mail in source or medium; Display matches display, banner, expandable, interstitial or cpm2Source 2 · Google Analytics Help[GA4] Default channel groupsupport.google.com. Choose medium values that land in the right group without custom rules.
| utm_medium | Use for | GA4 default channel |
|---|---|---|
| cpc | Paid search clicks (non-Google engines; Google Ads uses auto-tagging) | Paid Search |
| paid_social | All paid social: Meta, LinkedIn, TikTok, X, Pinterest ads | Paid Social |
| social | Organic posts, bios, profile links | Organic Social |
| Owned newsletters and lifecycle email | ||
| display | Programmatic and banner placements | Display |
| referral | Partner sites, directories, guest posts | Referral |
| affiliate | Affiliate and creator programs | Affiliates |
| pr | Earned media links you place or track | Custom: Earned media |
| qr | Offline: print, events, packaging | Custom: Offline |
Keep the source list just as tight: platform names in lowercase with no suffixes (linkedin, not linkedin.com or LinkedIn-Ads), newsletter names as newsletter-{name}, and partners by short domain. Store both lists in one place that every link tool reads from.
How should you name campaigns?
Use a fixed pattern with delimited slots, so a campaign name can be parsed back into its parts in SQL. Use underscores between slots and hyphens inside a slot. We recommend four slots:
utm_campaign={period}_{objective}_{initiative}_{market}
- period
- Quarter or month the campaign launched (2026q4 or 2026-10), or evergreen for always-on links
- objective
- Controlled list: awareness, demand, retention, launch, hiring
- initiative
- Free text in kebab case, short: webinar-ai-search, spring-sale
- market
- Controlled list: global, na, emea, apac, or ISO country codes
Example: 2026q4_demand_webinar-ai-search_emea. Because the slots are fixed, a single SQL expression can split it, and your dashboard can group spend and outcomes by objective or market across every platform. Use the same string as the campaign name inside each ad platform; that is what lets spend join to sessions and revenue later.
select
utm_campaign,
split_part(utm_campaign, '_', 1) as period,
split_part(utm_campaign, '_', 2) as objective,
split_part(utm_campaign, '_', 3) as initiative,
split_part(utm_campaign, '_', 4) as market,
utm_campaign ~ '^([0-9]{4}(q[1-4]|-[0-9]{2})|evergreen)_(awareness|demand|retention|launch|hiring)_[a-z0-9-]+_[a-z-]+$' as is_valid
from campaigns_seenPlatform-specific setups
The fewer links people tag by hand, the fewer errors you get. Each major platform has a way to automate tags.
- Step 1:
Google Ads: rely on auto-tagging
Auto-tagging adds a
gclidparameter to ad clicks. In GA4, auto-tagging is prioritized over manual tagging with no override option3Source 3 · Google Ads HelpAbout auto-taggingsupport.google.com, so you do not need UTMs on Google Ads links. Make sure auto-tagging is on and the accounts are linked. - Step 2:
Meta, LinkedIn, TikTok: use URL parameter fields and dynamic values
Put tags in each platform’s URL parameters (tracking) field rather than in the destination URL, and use dynamic values where offered, for example Meta’s
{{campaign.name}}and{{ad.name}}. Then make the platform campaign name follow your pattern, and the tag follows automatically. - Step 3:
Email platforms: set defaults once
Mailchimp and Brevo can append UTM parameters to every link automatically. Set source to
newsletter-{name}, medium toemail, and the campaign to your pattern in the template, not per send. - Step 4:
Social schedulers and organic posts
Configure the scheduler’s UTM template with
utm_medium=socialand the platform as source. For profile and bio links, use a permanent campaign such asevergreen_awareness_profile-link_global. - Step 5:
Offline and QR codes
Use
utm_medium=qrand a short redirect you control, so you can fix a tag after the brochure is printed.
Governance: making the right link the easy link
Governance fails when it depends on memory. It works when the compliant path is faster than the non-compliant one.
| Element | What it is | Owner |
|---|---|---|
| Vocabulary file | Allowed sources, mediums, objectives and markets, versioned | Marketing ops |
| Link builder | A form or sheet that only offers allowed values and builds the URL | Marketing ops |
| Campaign registry | One row per campaign: name, owner, dates, platforms, budget | Campaign owner |
| Change process | New values requested via a short form, approved weekly | Marketing ops |
| Monthly audit | Non-conforming values with session counts, sent to owners | Analytics |
Agencies and freelancers get the vocabulary file and link builder on day one, and their contract includes the convention. Reports from external partners use your campaign names, not theirs.
Cleanup rules for the mistakes that still happen
Even with good governance, some links will be wrong, and historical data predates your convention. Fix it in a cleanup layer in your data model rather than editing raw data, so every fix is visible and reversible.
with normalized as (
select
session_id,
date,
lower(trim(utm_source)) as src,
lower(trim(utm_medium)) as med,
lower(trim(utm_campaign)) as campaign
from web_sessions_raw
)
select
n.session_id,
n.date,
coalesce(sa.canonical, n.src) as utm_source,
coalesce(ma.canonical, n.med) as utm_medium,
n.campaign as utm_campaign
from normalized n
left join source_aliases sa on sa.alias = n.src -- e.g. 'linkedin.com', 'lnkd.in' -> 'linkedin'
left join medium_aliases ma on ma.alias = n.med -- e.g. 'paidsocial', 'paid-social', 'cpc_social' -> 'paid_social'Keep the alias tables small and reviewed. Each new alias is a signal that the link builder or a platform template needs fixing at the source. If a large share of sessions shows (not set) for source or medium, check the tagging basics first: Google documents causes such as a missing session_start event when the tag is not triggered on initialization, unlinked Google Ads accounts, disabled auto-tagging and incomplete UTM parameters4Source 4 · Google Analytics Help[GA4] What the value (not set) means in your reportssupport.google.com.
How do you audit UTMs every month?
Run one query on the first business day of each month and send the result to campaign owners. It lists every value outside the vocabulary, ranked by sessions, so people fix what matters.
select
utm_source,
utm_medium,
utm_campaign,
count(*) as sessions,
case
when utm_medium not in (select value from allowed_mediums) then 'medium not allowed'
when utm_source not in (select value from allowed_sources) then 'source not allowed'
when utm_campaign !~ '^([0-9]{4}(q[1-4]|-[0-9]{2})|evergreen)_[a-z]+_[a-z0-9-]+_[a-z-]+$' then 'campaign pattern'
else 'ok'
end as issue
from sessions_clean
where date >= date_trunc('month', current_date) - interval '1 month'
and date < date_trunc('month', current_date)
group by 1, 2, 3
having count(*) >= 20
order by issue <> 'ok' desc, sessions descIn Kimo you can save this as a model and attach an alert that fires when non-conforming sessions exceed 5% of the month. The same model feeds the Unmapped row on the Marketing command center, so the problem is visible where people already look.
Worked example: one campaign across five channels
Suppose your team launches a webinar on AI search in Europe during the fourth quarter. The campaign name is decided once, in the campaign registry: 2026q4_demand_webinar-ai-search_emea. Every channel then reuses that exact string, and only source, medium and content change.
| Channel | utm_source | utm_medium | utm_content | How the tag is applied |
|---|---|---|---|---|
| Google Ads | (auto-tagging) | (auto-tagging) | — | gclid; campaign named identically in Google Ads |
| LinkedIn Ads | paid_social | single-image-v1 | URL parameters field in Campaign Manager | |
| Meta Ads | facebook or instagram | paid_social | {{ad.name}} | URL parameters field with dynamic values |
| Newsletter | newsletter-product | hero-cta | Template default in the email platform | |
| LinkedIn Page post | social | post-announcement | Scheduler UTM template |
A month later, the dashboard can answer questions that are impossible with ad hoc tags: how many registrations the webinar produced per channel, what each registration cost on paid channels, how organic posts compared with paid ones, and whether EMEA demand campaigns as a group are improving quarter over quarter. Because the objective and market are parseable slots, the same query works for every future campaign without editing.
How the tags connect spend to revenue
Three joins make cross-channel reporting work. Spend joins to sessions on the campaign name and date. Sessions join to sign-ups or leads on the session or user identifier your product captures at conversion. Leads join to opportunities or orders in your CRM or shop. If any link in that chain uses a different spelling, the chain breaks and the revenue falls into Unassigned. This is why a taxonomy is a revenue-reporting prerequisite, not a tidiness project. Our post on one marketing dashboard shows the finished view, and the command center in the Kimo Marketing app renders it on simulated data.
Common mistakes and how to avoid them
| Mistake | Effect | Fix |
|---|---|---|
Mixed case (Facebook, facebook) | One source split into several rows | Lowercase in builder and in cleanup |
| Creative names in utm_medium | Traffic lands in Unassigned | Medium from the controlled list only; creative goes in utm_content |
utm_medium=social on paid ads | Paid traffic counted as organic | Use paid_social for all paid placements |
| Manual UTMs on Google Ads | Redundant at best; inconsistent naming at worst | Rely on auto-tagging and account linking |
| UTMs on internal links | Original source overwritten | Use events or content groups |
| Different campaign names in ad platform and UTM | Spend cannot be joined to outcomes | One string, used in both places |
| Spaces and special characters | Encoded values that are hard to filter | Lowercase letters, digits, hyphens and underscores only |
One more subtle point: GA4 also keeps the traffic source that first acquired a user, and those values do not change after acquisition, even if the user later arrives through new campaigns5Source 5 · Google Analytics Help[GA4] BigQuery Export schemasupport.google.com. Decide whether a report should use first-user or session attribution and label it clearly. A clean taxonomy is what makes both views trustworthy, and it is the backbone of a unified marketing dashboard and of any attribution model you adopt later.
UTM taxonomy launch checklist
- Vocabulary file published with allowed sources, mediums, objectives and markets.
- Mediums chosen to land in GA4 default channel groups without custom rules.
- Campaign pattern defined with four slots and a validation regex.
- Google Ads auto-tagging confirmed; other platforms use dynamic parameters.
- Email and scheduler templates updated with default tags.
- Link builder offers only allowed values and outputs lowercase.
- Cleanup layer with alias tables in the data model.
- Monthly audit scheduled and routed to campaign owners.
Sources
5 references- [GA4] URL builders: Collect campaign data with custom URLs (opens in a new tab)Google Analytics Helpsupport.google.com
Supported UTM parameters, their report mapping, and case sensitivity.
- [GA4] Default channel group (opens in a new tab)Google Analytics Helpsupport.google.com
Medium and source rules for Paid Social, Organic Social, Email, Display and more.
- About auto-tagging (opens in a new tab)Google Ads Helpsupport.google.com
GCLID auto-tagging is prioritized over manual tagging in GA4.
- [GA4] What the value (not set) means in your reports (opens in a new tab)Google Analytics Helpsupport.google.com
Causes of (not set) source, medium and campaign values.
- [GA4] BigQuery Export schema (opens in a new tab)Google Analytics Helpsupport.google.com
First-user traffic_source fields do not change after acquisition; session last-click fields.
External sources were accessed at the time of writing. Kimo product details, customers and figures in examples are illustrative unless a source is cited.
Mark as done
0 of 10 sections done
Frequently asked questions
Are UTM parameters case sensitive?
Yes. In GA4, utm_source=google and utm_source=Google are recorded as different values. Use lowercase everywhere and normalize case in your data model as a safety net.
Do I need UTM parameters on Google Ads links?
Usually not. With auto-tagging enabled and Google Ads linked to GA4, the gclid carries campaign data, and GA4 prioritizes auto-tagging over manual tags.
What is the difference between utm_source and utm_medium?
Source is who sent the visit, such as linkedin or a newsletter name. Medium is the type of channel, such as paid_social, social or email. Channel groupings depend mostly on medium.
Should I use UTM parameters on internal links?
No. They overwrite the visitor’s original source and inflate the number of sessions attributed to your own site. Track internal promotions with events instead.
How do I fix historical UTM data?
Do not edit raw data. Add a cleanup layer that lowercases values and maps known aliases to canonical values, and keep the alias tables under review.
Skip the setup — start from a working version.
Marketing command center: Every channel on one screen: social, SEO, paid, email and media.



