Skip to content
LinkProfit

UTM Parameters: The Complete Guide

LinkProfit Team11 min read
  • utm
  • analytics
  • marketing
On this page

Every analytics report that shows a paid campaign sitting in the "Direct / (none)" bucket is a tagging failure, and that failure almost always happened weeks earlier, in a link somebody built by hand. UTM parameters are the oldest and most portable way to tell an analytics system where a visitor came from, and one of the easiest things in marketing to do inconsistently. This guide covers what the five standard parameters mean, when the less common ones earn their place, how to name values so a team of six produces one clean dataset instead of six dirty ones, the mistakes that silently destroy attribution, and how short links solve the practical problem that a properly tagged URL is far too long to distribute.

What UTM Parameters Actually Are

A UTM parameter is nothing more than a key-value pair appended to the query string of a destination URL. The acronym comes from the Urchin Tracking Module, named after Urchin Software, the analytics company Google acquired in 2005 and rebuilt into Google Analytics. The convention outlived its origin: virtually every analytics platform reads the same parameter names, from the Google stack to Adobe, Matomo, Plausible, Amplitude, and Mixpanel. That universality is the whole value — a tagged link behaves identically on a site you own and on a client's.

The mechanism is deliberately simple. Someone clicks a tagged link, the browser requests the destination with the query string intact, and the analytics script reads the parameters as the page loads. The values attach to the session and, depending on the attribution model, to any conversion that follows. Nothing is verified — a UTM parameter is a self-reported label, which is exactly why naming discipline matters so much.

The five standard parameters

| Parameter | Status | The question it answers | Example values | | --- | --- | --- | --- | | utm_source | Required | Which specific property, publication, or vendor sent this visitor? | newsletter, linkedin, partner_acme, packaging_box | | utm_medium | Required | What category of channel was it? | email, sms, social, cpc, qr, affiliate | | utm_campaign | Required | Which initiative or promotion does this belong to? | spring_sale_2026, q3_webinar_series | | utm_term | Optional | Which paid keyword or audience triggered the placement? | link_shortener_api, retargeting_30d | | utm_content | Optional | Which creative, placement, or variant within the campaign? | hero_button, variant_b, back_panel |

The distinction people get wrong most often is source versus medium. Source is the named thing that sent the traffic; medium is the kind of thing it is. LinkedIn is a source, social is a medium; your Tuesday newsletter is a source, email is its medium. If you can swap the two values and the sentence still reads plausibly, one of them is wrong.

Term versus content matters less but is worth settling once. Term exists for paid search keywords and is often auto-populated by ad platforms; content covers everything that distinguishes one placement from another inside the same campaign. When in doubt, use utm_content — most reporting interfaces expose it by default.

Where the values actually end up

Understanding the lifecycle prevents most of the mistakes below. The parameters describe an arrival. An analytics tool sees them, decides this visit came from outside, and writes source, medium, and campaign onto the session. Then they are done — they do not persist across pages, and if the visitor returns tomorrow by another route, new values replace the old ones under whatever attribution rules the tool applies.

They are also public. They sit in the address bar, get copied when someone shares a URL, land in server logs and browser history, and can be indexed. Never put anything sensitive in them: no email addresses, no customer identifiers, no internal revenue figures encoded into a campaign name.

utm_id and the Non-Standard Parameters

Beyond the five, there is a small set of parameters worth knowing.

utm_id carries a campaign identifier rather than a readable name. Its purpose is joining: when you import cost data from an ad platform, it is the key matching spend rows to traffic rows. Skip it if you are not importing cost data; if you are, it must match the exported identifier exactly.

Google Analytics 4 also recognizes utm_source_platform, utm_creative_format, and utm_marketing_tactic, which describe the buying mechanism rather than the placement — which platform bought the impression, what format the creative was, whether the tactic was prospecting or remarketing. Useful for large paid programs, noise for everyone else.

Custom parameters are legitimate too: a partner_id or placement value your own backend reads is fine. Two rules. Do not prefix them with utm_, or you will eventually collide with something the vendor adds later. And expect them to be invisible to standard reporting unless you configure the tool to capture them.

Naming Conventions That Survive a Team

Tagging discipline fails at scale, not at the individual link. One person is consistent by accident. Six people produce facebook, Facebook, FB, fb-ads, facebook_ads, and meta — six rows that should have been one, with the campaign's performance split six ways.

Case

Pick lowercase and enforce it. The reason is not aesthetic: analytics platforms differ in whether they normalize case, and they differ per field. You cannot build a policy on behavior that varies by tool, so remove the variable — lowercase always, applied by the builder rather than by memory.

Controlled vocabularies

utm_medium should be a closed list, decided once and written down. A workable default is email, sms, social, paid_social, cpc, display, affiliate, qr, referral, push, and print. A closed list is what makes channel grouping meaningful.

