kimo
GuideBeginner11 minMarketing

A UTM taxonomy that survives contact with reality

A UTM taxonomy that survives contact with reality has three parts: a small controlled vocabulary for utm_source and utm_medium that maps cleanly to your channel groups, a structured but readable pattern for utm_campaign, and governance that makes the right link the easiest one to create. Add a monthly audit and a cleanup layer for the mistakes that still slip through, and cross-channel reporting becomes possible.

Sam Okafor · Growth lead
11 min read

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%.

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.

Share of sessions in Unassigned or Unmapped, before and after governance
Figure. Illustrative data: a simulated B2B team that introduced a controlled vocabulary and a link builder in month 4, then a monthly audit in month 6.

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 properties1.

ParameterMeaningRuleExample
utm_sourceWho sent the visitControlled list, lowercaselinkedin, google, newsletter
utm_mediumHow it was sent (the channel type)Controlled list matching channel rulespaid_social, cpc, email, social
utm_campaignWhy: the campaign or initiativeFixed pattern, see below2026q4_demand_webinar-ai-search_emea
utm_idCampaign ID for cost import or joinsUse platform campaign ID when available23847561
utm_contentWhich creative or linkShort, descriptive, lowercasecarousel-v2, hero-cta
utm_termKeyword or audiencePaid search keyword or audience namelookalike-1pct
utm_source_platformBuying platformOptional; for multi-platform buysdv360
Parameter reference with our recommended rules.

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 cpm2. Choose medium values that land in the right group without custom rules.

utm_mediumUse forGA4 default channel
cpcPaid search clicks (non-Google engines; Google Ads uses auto-tagging)Paid Search
paid_socialAll paid social: Meta, LinkedIn, TikTok, X, Pinterest adsPaid Social
socialOrganic posts, bios, profile linksOrganic Social
emailOwned newsletters and lifecycle emailEmail
displayProgrammatic and banner placementsDisplay
referralPartner sites, directories, guest postsReferral
affiliateAffiliate and creator programsAffiliates
prEarned media links you place or trackCustom: Earned media
qrOffline: print, events, packagingCustom: Offline
A medium list that maps cleanly to GA4 default channel groups.

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:

Formula

utm_campaign={period}_{objective}_{initiative}_{market}

where
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.

Parse campaign names into slots
sql
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_seen

Platform-specific setups

The fewer links people tag by hand, the fewer errors you get. Each major platform has a way to automate tags.

  1. Step 1:

    Google Ads: rely on auto-tagging

    Auto-tagging adds a gclid parameter to ad clicks. In GA4, auto-tagging is prioritized over manual tagging with no override option3, so you do not need UTMs on Google Ads links. Make sure auto-tagging is on and the accounts are linked.

  2. 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.

  3. Step 3:

    Email platforms: set defaults once

    Mailchimp and Brevo can append UTM parameters to every link automatically. Set source to newsletter-{name}, medium to email, and the campaign to your pattern in the template, not per send.

  4. Step 4:

    Social schedulers and organic posts

    Configure the scheduler’s UTM template with utm_medium=social and the platform as source. For profile and bio links, use a permanent campaign such as evergreen_awareness_profile-link_global.

  5. Step 5:

    Offline and QR codes

    Use utm_medium=qr and 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.

ElementWhat it isOwner
Vocabulary fileAllowed sources, mediums, objectives and markets, versionedMarketing ops
Link builderA form or sheet that only offers allowed values and builds the URLMarketing ops
Campaign registryOne row per campaign: name, owner, dates, platforms, budgetCampaign owner
Change processNew values requested via a short form, approved weeklyMarketing ops
Monthly auditNon-conforming values with session counts, sent to ownersAnalytics
A lightweight governance model for teams of 5 to 50.

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.

sessions_clean.sql: normalize, alias, then map
sql
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 parameters4.

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.

utm_audit.sql
sql
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 desc

In 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.

Channelutm_sourceutm_mediumutm_contentHow the tag is applied
Google Ads(auto-tagging)(auto-tagging)—gclid; campaign named identically in Google Ads
LinkedIn Adslinkedinpaid_socialsingle-image-v1URL parameters field in Campaign Manager
Meta Adsfacebook or instagrampaid_social{{ad.name}}URL parameters field with dynamic values
Newsletternewsletter-productemailhero-ctaTemplate default in the email platform
LinkedIn Page postlinkedinsocialpost-announcementScheduler UTM template
The same campaign, tagged consistently across channels.

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

MistakeEffectFix
Mixed case (Facebook, facebook)One source split into several rowsLowercase in builder and in cleanup
Creative names in utm_mediumTraffic lands in UnassignedMedium from the controlled list only; creative goes in utm_content
utm_medium=social on paid adsPaid traffic counted as organicUse paid_social for all paid placements
Manual UTMs on Google AdsRedundant at best; inconsistent naming at worstRely on auto-tagging and account linking
UTMs on internal linksOriginal source overwrittenUse events or content groups
Different campaign names in ad platform and UTMSpend cannot be joined to outcomesOne string, used in both places
Spaces and special charactersEncoded values that are hard to filterLowercase 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 campaigns5. 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
  1. [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.

  2. [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.

  3. About auto-tagging (opens in a new tab)
    Google Ads Helpsupport.google.com

    GCLID auto-tagging is prioritized over manual tagging in GA4.

  4. [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.

  5. [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.

0%

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.

Put it to work

Skip the setup — start from a working version.

Marketing command center: Every channel on one screen: social, SEO, paid, email and media.

All resources
Whitepaper
Marketing

One View of Marketing

Unified measurement across social, search, paid and earned media, in the age of AI search.

Nadia Benali
24 pages
Definition
Marketing

UTM parameters

UTM parameters are tags appended to a URL, such as utm_source, utm_medium and utm_campaign, that tell analytics tools which source, channel and campaign a visit came from.

Kimo team
3 min read

Every channel. One dashboard.

Social, SEO, paid, email, PR and AI-search visibility, normalized into one command center your whole team reads the same way.