Intermediate

Updated · 8 min read

UTM parameters for email: the convention that still parses a year later

Open the campaign report on any lifecycle programme that has been running for more than a year and you will usually find the same thing: Email, email, and EMAIL as three separate rows; a campaign called welcome_v2 sitting next to Welcome V2 (final); a chunk of traffic labelled direct that everyone knows came from the Tuesday send. None of that is an analytics failure. UTMs are a naming convention wearing a query string, and they decay exactly the way naming conventions decay: one rushed send at a time, with nothing on fire until the report is due. This is the version that holds up.

Justin Williames

By Justin Williames

Founder, Orbit · 10+ years in lifecycle marketing

SharePostPost

What the five parameters are actually for

Start with the mechanism, because it explains most of the failure modes further down. A UTM parameter is nothing more than a key-value pair bolted onto the end of a destination URL — ?utm_source=braze&utm_medium=email. Your email doesn't report anything to anyone. The recipient clicks, the browser carries the parameters to your own site, and your analytics tool reads them off the landing URL and stamps them onto that session. Every UTM you will ever set is a message you are writing to your future self, delivered via the user's address bar.

Five parameters exist. Only three of them earn their place in most lifecycle programmes.

utm_medium— the channel class. Email, SMS, push. This is the single most load-bearing parameter, because analytics tools build their channel groupings primarily off medium. Get medium wrong and the traffic lands in the wrong bucket in every dashboard downstream, including ones you didn't build.

utm_source — where the click came from within that channel. For lifecycle, the useful answer is the sending system: braze, klaviyo, hubspot. It answers "which system sent this" and it stays stable through every campaign rename, which is precisely what you want from the dimension you filter on most often.

utm_campaign — the programme and the specific send. This is where the actual naming work happens, and where the decay starts.

utm_content— which link inside the message was clicked, or which variant the recipient received. Hero button versus footer link. Variant A versus variant B. Genuinely useful, routinely left empty, and the fastest way to answer "did anyone actually click the thing we spent two days designing".

utm_term — originally the paid-search keyword. In lifecycle it has no natural job. Leave it out rather than inventing one; an empty parameter is cleaner than a parameter whose meaning depends on who set it.

The convention: lowercase, one delimiter, no spaces, four dimensions

A UTM convention is a naming convention that happens to live in a URL. It fails for the same reason every naming convention fails: it was slower to follow than to ignore.

Start with formatting. Three rules, none of them negotiable, because analytics tools treat UTM values as case-sensitive strings and will happily report Email and email as two unrelated channels.

Everything lowercase. No exceptions, no proper nouns, no product names in title case. One delimiter scheme, applied consistently. The scheme that reads well and survives scripting is underscores between dimensions, hyphens within a dimension — the same rule the Braze naming guide lands on, and worth keeping identical so a campaign name and its UTM parse the same way. Never a space. A space becomes %20 in some link builders and + in others, and now one campaign is two rows.

The campaign value itself carries programme, send, and date-or-version — no more. winback_60day-lapsed_2026-08 tells you the family, the specific send, and the vintage in forty characters. The test for adding a fifth dimension is the same test as for campaign names: if it isn't a filter you actually apply in a report, it's decoration you will spend a year typing.

Two things that must never go in a UTM: personal data and secrets. UTM values sit in the URL, which means they land in analytics logs, browser history, and the referrer header sent to any third-party script on your landing page. An email address or a user ID in utm_content leaks all three at once. Pass identity through your own authenticated session instead — the personalisation guide covers where that line sits.

Enforcement is the same problem as always. A documented convention loses to a rushed Friday send every time; a builder that produces the canonical string faster than free-text does not. The Orbit UTM Builder takes the four dimensions as dropdowns, lowercases and delimits automatically, and hands back a copyable URL — the point being that the structured path has to be the fast path, or it isn't a path.

Source and medium across email, SMS and push

Multichannel programmes are where most conventions come apart, because the person building the push notification isn't the person who set the email convention six months earlier. Agree the grid once and put it in the builder.

Channelutm_mediumutm_sourceWhy
Lifecycle emailemailSending system (braze, klaviyo)Medium drives channel grouping; source survives campaign renames.
Newsletter / batch emailemailSending systemSame medium — separate it in utm_campaign, not by inventing a second medium.
SMSsmsSending system or aggregatorA distinct medium so SMS traffic doesn't get counted as email in every report.
Push notificationpushApp platform (ios, android)Source distinguishes platforms without a second medium.
In-app messagein-appApp platformGenuinely different surface and different intent — worth its own medium.
Transactional emailemailSending systemutm_campaign carries 'transactional'; don't fork the medium.

