webtracking.org
tools

UTM builder with governance built in: validate campaign URLs, not just generate them

Build, bulk-generate, and validate UTM campaign URLs against an open standard — controlled medium vocabulary, campaign-name pattern, PII checks, CSV export.

last verified 2026-07-18

Every channel report you will ever read is downstream of a decision someone made while pasting a link: what to type into utm_source and utm_medium. When those values are freehand — Email one week, newsletter the next, E-Mail%20Promo from the agency — the damage never shows up as an error. It shows up months later as fragmented channel rows, “Unassigned” traffic, and attribution arguments nobody can settle, because the raw data cannot be retroactively fixed.

Most UTM builders don’t help with this. They concatenate whatever you type into a query string and call it done. The UTM & Campaign URL Governance tool on webtracking.org does the opposite: it treats tagging as a governance problem. Every URL it builds or checks is validated against the open Campaign URL / UTM Standard (v1.0.0), every pass/fail cites the exact rule it enforces, and the allow-lists it validates against are yours to edit, export, and share with your team. It runs entirely in your browser — nothing you paste is sent anywhere.

It is built for the people who own tagging discipline: measurement managers writing the taxonomy, marketing managers tagging the links, and agencies who need to prove their deliverables conform to a client’s standard before launch.

What it does

The tool has four tabs, all driven by the same validation engine:

  • Build one URL. One landing page, five parameters (utm_source, utm_medium, utm_campaign, utm_content, utm_term). Each field is checked live as you type; failures name the rule they break and the clause of the standard behind it. A status chip flips between “passes the standard” and a violation count, and the copy button gives you the assembled URL.
  • Bulk generate. Paste landing-page URLs one per line, define the campaign parameters once, and get a table of tagged URLs — each one validated. Export the whole table as CSV or JSON.
  • Validate existing. Paste already-tagged URLs from a spreadsheet, an email tool, or an ad platform export, and get a violation report per URL, per rule. Also exports to CSV and JSON.
  • Taxonomy. The allow-lists and pattern every other tab validates against: allowed utm_source values, the allowed utm_medium vocabulary, a campaign-name regular expression, and which parameters are required. Defaults come from the standard; you replace the starter source list with your organisation’s own, save it, and export it as JSON to check into a repo.

Source and medium fields in the Build and Bulk tabs autocomplete from your taxonomy, so the compliant value is always the easy one to pick.

How it works

The validation and generation logic lives in a standalone engine (utm.js) with no dependencies and no DOM access — it runs in the browser and in Node, so the same rules a marketer sees in the UI can run in a CI check.

Eleven named rules. Every violation the tool emits carries a rule ID that maps to a clause of the standard: url-parse, required, lowercase, whitespace, charset, source-allowlist, medium-vocab, campaign-pattern, term-scope, pii, and duplicate. That mapping is why the tool can cite chapter and verse instead of printing a vague “invalid value.”

Per-value checks. Each non-empty parameter value is tested for whitespace (including a literal %20), uppercase characters, and — only if those two pass — the token character set ^[a-z0-9]+(?:-[a-z0-9]+)*$: lowercase, hyphen-delimited, nothing else. Every value is also run through an email-address pattern; anything that looks like an email is flagged as PII, which the standard prohibits in any parameter.

Taxonomy-driven checks. utm_source must appear in your allow-list (an empty list disables that check). utm_medium must be one of the controlled vocabulary values — the standard’s v1 vocabulary ships as the default: organic, paid-search, paid-social, organic-social, display, email, affiliate, referral, sms, push, partner, sponsorship. Values outside it are validation errors, not new channels. utm_campaign must match your campaign pattern; the default regex ^\d{4}-q[1-4]-[a-z0-9]+(?:-[a-z0-9]+)*$ encodes the standard’s {yyyy}-{quarter}-{initiative}-{geo?} convention, so 2026-q3-launch and 2026-q3-launch-us pass and Summer%20Sale does not.

