UTM parameters: three you always use, four optional, and two that go nowhere
UTM parameters are the labels you attach to a link so analytics can say where a visit came from. Google Analytics recognises nine, three of them are effectively required, and two are accepted and then not reported at all.

UTM parameters are the labels you bolt onto a link so that analytics can say where a visit came from. Google Analytics recognises nine of them. Three carry the report you will actually read, four more are optional detail, and two are accepted and then not reported anywhere. Every one of them is a string you invented, which is why the naming rule matters more than the parameter list.
What you need before this chapter
You need a working analytics property and one honest expectation: labelling only works on links you control. Traffic that arrives without a label lands in whatever bucket the tool guesses, and for answer engines that bucket is usually Direct — the shape of that problem is in AI traffic showing as direct in GA4. Nothing in this chapter fixes that. It fixes the half you can label.
What UTM parameters actually do
They add key-value pairs to the end of a URL. The server ignores them, the page renders the same, and the analytics script reads them and files the visit under the names you supplied. There is no registry and no validation: utm_medium=email and utm_medium=Email are two different media, forever, in two different rows.
That is the whole mechanism. It also explains the failure mode everyone hits at month three — a report with fourteen spellings of the same newsletter — and why the deliverable in this chapter is a naming convention rather than a builder tool.
A UTM parameter is not a measurement. It is a label you promised to keep spelling the same way.
The nine parameters, and the two that go nowhere
Google is direct about the minimum: "When you add parameters to a URL, you should always use utm_source, utm_medium, and utm_campaign" (Collect campaign data with custom URLs, read 2026-09-04). The same page warns what happens if you skip them: "Missing UTM parameters will result in (not set) values being present in reporting."
| Parameter | Holds | Status |
|---|---|---|
utm_source | Where the click came from | Always use |
utm_medium | The channel type | Always use |
utm_campaign | The campaign name | Always use |
utm_id | A campaign ID | Optional |
utm_term | The paid keyword | Optional |
utm_content | Which creative | Optional |
utm_source_platform | The platform that sent it | Optional |
utm_creative_format | Creative type | Not reported |
utm_marketing_tactic | Targeting approach | Not reported |
The last two rows are worth reading twice. Google's own wording is that "utm_creative_format isn't currently reported in Google Analytics properties", and the identical sentence appears for utm_marketing_tactic. They are accepted, stored on the event, and absent from the interface. Adding them lengthens your URLs and changes no report you can open today.
The naming convention to copy
Four rules. They are boring on purpose, because the only thing that makes campaign reports readable is that nobody improvised.
- Lowercase everything, always. Case is preserved and case-sensitive, so one capital letter splits a row in two.
- Hyphens between words, underscores never. Pick one separator and put it in the document that people copy from.
utm_mediumcomes from a closed list you write down once. Five or six values, and adding a new one is a decision someone makes on purpose.utm_sourceis a place,utm_mediumis a kind of place.newsletteris not a medium;emailis.
# The closed list, kept somewhere everyone can find it
utm_medium ∈ { email | social | cpc | referral | affiliate | qr }
# One link, spelled the way the convention says
https://example.com/pricing
?utm_source=weekly-digest
&utm_medium=email
&utm_campaign=2026-09-pricing-update
&utm_content=header-button
# Same campaign, second creative — only utm_content changes
&utm_content=footer-text-link
Keep the campaign name date-prefixed. Sorting a campaign column alphabetically then sorts it chronologically, which is the one report layout nobody has to be taught to read.
The closed list is the part that gets skipped, and it is the part that pays. Six values is a channel report a person can read at a glance; thirty values is a spreadsheet that someone has to normalise by hand every month, and the normalising is guesswork because only the person who typed the label knows what they meant.
Do not put UTM parameters on your own internal links
Two of the three reasons are documented, and the third is where we stop and say we do not know.
The documented half is about search, not analytics. A labelled internal link is a second URL for a page that already had one, and Google will then decide which one to show: "If you don't specify a canonical URL, Google will identify which version of the URL is objectively the best version to show to users in Search" (How to specify a canonical URL, read 2026-09-04). A self-referencing canonical, covered in how to use canonical tags, is what keeps that decision from being made for you.
The second is reporting. Landing-page and campaign columns fill up with rows describing your own navigation, and the traffic that arrived from outside gets harder to find in its own report.
The third is attribution, and here the documentation stops short. Google states that "the session_start event carries the information that determines the attribution of the session, such as the gclid, UTM parameters, and referrer" ([GA4] Analytics sessions, read 2026-09-04). What that leaves open is what a labelled click does in the middle of a session that has already started. We have not run that test, so we will not tell you it rewrites the source. The first two reasons are enough on their own.
The audit you can run today
One command finds internal links already carrying labels. Run it on any template-heavy page — a homepage, a category page, an email footer rendered to HTML.
# Internal links on your own page that already carry a campaign label
curl -sL -A 'Mozilla/5.0' https://example.com/ \
| grep -oE 'href="[^"]*utm_[^"]*"' | sort | uniq -c | sort -rn
# Every distinct medium currently in use across a set of links
grep -ohE 'utm_medium=[^&"]+' links.txt | sort | uniq -c | sort -rn
The second line is the one that finds convention drift. If it returns more than about six values, the closed list is not being used, and no amount of tidying the report afterwards will merge Email back into email.
Three ways this goes wrong
All three are silent. The report keeps rendering, the numbers keep adding up, and the thing you are looking at is quietly describing something other than what you meant to measure.
- Two spellings of one source. Splitting a channel across rows understates both. This never announces itself; the report simply looks smaller than it should.
- Labels on links you do not control. Anyone can copy your labelled URL and post it elsewhere, and the visit is filed as your newsletter regardless. Labels are trusted input, not verified input.
- Labelled URLs in sitemaps or canonical tags. A tracking URL is not a page, and it should never be the address you nominate as the real one. Once one is in a sitemap it is very hard to notice.
What none of this settles is how much of your total arrival volume can be labelled at all. On most sites the labelled share is small, and the rest has to be reconstructed from two systems that disagree — that reconstruction is SEO attribution in one number. To check what a labelled URL actually returns before you send it to anyone, see how QueryWin reads a page.
Common questions
Are UTM parameters bad for SEO?
Not by themselves. The risk is duplicate addresses for one page, and a self-referencing canonical settles that. Labelled URLs should never be the ones you submit or link to internally.
Which UTM parameters are required?
Google names three: source, medium and campaign. The rest are optional, and two of the nine are not reported at all.
Does the order of the parameters matter?
No. They are read as key-value pairs. Keeping a consistent order still helps humans scan a spreadsheet of links.
Can I use UTM parameters with a hash instead of a question mark?
No. They have to be in the search string, before any fragment. A parameter placed after # is not sent to the analytics script the same way and will not be read as a campaign label.
How do I clean up a year of inconsistent labels?
You cannot retroactively fix the collected data. Write the closed list, apply it to everything you send from today, and treat the old rows as a separate era in the report rather than something to merge.
Part of the QueryWin handbook · Level 2


