UTM builder API
Generate tagged URLs from the recommended template for any platform — and get told what's wrong with them. Free, no key, no rate limit.
Enter a valid URL starting with http:// or https://
Every platform page on this site is backed by structured data: the recommended parameters, the click-time macros, and the click-ID rule. The API serves that same data, and applies it.
Quick start
One GET request. No key, no signup, no Authorization header.
curl "https://utm.new/api/v1/build?url=https://example.com/pricing&platform=google-ads" {
"url": "https://example.com/pricing?utm_source=google&utm_medium=cpc&utm_campaign={campaignid}&utm_id={campaignid}&utm_term={keyword}&utm_content={adgroupid}",
"platform": { "id": "google-ads", "name": "Google Ads", "status": "published" },
"params": { "utm_source": "google", "utm_medium": "cpc", "...": "..." },
"warnings": []
} What makes this different
Concatenating query parameters is trivial. Knowing which ones will break your
attribution is not. Every response carries a warnings array built
from what the catalog knows about that specific platform.
curl "https://utm.new/api/v1/build?url=https://example.com&platform=meta-ads&extra.fbclid=abc123" "warnings": [
{
"code": "click_id_auto_tagged",
"severity": "warning",
"param": "fbclid",
"message": "Meta Ads appends fbclid to the landing URL on every ad click. Sending it yourself puts the parameter on the URL twice and the platform's own value wins — remove it."
}
]
Warning code values are stable and safe to branch on. An empty array
means the link is clean.
| Code | Severity | Means |
|---|---|---|
click_id_auto_tagged | warning | You sent a click ID the platform appends itself — it will be duplicated. |
click_id_missing | warning | The platform does not auto-tag and you removed its click ID. |
tokens_unsupported | warning | You used a macro on a platform that cannot substitute it. |
url_length_exceeded | warning | The result is longer than the platform accepts. |
reserved_param_in_extra | warning | A utm_* key was passed via extra; use overrides. |
platform_is_receiver | warning | This platform reads UTMs, it doesn't send traffic. |
params_replaced | info | Your URL already carried these params; they were replaced. |
platform_unverified | info | Template is usable but hasn't been through editorial review. |
utm_id_unsupported | info | The platform has no campaign ID to populate utm_id. |
override_not_in_template | info | You overrode a key the template doesn't define. |
Endpoints
| Endpoint | Purpose |
|---|---|
GET /api/v1/build | Build one tagged URL. |
POST /api/v1/build | Structured overrides, or a batch of up to 50. |
GET /api/v1/platforms.json | All 37 platforms. |
GET /api/v1/platforms/{id}.json | One platform in full. |
GET /api/v1/openapi.json | OpenAPI 3.1 spec. |
Customising the template
Use override.<param> to replace a template value, and
extra.<param> for anything that isn't a UTM. Setting an
override to an empty string removes that parameter.
curl "https://utm.new/api/v1/build?url=https://example.com&platform=meta-ads&override.utm_campaign=spring-sale&override.utm_term=&extra.ref=newsletter" Batch
curl -X POST https://utm.new/api/v1/build \
-H "Content-Type: application/json" \
-d '{
"links": [
{ "url": "https://example.com/a", "platform": "google-ads" },
{ "url": "https://example.com/b", "platform": "reddit-ads",
"overrides": { "utm_campaign": "launch" } }
]
}' A bad entry is reported inline rather than failing the whole batch.
Use it from an AI assistant
The OpenAPI spec at
/api/v1/openapi.json is
importable as a Custom GPT Action, a Claude tool, or a custom connector in
Zapier, Make, and n8n. No auth to configure.
The click-ID rule
The single most common tagging mistake is adding a click ID the platform already appends. The API knows which is which.
Appends its own — don't add it
- ChatGPT Ads
oppref - Google Ads
gclid - LinkedIn Ads
li_fat_id - Meta Ads
fbclid - Microsoft Ads
msclkid - Pinterest Ads
epik - Snapchat Ads
ScCid - Taboola
tblci - TikTok Ads
ttclid - X / Twitter Ads
twclid - YouTube Ads
gclid
You must add it yourself
- MGID
adclid - Outbrain
ob_click_id - Reddit Ads
rdt_cid
Limits and stability
- No authentication, no rate limit, open CORS.
- 31 taggable platforms; 37 in the catalog.
GET /buildis deterministic and cached for 24h at the edge.- Only
httpandhttpsdestination URLs are accepted. -
Breaking changes ship under a new version path. Recommendations themselves
are content and may improve within
v1— every response carries aversionso you can detect it. - Data is CC BY 4.0. Attribution appreciated, not enforced.