Cross-parameter checks. utm_source, utm_medium, and utm_campaign are required by default (configurable in the Taxonomy tab). utm_term set while utm_medium is anything other than paid-search triggers the term-scope rule, because the standard reserves utm_term for paid-search keywords.

URL parsing and assembly. The validator parses tagged URLs itself, without touching the network: it strips the #fragment, splits the query string, percent-decodes each key and value (treating + as a space, and falling back to the raw text if decoding fails), and records any utm_* parameter that appears twice as a duplicate violation. The builder does the inverse: it preserves your existing non-UTM query parameters and fragment, replaces any existing utm_* parameters rather than stacking a second copy, percent-encodes values, and skips empty parameters.

Storage and export. Your taxonomy is saved to a single localStorage key in your browser — no account, no server. Saving or importing a taxonomy refuses a campaign pattern that isn’t a valid regular expression, so you can’t persist a rule that would fail every campaign name afterwards. CSV exports follow RFC 4180 quoting, and any cell starting with =, +, -, or @ is prefixed so a hostile pasted value can’t execute as a spreadsheet formula when you open the file in Excel or Sheets.

How to use it

  1. Open the tool and start in the Taxonomy tab. Replace the starter utm_source list with your organisation’s, adjust the campaign pattern and required parameters if yours differ, and hit Save taxonomy. Use Export JSON to share the file with your team or check it into a repo; teammates load it with Import JSON.
  2. For a single link, use Build one URL: enter the landing page and parameters, watch each field’s live check, and press Copy URL once the chip reads “passes the standard.” The Sample button fills in a working example if you want to see the checks fire.
  3. For a campaign across many pages, use Bulk generate: one landing page per line, campaign defined once, then Generate tagged URLs (or Ctrl/Cmd+Enter in the textarea). Fix anything flagged in the “standard check” column, then Export CSV for your email or ads platform.
  4. To audit links you didn’t build, paste them into Validate existing and press Validate. Each row names the parameter, the rule, and the clause of the standard it violates — export the report as CSV to send back to whoever built the links.

Limitations

  • It validates form, not truth. The tool can verify that utm_medium=email is in the vocabulary; it cannot know whether the link actually goes in an email. Semantic honesty is still on you.
  • PII detection is a heuristic. The pii rule catches values that look like email addresses. Names, user IDs, and other identifiers in parameter values will pass — the standard still prohibits them.
  • Fragments are ignored during validation. UTM parameters hidden after a # are not parsed, which matches how analytics tools read landing pages, but means the validator won’t flag them.
  • The taxonomy lives in one browser. localStorage doesn’t sync across devices or teammates; the JSON export/import flow is the sharing mechanism. If localStorage is unavailable, edits apply for the session but won’t survive a reload.
  • Client-side only. Nothing is fetched or crawled; the tool never visits the URLs you paste, so it can’t detect redirects that strip parameters or pages that don’t exist.

FAQ

How is this different from Google’s Campaign URL Builder? Google’s builder assembles a query string from whatever you type. This tool validates every value against a versioned standard and your own allow-lists, reports named rule violations, handles bulk generation with CSV/JSON export, and lets you audit URLs built elsewhere.

Why is utm_medium=cpc flagged as a violation? The standard’s controlled medium vocabulary uses paid-search, and any value outside the vocabulary is an error by design — one canonical spelling per channel is the whole point. If your organisation standardises on cpc instead, edit the medium list in the Taxonomy tab; the check follows your list.

Will it break links that already have query parameters? No. Both the single and bulk builders preserve existing non-UTM parameters and #fragments untouched. Existing utm_* parameters are replaced with your new values rather than duplicated.

Is anything I paste uploaded anywhere? No. All parsing, validation, and generation run in your browser; the page works offline, and the taxonomy is stored only in your browser’s localStorage.

Can I enforce these rules automatically in CI? The engine is dependency-free and runs in Node as well as the browser, so the same checks the UI performs can be scripted against a list of URLs — with your exported taxonomy JSON as the config.