utm_source cannot be fully closed, since new publications and partners appear constantly, but it should be a registry rather than a free-text field: keep the list where the team can see it and add to it deliberately.

utm_campaign needs a format rather than a vocabulary. Something like subject_detail_yyyymm produces pricing_launch_202608 and sorts sensibly. Whatever you pick, someone reading the report six months later should be able to tell what the campaign was without asking.

Separators and characters

Use underscores or hyphens inside values, never spaces. A space becomes %20 or + depending on the encoding, and you end up with spring+sale and spring%20sale as separate rows. Pick one separator and apply it everywhere; underscores are the more common convention for UTM values.

Avoid punctuation beyond the separator. Ampersands, question marks, hash symbols, and percent signs inside a value either terminate the parameter early or require encoding that tools handle inconsistently. Stick to lowercase letters, digits, and your one separator.

The Mistakes That Break Attribution

This is the most damaging mistake and the least obvious, because nothing appears broken. Someone tags the navigation link between the homepage and the pricing page to count clicks. The analytics tool sees campaign parameters, concludes a new visit arrived from outside, ends the current session, and starts one whose source is your own site. The paid campaign that actually brought the visitor loses the conversion, and your homepage is credited with revenue it did not generate.

Internal navigation is measured with events or click tracking, not campaign parameters — that is exactly what event tracking exists for.

Duplicating the channel across parameters

Setting both source and medium to facebook, or both to sms, wastes a field: the report can no longer roll individual sources up into a channel, which is the entire purpose of medium. Source names the property, medium names the category, and they should never be the same string.

Losing parameters in redirects

Query strings do not survive redirects automatically — the redirect has to forward them deliberately. A destination that redirects HTTP to HTTPS, adds or removes a trailing slash, or moves an old path to a new one can silently drop everything after the question mark. The traffic still arrives and the campaign still vanishes into direct.

Two habits prevent this. Test the full chain before launch by reading the final address bar, not the first response. And point links at the canonical destination rather than at a URL you know redirects. Where the destination is not yours, verify its redirect preserves the query string before spending money on traffic through it.

Tagging the wrong layer

When a short link sits in front of a destination, the parameters belong on the destination. Tagging the short link adds visible clutter to the thing you shortened to keep clean, and creates two places where the campaign name can drift out of sync.

Tagging transactional mail

Order confirmations, password resets, and receipts are not campaigns. Tagging them fills campaign reports with existing customers doing routine things, distorting every channel comparison afterwards. Tag marketing sends; leave transactional mail alone.

Templates by Channel

These are working starting points. Substitute your own campaign naming format and keep the medium values from your controlled list.

Email, where the source names the specific send or list and content distinguishes the placement inside the message:

https://example.com/pricing?utm_source=weekly_digest&utm_medium=email&utm_campaign=pricing_launch_202608&utm_content=header_cta

SMS, where the source names the audience segment rather than repeating the medium. Note that this tagged URL is the redirect destination and never appears in the message body itself, for reasons covered in our guide to cutting SMS costs with short links:

https://example.com/sale?utm_source=vip_list&utm_medium=sms&utm_campaign=flash_sale_202608&utm_content=segment_a

Organic social, where content identifies the creative so you can compare formats:

https://example.com/blog/deep-links?utm_source=linkedin&utm_medium=social&utm_campaign=q3_thought_leadership&utm_content=carousel_v2

Paid social, distinguished from organic by medium, with term carrying the audience:

https://example.com/white-label?utm_source=linkedin&utm_medium=paid_social&utm_campaign=wl_prospecting_202608&utm_term=agency_owners&utm_content=video_15s

QR codes, where the source names the physical surface and content names the exact placement on it, so you can tell the back panel from the shelf talker:

https://example.com/register?utm_source=packaging_box&utm_medium=qr&utm_campaign=summer_promo_2026&utm_content=back_panel

| Channel | Typical source | Medium | What to put in content | | --- | --- | --- | --- | | Newsletter | Name of the send or list | email | Position in the message: header, body, footer | | SMS broadcast | Audience segment or list | sms | Segment or variant identifier | | Organic social | Platform name | social | Creative format or post variant | | Paid social | Platform name | paid_social | Ad creative identifier | | Paid search | Engine name | cpc | Ad variant, with keyword in utm_term | | Printed material | The physical surface | qr or print | Exact placement on the surface | | Partner placement | Partner name | affiliate or referral | Placement on the partner's site |

Look at the paid social example above. It is 148 characters, and that is not unusual — five parameters with descriptive values routinely produce URLs between 150 and 250 characters. Fine in an email button, where the URL hides behind anchor text; impossible almost everywhere else. It will not fit in an SMS without consuming extra billed segments, cannot be printed under a QR code, cannot be read aloud, and pasted into a social post it looks like something a spam filter should catch.

Hiding the query string