The rule underneath the grid: medium is a small, closed vocabulary that almost never changes, and source is the system. Resist the very common temptation to put the campaign name in medium because it makes one particular report easier to read — that report gets easier, and every channel dashboard in the company gets wrong. If your organisation genuinely needs marketing email and transactional email separated at the channel level, do it with a campaign prefix and a custom channel grouping rather than by minting email-transactional as a medium.

What UTMs cannot tell you

UTMs measure one thing: a click that arrived on a page carrying parameters. Everything people ask them to prove beyond that is inference, and four gaps are worth naming out loud before someone builds a business case on top of them.

View-through is invisible.A recipient reads the email, doesn't click, opens the app three hours later and buys. That purchase carries no UTM. It is either unattributed or credited to whatever the user did click, and no amount of tagging discipline recovers it. This is the structural reason lifecycle looks smaller in click-based reporting than it is.

Forwarded email lies confidently. Forward a message and the UTMs go with it. Every click from the new recipient is stamped with the original campaign and looks exactly like a click from your list. Small effect in most programmes, large in B2B, where a single forwarded email can generate a cluster of sessions from people who were never subscribers.

Dark social cuts both ways. Someone copies your link into WhatsApp or a Slack channel: the UTMs survive, and those shares are reported as email clicks. Someone shares it via an app that rewrites or strips the URL: the UTMs vanish, and a real email-driven visit is reported as direct. You cannot see either event, only the distorted totals.

Cross-device breaks the chain. Click on a phone, buy on a laptop. Unless the user is logged in on both and your analytics stitches identity, the click and the conversion sit in two different sessions with two different attribution stories.

The honest framing: UTMs are excellent operational plumbing and a poor causal instrument. They tell you which links get clicked and which sends drive traffic — genuinely useful for creative decisions and broken-link detection. They cannot tell you whether the revenue would have happened anyway. That question needs a holdout, which the incrementality guide covers.

The same tags, read two ways: first-touch and last-touch

A common surprise: two dashboards built on identical UTM data can disagree wildly about how much email is worth. Usually neither is broken — they're answering different questions.

A last-touch read credits the campaign attached to the session in which the conversion happened. Lifecycle does reasonably well here on same-session conversions and badly on everything else, because a user who clicked your email on Monday and came back via search on Thursday hands the credit to search.

A first-touch read credits the campaign that started the user's relationship. Lifecycle almost always looks terrible under first-touch, and correctly so: the first touch belongs to acquisition by definition. Reading lifecycle performance in a first-touch dashboard is a category error, not a bad result — the programme wasn't there for the first touch.

Which model to defend in which room is its own decision, and it depends more on the question being asked than on the data. The attribution models guide maps question to model; the metrics dashboard guide covers what belongs on the tile once you've chosen.

The three failure modes, and how each one is caught

Mixed case fragmenting the report. The commonest and the dullest. One person types Braze, the convention says braze, and the campaign now appears twice with half the numbers each. It surfaces months later, when someone sums a column and gets a total that doesn't match the ESP. The fix is generation, not vigilance: if humans never type the string, humans never capitalise it. Where your analytics tool supports it, add a lowercase transformation on ingestion as a second net — but treat that as a safety net, not the policy, because it does nothing for the tools that don't.

UTMs on internal links, poisoning session attribution. This one does real damage. Tag a link from one page of your own site to another and, in most session-based analytics tools, arriving at a URL with campaign parameters starts a new session attributed to that campaign. The user's original source is discarded mid-visit. A homepage banner tagged utm_campaign=summer-sale will steadily eat credit from every acquisition channel that brought people to the homepage in the first place, and the resulting report looks plausible, which is what makes it dangerous. Rule: UTMs go on links that cross from outside your site to inside it. Internal navigation gets tracked with your own events instead.

The check is a click-through on a real send, not a preview: send a live test to yourself, click each distinct link type on both desktop and mobile, and read the URL in the address bar after every redirect has settled. Then confirm the session appears in your analytics real-time report with the source and medium you expected. Do it once per template, and again any time someone introduces a shortener, a new consent banner, or a deep-link handler. The Orbit Lifecycle Reporting skill folds the link audit into the pre-send gate so it runs on every template rather than on the ones somebody remembered.

The one thing to do on Monday: pull a source-and-medium report for the last ninety days, sort by session count, and read the long tail. The mess at the bottom — the near-duplicates, the mediums that are really campaign names, the direct traffic that spikes on send days — is a complete list of where your convention has already failed. Fix the generation step, and it stops growing from that day.

Read to the end

Scroll to the bottom of the guide — we'll tick it on your reading path automatically.

Frequently asked questions

