UTM Campaign URL Builder

Links that say where the click came from.

  • Correct URL encoding
  • Bulk link sheet
  • Naming rules enforced
A row of brown paper parcels on a shelf, each with several blank coloured tags tied on with string, in warm light.

The guide

A campaign link is a small promise, and consistency is what keeps it

Five short labels in a web address can say where a click came from, but only if every link spells them the same way and encodes them correctly.

  • utm_source the one label the reference table calls required
  • 146 characters the worked example, with four labels added
  • %2B how a real plus sign has to be written in a value
  • 2 bytes what an accented e becomes before it is percent-encoded
Read the full guide Fold the guide 7 min · 14 sources

A link in a newsletter and the same link on a printed flyer open the same page. The page cannot tell them apart unless the link itself says which is which. That is all a campaign parameter is: a short label, written into the address, that the destination can read when the visit arrives. The idea is modest and it works. Most of what goes wrong with it is not strategy at all but spelling and punctuation.

Where the five labels came from

The letters stand for Urchin Tracking Module. Urchin was an analytics program, and the encyclopedia entry on the subject says its parameters were carried over by the product that succeeded it and became a habit across the trade. Nobody standardised them. No standards body owns the names, and no specification says what a program must do when it meets one. They are a convention that spread because it was convenient.

That entry lists five names, usable in any order. The first, utm_source, identifies which site or sender sent the visit, and is the only one its table calls required. The second, utm_medium, names the type of link, such as email or paid advertising. The third, utm_campaign, names the promotion. The fourth, utm_term, records search terms. The fifth, utm_content, says what exactly was clicked, which makes it the usual place to tell two versions of one message apart.

Because the names are a habit and not a rule, it is worth checking that more than one reader honours them. They do. The default configuration of one open-source analytics program lists the campaign, source and medium names among the parameters it looks for, and the term name among its keyword parameters. The published documentation of another open-source project lists all five. What each program then does with the values is its own business, described in its own documentation, and can change.

Consistency beats cleverness

Here is the uncomfortable part. A label is text, and text that differs in one capital letter is different text. The documentation of one of those open-source projects, read on 10 October 2026, says plainly that these tags are case-sensitive and that inconsistent tagging can leave traffic duplicated or put in the wrong category. Write Newsletter on Monday and newsletter on Friday and you may have invented two sources.

The same goes for separators. A campaign called autumn sale, another called autumn-sale and a third called autumn_sale are three campaigns to anything that compares strings exactly. None of the three is wrong. The mistake is having all of them.

So the valuable thing is not a clever taxonomy. It is a short written convention that everyone on a team follows without thinking: lower case or not, hyphen or underscore, which characters are allowed, which labels are required, and the handful of sources and mediums that are actually in use. A page of rules that fits on one sheet of paper is worth more than a spreadsheet of forty carefully reasoned channel names that three people interpret in three ways. Decide once, write it down, and let a checker enforce it so that nobody has to remember.

A convention also has to say what a label is for. Source and medium answer different questions, who sent the visit and by what kind of link, and swapping them halves the usefulness of both. Content is for the detail that changes between two otherwise identical links. If a team cannot say in one sentence what goes in each slot, the links will drift.

What the address does to your words, and where they go

A web address is not free text. The generic syntax for addresses names a small set of characters as unreserved: letters, digits, the hyphen, the period, the underscore and the tilde. Those can appear anywhere as themselves. Nearly everything else either has a job, like the ampersand that separates one parameter from the next and the equals sign that separates a name from its value, or is not allowed in raw form at all.

Anything outside the safe set is percent-encoded: turned into bytes, with each byte written as a percent sign and two hexadecimal digits. The bytes come from UTF-8. A plain letter is one byte, but an accented e is 2 bytes, so a value such as the word for a coffee house in French ends in %C3%A9. An emoji takes four. The address gets longer, and it stays correct.

Spaces have two spellings, and this is where many hand-built links go wrong. The older form rule, still used when a browser reads a query string as form data, treats a plus sign as a space. The URL standard’s form parser does exactly that: it replaces every plus with a space before it decodes anything else. Browser documentation notes that one built-in interface writes a space as a plus while another writes it as %20. Both read back as a space. Pick one and stay with it.

The consequence is easy to miss. If a plus means a space, then a real plus sign cannot be written as itself. A value like a+b, left alone, arrives as a b. It has to be written %2B. The percent sign has the same problem one level up: a literal percent must be written %25, or the reader will try to decode whatever follows it.