A short link separates what people see from what the analytics tool receives. You build the tagged destination URL, shorten it, and distribute go.yourbrand.com/summer. The click hits the redirector, which responds with the full tagged URL, and the browser follows it to a landing page that receives every parameter intact. The recipient sees a clean branded link; your reporting sees complete tagging.

Appending parameters without overwriting

The subtler capability is merging. Clicks often arrive at a short link carrying their own query parameters — a partner appended a referral identifier, a platform added a click ID, a template passed through a segment value. A naive redirector either ignores these or clobbers the destination's parameters with them.

Correct behavior is a defined merge: parse the destination's query string, parse the incoming one, combine them under an explicit precedence rule, and emit the result. Values set deliberately on the destination win over values arriving at click time, so nothing you configured can be overwritten by an inbound parameter you did not anticipate, and anything that does not collide is carried through rather than discarded.

The same machinery supports workspace-level UTM defaults. If every link built for a client should carry utm_source=partner_acme, apply it at the redirector instead of typing it into every URL — which removes the largest single cause of inconsistency, humans retyping the same string a hundred times.

Measurement before the click lands

One more benefit is easy to miss. When links pass through a redirector you control, campaign parameters become click-side data rather than session-side data. The redirector records timestamp, approximate location, device, operating system, and referrer for every click, alongside the UTM values on that link. You can compare campaigns in the analytics dashboard even where you do not control the destination page or cannot install a script — a client's site, an app store listing, a partner's landing page. Our guide to tracking link clicks covers where click-side and session-side numbers legitimately differ.

Auditing What You Already Have

Start with the reports rather than the links. Open your channel report and look for the symptoms: near-duplicate source values, a medium column containing platform names, campaign names in three formats, and an unexpectedly large direct bucket during a period when you were spending. Each points at a specific upstream failure.

Then fix the generation step, because auditing links one at a time is a treadmill. A builder with saved presets removes the opportunity for drift — medium comes from a dropdown, case is normalized automatically, campaign format is enforced rather than remembered. Our free UTM builder does this in the browser and keeps a history, so the next person tagging a LinkedIn post uses the same values as the last one.

For links already in the wild, check the redirect chain before assuming the tagging is wrong. Paste the link into a link checker and read every hop. If parameters are present at the start and missing at the end, the problem is a redirect, and no amount of rebuilding URLs will fix it.

Getting the Basics Right

UTM tagging rewards boring consistency more than cleverness. Three required parameters on every external link, a closed list of mediums, lowercase everywhere, a campaign format written down where the team can see it, nothing sensitive in the values. Add utm_content when you have a real question about placement and utm_id when you are importing cost data. Leave internal links alone.

Then hide the result behind a short link on your own domain, so the discipline that keeps reporting clean does not force a 200-character URL into an SMS or onto a printed page. Build a tagged URL in the UTM builder, shorten it with the URL shortener, and check the first report against what you expected — that one comparison will teach you more about your tagging than another week of documentation.

Questions people ask

Which UTM parameters are actually required?

Three: utm_source, utm_medium, and utm_campaign. Most analytics tools will accept a URL with only one of them, but the resulting rows are unusable — a source with no medium cannot be grouped into a channel, and a medium with no campaign cannot be tied to spend. Treat those three as mandatory on every external link, and add utm_content and utm_term only when you have a specific question they answer.

Should UTM parameters be lowercase?

Yes, and you should enforce it mechanically rather than by convention. Some analytics platforms normalize campaign values, some compare them case-sensitively, and some do one for source and the other for medium. If you cannot rely on the tool to normalize, the only safe policy is lowercase everywhere, applied by whatever builder or template your team uses so nobody has to remember it.

Do UTM parameters hurt SEO or create duplicate content?

Not if your site handles them correctly, and you should verify that it does. Query parameters create distinct URLs, so a page reachable with dozens of tagging variants can be crawled dozens of times. The fix is a self-referencing canonical tag on the landing page that points at the clean URL without parameters. With that in place, tagged URLs consolidate to the canonical and there is no duplicate-content problem.

Why do my campaigns show up as direct traffic?

Usually one of four causes: a redirect somewhere in the chain dropped the query string, the link was pasted without tags into a channel you did not control, the destination used an HTTP-to-HTTPS or trailing-slash redirect that discarded parameters, or the click landed in an in-app browser that opened a fresh session. The redirect chain is the most common and the easiest to test — follow the link end to end and look at the final address bar.

Can I put UTM parameters on internal links?

You should not. Analytics tools read campaign parameters as a signal that a new session has arrived from outside, so tagging an internal button can restart the session and overwrite the real acquisition source with your own homepage. Measure internal navigation with events or click tracking instead, which is what those systems are designed for.

How do short links and UTM parameters work together?

The short link is what people see and the tagged URL is what they land on. You tag the destination, shorten it, and distribute the short version, so the recipient never sees a hundred characters of query string. A good redirector also merges parameters at click time: values already on the destination are preserved, and anything the redirector is configured to add gets appended only where it does not overwrite an existing key.