Do I need UTMs if my ESP already reports clicks?
Yes, and they answer different questions. ESP click reporting tells you a link was clicked. UTMs tell your own analytics what happened after the click — pages viewed, sign-ups started, revenue. Without them, email-driven traffic lands in your site analytics as direct or referral and can't be joined to any campaign. Run both: the ESP for engagement, UTMs for on-site outcomes.
What should utm_source be for email — the ESP or the campaign?
The sending system: braze, klaviyo, hubspot, customerio. It's stable, it survives every campaign rename, and it keeps utm_source answering one question rather than two. The campaign belongs in utm_campaign, which is the parameter designed for it. Teams that put campaign names in source end up unable to filter for 'all lifecycle email' without a wildcard.
Are UTM parameters case-sensitive?
The values are, in effect — most analytics tools treat 'Email' and 'email' as distinct strings, which is how one campaign becomes three rows in a report. Some tools normalise some fields on ingestion, but the behaviour varies by tool and by field, so it isn't something to rely on. Generate every URL lowercase from a builder and the question never comes up.
Should I put UTMs on links inside my own website?
No. In session-based analytics, landing on an internally-linked URL that carries campaign parameters typically starts a fresh session attributed to that campaign, which discards the user's real source mid-visit. Tag only links that cross from outside your site to inside it. For internal navigation, use your analytics tool's own event tracking.
Why does email traffic show up as 'direct' in my analytics?
Almost always a stripped parameter rather than a missing tag. Click-tracking wrappers, shorteners, consent gateways, login redirects, and canonical-URL redirects on your own server can all drop the query string, and the visit then arrives unlabelled. Some email clients and in-app browsers also open links in contexts that break the handoff. Diagnose it by clicking a real send end-to-end and reading the address bar after every redirect resolves.
Can UTMs prove my email programme produced the revenue?
No — they tell you which clicks preceded a conversion, which is a different claim. They can't see view-through conversions, they can't tell a forwarded click from a subscriber click, and they can't say whether the revenue would have arrived anyway. For that you need a holdout: withhold the programme from a random group and compare. UTMs are the plumbing; incrementality is the evidence.
How many UTM dimensions should a campaign name carry?
Usually three — programme family, specific send, and a date or version. Add a fourth only when it corresponds to a filter you genuinely apply in reports. Conventions die from length — if the canonical string takes longer to assemble than free-text does, people will type free-text at 4:47 on a Friday, and the convention was never really in force.

This guide is backed by an Orbit skill

Related guides

Browse all
Experimentation8 min

First-party email analytics: the minimum schema, and the discipline that keeps it honest

You can measure a site and the traffic your sends drive into it with three Postgres tables and no third-party pixel. What nobody warns you about is that first-party analytics fails silently — no vendor is going to tell you the column is empty. Two bugs from our own tables, and the rules we now work to.

Experimentation9 min

Churn cohort analysis: the one chart that tells you if retention is actually improving

A cohort retention curve is the single most useful analytical artifact in lifecycle marketing. It isolates real program impact from the compounding noise that every other metric hides, and it's the one view that survives every limitation of the simpler numbers. Here's how to build one and how to read it without kidding yourself.

Experimentation10 min

Attribution models for lifecycle: which one to defend in which room

Attribution debates are half epistemology, half politics. Last-touch is wrong but defensible. Multi-touch is more accurate but less defensible. Incrementality is the only one that answers the causal question — and it's the slowest. Here's which model to use for which question, and why.

Experimentation9 min

Holdout group design: the incrementality tool most lifecycle programs skip

Without a holdout, lifecycle ROI is attribution-model guesswork with a spreadsheet. With one, you get a defensible number you can actually put in front of finance. Here's how to size, run, and read a holdout — and the three mistakes that quietly invalidate the result.

Experimentation8 min

Measuring AI personalisation lift honestly

Every vendor case study shows AI personalisation moving the numbers. Most internal post-mortems show the lift evaporating once a proper holdout is in place. The gap between the two is the measurement methodology. Here's the framework for proving — to yourself, your CFO, and the auditor — whether AI personalisation is actually earning its place.

Strategy8 min

The lifecycle metrics dashboard: what to track, what to ignore

Most lifecycle dashboards show forty metrics and answer none of the questions the team actually has. A good one shows eight, and each one tells you what to do next. Here's the eight-metric dashboard that runs a real lifecycle program.

Found this useful? Share it with your team.

SharePostPost

You finished the playbook. Get the next.

New guides and product updates land in your inbox when they ship. One list, real lifecycle work, unsubscribe the second it stops being useful.

Guides and Orbit updates only. No sequences, no selling your address.

Use this in Claude

Claude can run this playbook for you.

Orbit is a free extension for Claude Desktop — no licence key, no card — that runs the lifecycle work you just read about. You've read how it works; Orbit hands Claude the same playbook as a skill it can execute: discovery, build, QA, push, on your own ESP.

Download Orbit — free