UTM Standard
Deterministic rules for generating UTM parameters. Given the same campaign, source, and distribution context, two conforming agents generate the same UTM.
Same context + same standard = same UTM.
Overview
What it does
Teams and AI agents tag the same campaign differently: LinkedIn, linkedin.com, li. Reports fragment, and channel attribution in Google Analytics drifts.
The UTM Standard removes the guesswork. It defines which inputs are required, how each parameter is derived, and what to return when context is missing. Parameter meanings come from Google Analytics. Canonical values come from the open Source Registry.
Campaign
Approved campaign identity
utm_campaignSource
Resolved from the Source Registry
utm_sourceDistribution context
organic, paid, owned, display
utm_medium
{
"campaign": {
"name": "Spring Product Launch"
},
"source": "linkedin",
"distribution_context": "organic",
"destination_url": "https://example.com/product"
}{
"status": "ok",
"standard_version": "0.1.0",
"parameters": {
"utm_source": "linkedin",
"utm_medium": "social",
"utm_campaign": "spring_product_launch"
},
"url": "https://example.com/product?utm_source=linkedin&utm_medium=social&utm_campaign=spring_product_launch"
}Standard
Parameters
The minimum conforming set is utm_source, utm_medium, utm_campaign. Every other parameter is set only from supplied inputs. Agents never invent values.
| Parameter | Requirement | Value from | Derivation |
|---|---|---|---|
| utm_source | Required | Source Registry | The canonical_source of the resolved source record. Google meaning: The referrer of the traffic, such as a search engine, newsletter, or other source. Google-defined |
| utm_medium | Required | Source + distribution context | contexts[distribution_context].utm_medium of the resolved source record. Google meaning: The marketing medium, such as cpc, banner, or email newsletter. Google-defined |
| utm_campaign | Required | Approved campaign identity | campaign.slug exactly if present; otherwise the campaign slug algorithm applied to campaign.name. Google meaning: The name of the campaign, product, promotion, or other identifier. Google-defined |
| utm_id | Recommended | Campaign system | The campaign ID from the system of record, passed through unchanged. Google meaning: The campaign ID used to identify a specific campaign or promotion. Google-defined |
| utm_source_platform | Recommended where applicable | Platform | The buying or management platform directing the traffic, when one exists. Normalized with the value format rule. Google meaning: The platform responsible for directing traffic to a given property, such as a buying platform that sets budgets and targeting criteria. Google-defined |
| utm_content | Optional | Creative / asset | The creative or asset identifier, normalized with the value format rule. Google meaning: Used to differentiate ads or links that point to the same URL. Google-defined |
| utm_term | Optional | Keyword / targeting | The paid keyword or targeting term, normalized with the value format rule. Google meaning: Identifies paid search keywords. Google-defined |
| utm_creative_format | Optional | Creative format | The creative format, normalized with the value format rule. Google meaning: The type of creative, such as display, native, video, or search. Google-defined |
| utm_marketing_tactic | Optional | Marketing tactic | The targeting criteria or tactic, normalized with the value format rule. Google meaning: The targeting criteria applied to a campaign, such as remarketing or prospecting. Google-defined |
Standard
Campaign naming
utm_campaign represents campaign identity. It is not a container for every available marketing dimension.
Precedence
- If campaign.slug exists, use it exactly. Do not re-normalize it.
- Otherwise derive the slug from campaign.name with the slug algorithm.
- If neither exists, return requires_context with campaign in missing.
Slug algorithm
- Apply Unicode NFKD normalization and remove combining marks.
- Convert to lowercase.
- Replace every run of characters outside a-z and 0-9 with a single underscore.
- Trim leading and trailing underscores.
Result must match ^[a-z0-9]+(_[a-z0-9]+)*$ and stay stable for the life of the campaign.
Do not add unless part of campaign identity
- source
- medium
- platform
- placement
- creative
- audience
- ad_set
- keyword
- date
- year
- quarter
Examples
- Spring Product Launchbecomes
spring_product_launch - Q3 Partner Summit — Berlinbecomes
q3_partner_summit_berlin - Café Rewards Programbecomes
cafe_rewards_program
A supplied campaign.slug is always used exactly, even when the name differs.
Standard
Generation
Steps
- 1Resolve source to a registry record by exact match on canonical_source or aliases, case-insensitive.
- 2Resolve distribution_context against the record's contexts.
- 3Set utm_source and utm_medium from the record.
- 4Set utm_campaign from campaign naming precedence.
- 5Set recommended and optional parameters only from supplied inputs. Never invent values.
- 6Apply the organization profile, if any.
- 7Assemble the URL using url_assembly.
URL assembly
- Remove any existing utm_* parameters from the destination URL.
- Preserve all other existing query parameters in their original order.
- Append UTM parameters after existing parameters in parameter_order.
- Omit parameters that have no value. Never emit an empty parameter.
- Percent-encode values per RFC 3986. Conforming values require no encoding.
- Preserve the URL fragment after the query string.
When generation cannot complete
Missing context. Do not guess. Return a requires_context response listing every missing required input.
{
"status": "requires_context",
"missing": [
"distribution_context"
]
}Unknown source. Do not invent a source. Return an unknown_source response.
{
"status": "unknown_source",
"source": "<input>"
}Unsupported context. Do not substitute a different context. Return an unsupported_context response listing supported contexts.
{
"status": "unsupported_context",
"source": "<canonical_source>",
"supported": [
"<context>"
]
}Provenance
What Google defines, what SchemaFirst defines
Every value in the standard and registry is labeled with where it comes from. SchemaFirst is an independent community standard. It is not authored or endorsed by Google.
- Google-defined
Semantics, supported parameters, channel behavior, and documented recommendations from Google Analytics.
- SchemaFirst default
Canonical implementation decisions made by SchemaFirst for deterministic agent generation. Not authored or endorsed by Google.
- Organization override permitted
Defaults that may be replaced through an explicit organization profile.
Google Analytics references
- URL builders: Collect campaign data with custom URLsUTM parameter family, parameter meanings, UTM best practices
- Default channel groupChannel classification rules for manually tagged traffic
- Traffic-source dimensions, manual tagging, and auto-taggingHow UTM parameters map to dimensions; interaction with auto-tagging
- About traffic-source dimensionsDefinitions of source, medium, campaign, campaign ID, source platform
Overrides
Organization profiles
Organization profile > SchemaFirst default. Google-defined parameter semantics cannot be overridden.
Permitted
- Require recommended or optional parameters.
- Define proprietary source records.
- Define additional distribution contexts.
- Override defaults marked as overridable.
- Define where organization-owned values come from.
Not permitted
- Redefine the meaning of Google-defined UTM parameters.
- Remove a parameter from the minimum conforming set.
- Change the campaign slug algorithm.
{
"extends": "https://www.schemafirst.org/standards/utm/0.1",
"organization": "Example Company",
"overrides": {
"utm_id": {
"required": true
}
}
}Community
Versioning and contributions
The standard uses semantic versioning. Changes to any of the following require a new major version:
- parameter semantics
- required fields
- campaign naming
- generation behavior
- override precedence
The Source Registry is versioned independently. Adding a source record and Adding a distribution context to a source record are non-breaking.
Propose sources, contexts, and changes through GitHub. Each source record lives in its own file so changes are reviewed individually.
Licensed under Apache-2.0.