You have inherited a set of tagged links and a campaign report that does not reconcile with what was posted. One launch appears twice with different totals. Social traffic sits in a channel you did not expect. Nobody who built the links still works here.
Why the rows do not reconcile
Campaign parameters are collected as text. Google’s documentation is explicit: parameter values are case sensitive, so utm_source=google is a different value from utm_source=Google, and two spellings differing by separator are distinct. No Google Analytics report setting is documented to merge them afterwards.
The cost arrives late. The tagging decision is made on the day a link is posted, and surfaces a quarter later when someone tries to compare two campaigns and cannot.
Links already shared cannot be corrected, because their data was stored as it arrived. The convention applies from the next link forward, and the old rows are read with the collisions understood rather than fixed. Every claim about parameter handling below traces to the platform’s own documentation, checked on 26 August 2026.
The five parameters, and the one decision each one hides
Google documents more, but five carry most social tagging, each hiding a decision.
| Parameter | Documented to carry | The decision to freeze first |
|---|---|---|
| utm_source | The referrer, examples google and billboard, one per platform, sub-platforms as fb and insta. | Which single string represents one network, and where the approved list lives. |
| utm_medium | The marketing medium, examples cpc and banner, one per channel. | Whether organic and paid social share a value. Medium feeds channel grouping. |
| utm_campaign | The product, slogan or promo code. One unique name per campaign, documented as what stops one effort splitting into rows. | A launch, a quarter, or an offer. Scope decides whether two rows are comparable. |
| utm_content | A way to differentiate creatives, for example two links in one message. | One job only, creative variant or placement, never both. |
| utm_term | The paid keyword, with guidance asking for lowercase and identical spelling. | That it stays empty for anything that is not paid keyword traffic. |
The convention, written out
These are rules, not preferences. A preference gets renegotiated by whoever joins next.
- All values lowercase, every parameter. Google names lowercase as standard practice, which removes the judgement call.
- One separator, everywhere. Underscore or hyphen, never mixed. A space is encoded in the query string, so it stores as a different value again.
- One approved string per network, in a named place: a shared sheet or a locked dropdown. New strings join the list before use, never invented at build time.
- A fixed field order for the campaign value. If the order is period, type, subject, the value is 2026q3_launch_pricingpage, and a colleague next month produces the same string.
- utm_term stays empty unless the traffic is paid keyword traffic. It is not a second content field.
- One page, one named owner, stored beside the builder and handed over deliberately.
Collision one: the same value in two cases
Two links go out in one week for one launch. Monday’s carries utm_campaign=springlaunch. Thursday’s, built by a colleague working from memory, carries utm_campaign=SpringLaunch. The report shows two rows.
Sessions and conversions divide across them, so each row understates the launch and any threshold built on one row is quietly wrong. The account total is intact, which is why nobody catches it.
Since the documentation is explicit that values are case sensitive, the fix is casing enforced at build time rather than corrected in the report. One boundary: the default channel group page states channel definitions are not case sensitive, so only value storage splits rows.
Collision two: one network, several sources
The most common inherited defect. One network arrives under four source strings: a full domain, a bare brand word, an abbreviation, and a value naming the placement instead of the network.
The damage is not confined to the campaign table. Google’s default channel group rules are evaluated against the collected source and medium, so an unrecognised string files the traffic under a channel you would never check. Those groups cannot be edited.
A shortener or redirect neither creates nor normalises these values. What reaches the report is what sat on the final destination URL. The forward fix is a closed list of approved source strings.
Collision three: utm_content doing two jobs
The subtlest of the three, because nothing looks broken. One campaign used utm_content for the creative variant, values like video_a and video_b. A later campaign, different person, used it for placement, values like bio and story. Every value obeys the casing and separator rules.
Now ask: across those two quarters, did the first creative variant outperform the second? You cannot. Two different things share one dimension, nothing in the value says which is which, and they report as one row.
That is a merge, not a split, and it survives because the total still looks right. When you need both, pick which one utm_content owns, encode the other in the campaign value or a separate parameter, and record the decision. One job per parameter, in writing.
Taking over a set of links you did not build
Audit before changing anything. Pull the distinct campaign, source, medium and content values already in the report and read them as a record of what previous authors did, not as a list of errors.
Read it as patterns. One thing spelled several ways is a split, collision one. Several strings pointing at one network is collision two, worth checking first because it reaches channel grouping. A content list holding two unlike kinds of value is collision three.
Then cut over on a stated date, recorded in the document. Any comparison spanning that date crosses two tagging schemes and needs a note attached rather than a chart presented as continuous. The historical rows are not repaired. Annotate them.
Build every link in one builder so nothing is hand typed; Google directs website link tagging to its Campaign URL Builder. Source, medium and the campaign field order belong there as constrained choices, with free text limited to the subject. Plausible’s documentation lists all five parameters too, so none of this is vendor specific.
The check before a link goes out
The only moment this is enforceable.
- Casing checked against the rule, not against memory.
- Source string confirmed against the approved list, not typed.
- Campaign value follows the field order, and you can say what it is scoped to.
- utm_content carries the one job the convention assigned it.
- utm_term empty unless this is paid keyword traffic.
- Destination is the final URL, so no redirect sits between the link and the page that reports the visit.
Where to go next
What link management tools meter covers the commercial side this post leaves alone. Handing over brand account access applies the same handoff argument to credentials.
Sources were verified on 26 August 2026 and are listed below. No prices appear in this post, and nothing here is Watchdog data or on the re-verification schedule. Disclosure: followedapp is published by the team behind RecurPost, and RecurPost is a covered vendor under the same rules as every other vendor.
FAQ
Are UTM parameters case sensitive?
Yes, and the documentation says so. Google’s URL builder page states that parameter values are case sensitive, gives utm_source=google and utm_source=Google as different values, and recommends lowercase as standard practice. Plausible also calls UTM tags case sensitive, though its Sources tab consolidates capitalisation differences into one entry. That is a report view, not a general rule.
Can I fix UTM tags on links that are already posted?
Not for data already collected. Values are stored as they arrived, so retagging changes what future visits record and nothing else. Editing a link’s destination, where the platform allows it, changes what future clicks send, not what past clicks recorded. The honest treatment of the old rows is annotation, not correction.
Should organic and paid social share the same utm_medium?
Separate them. A shared value makes paid and organic performance for one campaign incomparable. Medium also feeds grouping: Google’s default channel group page matches Organic Social on a medium from a short closed list, while Paid Social additionally requires the medium to match its paid pattern. The URL builder page’s own medium example is paid_social and organic_search.
Do I need utm_term for social posts?
No. Google documents utm_term as the paid keyword, so leave it empty for anything that is not paid keyword traffic. Repurposing it as a second content field is the same one parameter, two jobs failure described in collision three.
Does a link shortener strip my UTM parameters?
What reaches the report is what sits on the final destination URL. A shortener or redirect that carries the parameters through preserves them, one that drops or rewrites them does not. Do not assume: follow the link to the landing page and read the query string that arrives.
How long should a UTM convention document be?
One page, because the document only works if the next person reads it during a handoff. It must contain the casing rule, the separator rule, the approved source list, the campaign field order, and the assigned job for utm_content. Anything else belongs in the builder.
Sources
- Google Analytics Help, Collect campaign data with custom URLs, fetched 2026-08-26.
- Google Analytics Help, Default channel group, fetched 2026-08-26.
- Google Analytics Help, Analytics dimensions and metrics, fetched 2026-08-26.
- Google Campaign URL Builder, fetched 2026-08-26.
- Plausible docs, UTM parameters, fetched 2026-08-26.
- Plausible docs, Channels, Sources and Campaigns, fetched 2026-08-26.
