UTM Governance: A Naming Convention That Survives Three Agencies
The 60-second version
Most UTM schemes die the first time someone else touches them. A convention, a validator query, and the four rules that keep a taxonomy intact across agency handovers.
- What happened, in one line
- What to do about it this week
- What you can safely ignore
Open your channel report and count the rows. If you see facebook, Facebook, FB, fb, facebook.com, meta, and Facebook_Ads, you do not have a source problem — you have seven rows describing one channel, and every ROAS number computed against any single one of them is wrong.
This did not happen because anyone was careless. It happened because three agencies, two freelancers, one intern and an email platform each built links over four years, and nothing ever validated them. A UTM taxonomy is not a spreadsheet you write once. It is a convention plus an enforcement mechanism, and without the second half the first half decays within about two months of the person who wrote it leaving.
Why conventions decay
The Standard Decay Path
Process FlowSomeone writes the doc
A thorough Google Doc, correct in every particular, shared in a Slack channel that later gets archived.
It works for one quarter
While the author is personally reviewing links, compliance is near-perfect.
A new agency onboards
They have their own convention, from their own last client. Nobody sends them the doc. They ship 200 links.
Someone builds a link on a phone
Autocapitalisation turns `newsletter` into `Newsletter`. A new row appears in the report, permanently.
The report becomes untrustworthy
Someone notices the numbers are wrong, does a manual cleanup, and writes a new doc. Return to step 1.
The doc is not the failure. The failure is that nothing between the doc and the report ever checks. Every durable UTM system has a validator; every fragile one has only a convention.
The four rules
Everything else is detail. These four are what actually determine whether a taxonomy survives a handover.
Rule 1: source and medium are a closed set. Everything else is open.
This is the single most important rule and the one most often broken.
utm_source and utm_medium are the two fields your channel grouping depends on, so they must come from a fixed, short, enumerated list that only changes through a deliberate decision. utm_campaign, utm_content and utm_term can be free-form, because nothing structural depends on them.
| Field | Governance | Values |
|---|---|---|
utm_source | Closed set — additions require a decision | google, meta, linkedin, newsletter, partner, podcast |
utm_medium | Closed set — should almost never change | cpc, paid_social, email, organic_social, affiliate, referral |
utm_campaign | Open, but pattern-enforced | 2026q3_diwali_prospecting |
utm_content | Open | carousel_v3_lifestyle |
utm_term | Open, usually auto-populated | Keyword or audience |
Agencies push back on closed sets because their internal naming differs. That is exactly the point: they conform to yours, or their data is unusable alongside everyone else's.
utm_medium is not a channel name. The most common taxonomy error is utm_medium=facebook — but medium is the type of traffic (paid_social), and source is where it came from (meta). Getting this backwards breaks GA4's default channel grouping, and GA4 will silently reclassify your traffic into "Unassigned" rather than telling you.
Rule 2: Lowercase, underscores, no spaces. Enforced, not requested.
UTM values are case-sensitive in GA4 and in almost every warehouse. Newsletter and newsletter are two different rows forever — there is no retroactive merge.
- Lowercase everything. Autocapitalisation on mobile keyboards is the largest single source of case drift.
- Underscores, never spaces. A space becomes
%20or+depending on the client, so one campaign name can produce three distinct values. - No punctuation beyond underscore and hyphen. Ampersands terminate parameters and silently truncate the rest of your URL.
- Pick underscore or hyphen and never mix. Both work; using both means
black_fridayandblack-fridaycoexist.
Rule 3: utm_campaign carries structure, in a fixed field order
A campaign name is the one place multiple facts have to coexist, so give it a grammar:
<period>_<initiative>_<funnel_stage>
2026q3_diwali_prospecting
2026q3_diwali_retargeting
2026q4_newyear_prospecting
Fixed field order matters because it makes the name parseable in SQL. With a grammar, SPLIT(utm_campaign, '_')[OFFSET(2)] gives you funnel stage as a dimension across every campaign ever run. Without one, funnel stage is locked inside a string and every analysis needs a hand-written CASE WHEN that goes stale.
Two campaign names, one parseable
Rule 4: Never UTM-tag your own internal links
Internal links carrying UTMs start a new session in GA4 and reassign the source, which means a customer who arrived from a paid ad and then clicked an internal banner is re-attributed to that banner. Your paid channel loses the conversion; a homepage carousel gains it.
Use a separate, non-UTM parameter for internal promo tracking — int_promo=homepage_hero, say — and either strip it in your tag configuration or simply do not use UTMs for it. This one mistake can distort a channel report by 20% or more and produces no error anywhere.
Enforcement: the part that makes it survive
The convention is the easy half. Here is what actually holds it together across handovers.
A builder, not a document
Give everyone a link builder that only emits valid values: dropdowns for source and medium, a pattern-validated field for campaign. Even a shared spreadsheet with data-validation dropdowns and a CONCATENATE formula beats a document, because it makes the correct thing the path of least resistance. A person who has to look something up will guess; a person given a dropdown will pick.
A validator query that runs on a schedule
This is what catches drift regardless of who created the link. Run it weekly and route the output somewhere a human reads:
Show query
Catch drift at 40 sessions, not 40,000. A weekly validator surfaces a bad convention while it has affected one campaign. A quarterly review surfaces it after a full quarter of reporting has been built on it — at which point the only options are a painful backfill or a permanent asterisk in your historical data.
A normalisation view, because history is immutable
You cannot retroactively fix links that have already been clicked. What you can do is normalise at read time, so every downstream report sees clean values regardless of what was in the URL:
Show query
Point every report at the view, never the raw table. New drift then costs one WHEN clause instead of a rewrite.
A handover checklist
The moment a taxonomy is most at risk is an agency transition. Make these four things part of the contract:
- The approved source and medium lists, as data, not prose.
- The campaign-name grammar with three worked examples.
- Read access to the validator output, so they see their own violations.
- An explicit statement that unapproved values will be normalised into whatever bucket the view assigns, which is usually not the one they wanted.
What good looks like after six months
Three Levels of UTM Maturity
Reporting HierarchyDocumented
A convention exists in a doc. Compliance depends entirely on whether people read it. Decays within a quarter of the author leaving.
Enforced at build
A link builder with dropdowns makes valid links the easy path. Catches most drift, but nothing stops a hand-typed link.
Enforced at read
A weekly validator catches drift within days, and a normalisation view means historical drift never reaches a report. Survives handovers.
The third tier is roughly a day of work, and it is the only one that is still standing after three agencies.
Frequently asked questions
Are UTM parameters case-sensitive?
The parameter names are conventionally lowercase and treated case-insensitively by most tools, but the values are case-sensitive everywhere that matters — GA4, BigQuery, and every warehouse. Email and email are two permanent rows.
Should I put UTMs on Google Ads links?
Generally no. Google Ads auto-tagging with gclid gives richer data than UTMs and does not conflict with GA4's channel grouping. Manual UTMs on Google Ads links can override auto-tagging and lose you the click-level detail. Use auto-tagging, and use UTMs for the channels that have no equivalent — email, partners, podcasts, influencers.
What about utm_id?
utm_id is intended to carry a campaign identifier that ties back to a cost-data import in GA4. It is genuinely useful if you are importing cost data, and pointless otherwise. It does not replace utm_campaign.
How do I fix historical data that is already messy?
You do not fix it — you normalise it at read time with a view, as above. Rewriting stored session data is possible in a warehouse and almost never worth it: the mapping logic has to exist either way, and putting it in a view means it stays visible and correctable.
Should the agency get to add new sources?
They should be able to request one, and someone on your side approves it. An open source list is functionally the same as no list — within two quarters you are back to seven rows for one channel.
The summary
- Closed set for
sourceandmedium; open but pattern-enforced forcampaign. This is the rule everything else hangs off. - Lowercase, underscores, no spaces, no mixing separators — enforced by a builder, not requested in a doc.
- Give
utm_campaigna fixed field grammar so it can be parsed in SQL rather than decoded by hand. - Never UTM-tag internal links; it restarts the session and steals the conversion from the channel that earned it.
- Run a drift validator weekly and normalise at read time. The convention is not the system — the validator is the system.
Related: how channel CAC depends on this taxonomy being clean, and what to do when ad spend and orders share no join key.
Blended CAC Calculator
Total spend across every channel, divided by total new customers — the acquisition cost number that reconciles with what you actually spent.
Chinmay Raibagkar
About author →Founder of DataLens AI. He helps non-technical teams read their ad and database numbers with confidence — which number to trust, what to do next, and what to ignore.