That leads to the commonest fault of all, encoding twice. A value that already says %20 is run through an encoder again, the percent sign becomes %25, and the label arrives as the visible text %20 in place of a space. The cure is a rule about direction. What a person types is always plain text and is encoded exactly once. What is already in an address is left byte for byte as it was.

An address has an order: the scheme, the host, the path, then a question mark and the query, then a hash sign and the fragment. Campaign labels belong in the query. They must come before the hash, and this is not a matter of taste.

The fragment never leaves the browser. The syntax specification says it is handled solely by the user agent, and the specification for the web’s transfer protocol says the address a request is sent to excludes it. A label written after the hash is invisible to the server. It may still be visible to a script running in the page, which is why such mistakes can go unnoticed for months in one report and not another.

A reproducible case shows the whole thing. Take the address https://www.example.org/autumn-sale?ref=home#prices, on a host name that the internet’s standards reserve for documentation. Add a source of newsletter, a medium of email, a campaign of autumn-sale-2026 and a content label of header-button. The finished link keeps ref=home, places the four new labels after it, joined by ampersands, and ends with the fragment, still last. It is 146 characters long. Put the same values in the builder above and count.

Two smaller traps sit at the front of the address. A link typed without its scheme is not a link: a browser’s parser refuses it, and a page treats it as a path on its own site. And a host name with letters outside ASCII is converted by the browser to a compatible ASCII form by a published Unicode procedure, so the address you typed and the one the browser shows may differ while meaning the same place.

An address is one of the least private things on the web. The transfer protocol’s own security section says addresses are meant to be shared, not secured: they are shown on screens, kept in bookmark lists, and logged by servers and proxies, so it is unwise to put anything personally identifiable in one. A security reference lists the same leaks from the other side, naming the referring-page header, web logs and browser history.

For campaign links the rule is simple. No email address, no phone number, no customer name, no account number, in any label, ever. It is tempting to tag a mailing with the recipient so that clicks can be matched to people. Use an opaque code that means nothing outside your own records, or do not do it. A pattern checker can catch text shaped like an email address or a telephone number. It cannot recognise a name, so the convention has to say it.

Sheets of links carry a risk of their own. The common format for them is simple: fields separated by commas, quoted when they contain a comma, a line break or a quotation mark, with the quotation mark doubled. A spreadsheet, though, may run a cell that begins with an equals sign, a plus, a minus or an at sign as a formula. One documented defence is to put a single quote in front of such a cell so it is shown as text.

A label records what the link said, not what happened. If someone forwards the newsletter, or copies the address into a chat, the link still says newsletter. Anyone can type any value. A link that is never tagged says nothing, and software that strips parameters says nothing either. The numbers that come out the far end are a count of labelled arrivals, shaped by every one of those gaps.

Nor does a correct link promise any result. It does not bring a visit, and it cannot say why someone clicked. What it can do is narrower and worth having: when a visit does arrive, the label on it is exactly the one you meant, spelled the way you always spell it. That is the whole promise. Kept across a few hundred links, it is the difference between a report you can read and one you have to clean first.

Sources

Every source consulted for this guide. Links checked October 10, 2026.

  1. URL Standard WHATWG
  2. RFC 3986: Uniform Resource Identifier (URI): Generic Syntax IETF, RFC Editor
  3. RFC 9110: HTTP Semantics IETF, RFC Editor
  4. RFC 3629: UTF-8, a transformation format of ISO 10646 IETF, RFC Editor
  5. RFC 4180: Common Format and MIME Type for Comma-Separated Values (CSV) Files IETF, RFC Editor
  6. RFC 2606: Reserved Top Level DNS Names IETF, RFC Editor
  7. RFC 6761: Special-Use Domain Names IETF, RFC Editor
  8. UTM parameters Wikipedia
  9. URLSearchParams MDN Web Docs, Mozilla
  10. UTS #46: Unicode IDNA Compatibility Processing Unicode Consortium
  11. Information exposure through query strings in URL OWASP Foundation
  12. CSV Injection OWASP Foundation
  13. Traffic sources, referrers and UTM campaigns (docs/top-referrers.md) plausible/docs repository on GitHub
  14. config/global.ini.php, default configuration matomo-org/matomo repository on GitHub