flowsk.com
Feature

UTM taxonomy — one canonical vocabulary your team cannot drift from

Analytics groups on the exact string, so "Facebook" and "facebook" are two channels. Flowsk stores your canonical vocabulary, flags drift as it happens and builds compliant links.

Aug 4, 2026· 3 min read ·Features
Quick answer

one canonical value per channel · lowercase · hyphens · never empty

Every analytics tool groups on the exact string. Facebook and facebook are two sources. spring-sale and Spring Sale are two campaigns. Nothing errors — your numbers just split in half and every row looks like it underperformed.

A convention nobody can validate is a convention nobody follows. The fix is a stored vocabulary plus a checker that runs before launch.

Attribution failures usually get blamed on browsers. A large share of them are simply spelling.

The failure, concretely

Three people launch campaigns in the same week:

?utm_source=facebook&utm_medium=cpc&utm_campaign=spring-sale
?utm_source=Facebook&utm_medium=paid-social&utm_campaign=Spring Sale
?utm_source=fb&utm_medium=ppc&utm_campaign=spring-sale

One campaign. Three rows. Each showing a third of the conversions, a third of the revenue, and a CPA that looks three times worse than reality.

Nobody gets an error. Nobody gets a warning. The report simply becomes wrong in a way that looks like underperformance — so the natural reaction is to cut spend on a campaign that was working fine.

What Flowsk does about it

A stored canonical vocabulary. You declare, once, that the source is facebook, the medium is cpc, and the campaign naming pattern is initiative-audience-date. It lives in the workspace, not in someone’s Notion page.

Drift detection on arrival. When traffic lands with Facebook, fb or facebook.com, it is flagged against the canonical value immediately — not at the end of the month when someone notices the report looks odd.

Normalisation on read. Reports group by the canonical value while the raw strings stay on the events. Nothing is rewritten, so you can always see what actually arrived, and historical traffic regroups the moment you declare a canonical value.

A link builder. Building the URL from the vocabulary is the only reliable way to keep it consistent, because it removes the step where a human types.

The vocabulary that survives a marketing team

Parameter Rule Good Bad
utm_source The platform. One canonical value each. facebook FB, Facebook, facebook.com
utm_medium The delivery mechanism, from a closed list. cpc paid-social, PPC, paid_search
utm_campaign The initiative. Lowercase, hyphenated, dated. spring-sale-2026 Spring Sale, spring sale
utm_content The creative or placement variant. video-a Video A (final v2)
utm_term Keyword, search only. running-shoes Running Shoes
utm_id Stable platform campaign id, if available. 23851234567 (left empty)

The closed list for utm_medium matters more than any other rule. Source can be long-tailed — you will always add new platforms. Medium should be a set of six or seven values that never grows, because medium is what you group by when you want to answer “how much of our revenue comes from paid?”

Why this is a product feature and not a document

Every team already has a UTM convention document. Almost none of them have clean UTM data.

The gap is enforcement. A convention that lives in a document is checked by memory, at 6pm, by someone launching a campaign in a hurry. A convention that lives in the tool is checked by the tool, every time, for free.

Start with the free validator — paste your last month of campaign URLs and see how much drift is already in your reports. The paid workspace is the same check, running continuously, plus the builder that stops it happening again.

Frequently asked questions

Why does casing matter so much?

Because grouping is a string comparison. If half your team writes Facebook and half writes facebook, your channel report shows two rows with half the conversions each — and both look like they underperformed against the same benchmark.

What is the difference between source and medium?

Source is where the traffic came from (facebook, google, newsletter). Medium is how it got there (cpc, email, social, referral). The most common mistake is putting the platform in both, which makes medium useless for grouping.

Can I fix historical data?

Flowsk normalises on read against your canonical vocabulary, so past traffic regroups once you declare the canonical value. The underlying events keep their original strings — nothing is rewritten.

What about ad platform macros?

Use them for utm_content and utm_id, where the platform substitutes a stable identifier. Keep utm_source, utm_medium and utm_campaign hand-controlled and validated — macros are exactly where uncontrolled vocabulary enters.

Do UTMs survive redirects?

Not always. Link shorteners, 301 chains and some consent flows drop query parameters. Capture them server-side on the first request that lands, before any redirect can eat them.

Check your current campaigns

Paste your campaign URLs into the free validator and see every casing difference, synonym and missing parameter splitting your reports right now.

Validate my UTMs

Stop guessing which ad made the sale.

Flowsk Signals stitches the anonymous click to the email to the purchase — first-party, server-side, de-duplicated. One snippet, $29/mo, and every conversion comes with a receipt you can inspect.

Keep reading