UTM tag generator
UTM tags are parameters added to a link so that Google Analytics 4, Yandex.Metrica and ad dashboards can show exactly where a visitor came from: which platform, campaign, ad and keyword. Without them all paid and affiliate traffic collapses into a single generic ‘referral’.
They are most useful for:
- search and paid-social advertising — Google Ads, Yandex.Direct, VK Ads, Meta Ads, TikTok Ads, Telegram Ads — to see which source and campaign actually deliver;
- affiliate marketing — to label funnels and pass click data into a tracker (Keitaro, Binom, Voluum) and the affiliate network;
- email and messenger newsletters — to compare the performance of different emails and sending services;
- influencer seeding and push/native networks — to tell effective placements and creatives apart;
- comparing individual ads, banners and posts against each other and cutting the unprofitable ones.
Landing page URL
Traffic source
Pick a platform — we'll fill the correct utm_source and utm_medium. Or keep "Custom values" and fill in manually.
Required parameters
Optional parameters
Advanced parameters
utm_source_platform is visible only in GA4 Explorations; utm_creative_format and utm_marketing_tactic are not reported by GA4 yet — add them for third-party BI tools.
Result
Link history
My templates
Shorten the link
clck.ru — for RU IPs · tinyurl.com / da.gd — for everyone else.
QR code
Tracker campaign link
Builds a campaign link with sub parameters for your tracker: source macros go into the right slots.
Tracker postback
S2S postback template to paste into your CPA network. Replace placeholders with your network's macros.
Dynamic variables in tracking links
- What is it?
- Google Ads
- Yandex.Direct
- VK Ads
- Meta Ads (FB/IG)
- TikTok Ads
- Click IDs
- Push/pop networks
- Native networks
- Trackers
Dynamic variables (macros): what they are
Dynamic variables — also called macros or dynamic parameters — automatically insert click data into an ad link: which ad, keyword, device or region the visit came from. You write the macro into a UTM tag once, and the ad platform replaces it with a real value on every click.
For example, in Google Ads utm_content={creative} is replaced with the ID of the ad that was clicked. Macros most often go into utm_content and utm_campaign, but any tag will do.
The key subtlety: every platform has its own macro wrapper, and you cannot mix them up. Substitution is literal string replacement — get a bracket wrong and the macro lands in your reports as plain text. The main wrappers are: {...} — Google Ads, Yandex.Direct, most push and native networks; {{...}} — VK Ads, Meta Ads, Outbrain; __...__ — TikTok Ads; [...] — RichAds and some push networks; ${...} — the click ID in PropellerAds.
Below are macro tables verified against official docs for the platforms and trackers that are current in 2026.
Google Ads: ValueTrack macros
Google Ads uses the ValueTrack system — macros in single curly braces {...}. Put them into UTM tag values; the case inside the braces does not matter, but the braces themselves are critical. Note that there is no {campaignname} macro — only the numeric {campaignid} is available.
There are two tracking fields, and it matters not to confuse them. The final URL suffix is a tail of parameters appended to the landing page URL without a redirect — this is where UTM tags belong. The tracking template is a tracker URL with a redirect that the click passes through before the landing page; the {lpurl} macro only works there.
Recommended final URL suffix:
utm_source=google&utm_medium=cpc&utm_campaign={campaignid}&utm_content={creative}&utm_term={keyword}&adgroupid={adgroupid}&network={network}&device={device}&matchtype={matchtype}&placement={placement}&gclid={gclid}
| Parameter | Description |
|---|---|
| {campaignid} | Campaign ID (numeric). There is no {campaignname} macro. |
| {adgroupid} | Ad group ID. |
| {creative} | Ad ID. |
| {keyword} | The keyword the ad was shown for (Search network). |
| {targetid} | ID of the keyword (kwd), DSA (dsa), audience (aud) or AI Max keywordless target. E.g. kwd-123:aud-456. |
| {matchtype} | Match type: b — broad, p — phrase, e — exact, a — AI Max keywordless (since 2025). |
| {network} | Network: g — Search, s — search partners, d — Display, ytv — YouTube, vp — video partners, gtv — Google TV, x — Performance Max, e — App engagement. |
| {device} | Device type: m — mobile, t — tablet, c — computer. |
| {devicemodel} | Device model (Display only). |
| {adposition} | Ad position. E.g. 1t2 — page 1, shown above results (top), position 2. |
| {placement} | The Display site where the ad was clicked. |
| {target} | Placement category (for managed placements). |
| {extensionid} | Extension ID (asset system). {feeditemid} is the legacy version. |
| {loc_physical_ms} | ID of the physical location the click came from. |
| {loc_interest_ms} | ID of the location of interest from the user’s query. |
| {gclid} | Google Click ID — a unique click identifier. |
| {lpurl} | The final URL. Works only in the tracking template; variants include {lpurl+2}, {lpurl+3}, {unescapedurl}. |
| {ignore} | Separates the tracking tail from the content part of the URL. |
| {random} | A random number (used for cache-busting). |
| {ifmobile:X} / {ifnotmobile:X} | Inserts X depending on whether the device is mobile. |
| {ifsearch:X} / {ifcontent:X} | Inserts X depending on the network (Search/Display). Does not work in Performance Max. |
| {product_id}, {merchant_id}, {product_partition_id}, {store_code} | Product data from Merchant Center (for Shopping campaigns). |
Yandex.Direct: link parameters
Yandex.Direct uses macros in single curly braces {...}. Mind the limits: there is no {gender} macro in Direct, and {param1} / {param2} can only be set via an XLS file, Direct Commander or the API.
Recommended template:
utm_source=yandex&utm_medium=cpc&utm_campaign={campaign_id}&utm_content={ad_id}&utm_term={keyword}&source={source_type}_{source}®ion={region_id}&device={device_type}
Direct appends the yclid click ID to the link automatically by default — do not add it by hand. Keep the URL length limit in mind — 4096 bytes: Cyrillic in UTF-8 uses it up faster (one Russian character takes 2 bytes).
| Parameter | Description |
|---|---|
| {campaign_id} | Campaign ID. |
| {campaign_name} | Campaign name. |
| {campaign_name_lat} | Campaign name transliterated into Latin. |
| {campaign_type} | Campaign type (type1 — text & image ads, type2 — app ads, type3 — dynamic, type4 — smart banners). |
| {gbid} | Ad group ID. |
| {ad_id} (= {banner_id}) | Ad ID. |
| {phrase_id} | Keyword ID. |
| {keyword} | The keyword the ad was shown for (without negative keywords). |
| {matched_keyword} | The phrase matched by auto-targeting. |
| {match_type} | Match type: rm — auto-targeting, syn — synonym. |
| {retargeting_id} | Retargeting condition ID. |
| {adtarget_id} / {adtarget_name} | ID / name of the dynamic-ad targeting condition. |
| {creative_id} | Creative ID from the constructor. |
| {coef_goal_context_id} | Bid adjustment ID. |
| {source} | Ad-network (RSYA) site domain (e.g. cpa.rip), or none when shown in Yandex Search. |
| {source_type} | Placement type: search or context (networks). |
| {position_type} | Block type: premium, dynamic_places, other, or none (shown in networks). |
| {position} | Ad position number within the block (0 — shown in networks). |
| {region_id} / {region_name} | ID / name of the region where the ad was shown. |
| {device_type} | Device type: desktop, mobile, tablet. |
VK Ads: dynamic parameters
VK Ads (ads.vk.com) has replaced both the old VKontakte office (vk.com/ads) and myTarget: from 17.11.2025 no new campaigns can be created in them, and on 28.01.2026 both offices were fully closed and switched to read-only. Advertising in Odnoklassniki now also runs only through VK Ads. The macro syntax is inherited from myTarget — double curly braces {{...}}.
The main trap. Despite the name, {{campaign_id}} inserts the ad group ID, not the campaign ID. The campaign ID itself (top level) is {{ad_plan_id}}. There is no {{ad_id}} macro: the ad ID is passed by {{banner_id}}.
Recommended template:
utm_source=vk_ads&utm_medium=cpc&utm_campaign={{ad_plan_id}}&utm_content={{banner_id}}&utm_term={{search_phrase}}&adgroup={{campaign_id}}&geo={{geo}}&demo={{gender}}.{{age}}
| Parameter | Description |
|---|---|
| {{advertiser_id}} | Advertiser ID. |
| {{ad_plan_id}} | Campaign ID — the top level (this is the campaign). |
| {{ad_plan_name}} | Campaign name. |
| {{campaign_id}} (= {{ad_group_id}}) | Trap: the AD GROUP ID, not the campaign ID (a myTarget legacy). |
| {{campaign_name}} (= {{ad_group_name}}) | Ad group name. |
| {{banner_id}} | Ad (creative) ID. There is no {{ad_id}} macro. |
| {{geo}} | Region ID (by the geo tree) the click came from. |
| {{gender}} | Gender of the user who clicked. |
| {{age}} | Age of the user who clicked. |
| {{search_phrase}} | The search phrase the click came from. |
| {{impression_weekday}} | Weekday of the impression (e.g. mon). |
| {{impression_hour}} | Hour of the impression in Moscow time, 24-hour format (e.g. 23). |
| {{user_timezone}} | The user’s time zone (e.g. +3). |
| {{random}} | A random number (cache-busting). Not {{random_id}}. |
Meta Ads (Facebook/Instagram): macros
Meta Ads (Facebook and Instagram) uses macros in double curly braces {{...}}. They go into the ad-level URL parameters field — without a leading ?, just the parameters themselves.
Gotcha 1: the name macros ({{campaign.name}}, {{adset.name}}, {{ad.name}}) are frozen at first publish — if you rename the campaign later, the old name keeps flowing into reports. Use ID macros for stability. Gotcha 2: Meta adds the fbclid click ID to the link itself — do not put it in the template.
Recommended URL parameters value (without ?):
utm_source={{site_source_name}}&utm_medium=paid_social&utm_campaign={{campaign.id}}&utm_content={{adset.id}}_{{ad.id}}&utm_term={{placement}}
| Parameter | Description |
|---|---|
| {{campaign.id}} | Campaign ID. |
| {{campaign.name}} | Campaign name (frozen at first publish). |
| {{adset.id}} | Ad set (ad group) ID. |
| {{adset.name}} | Ad set name (frozen at first publish). |
| {{ad.id}} | Ad ID. |
| {{ad.name}} | Ad name (frozen at first publish). |
| {{placement}} | Placement (feed, stories, marketplace, etc.). |
| {{site_source_name}} | Platform: fb — Facebook, ig — Instagram, msg — Messenger, an — Audience Network. |
TikTok Ads: dynamic macros
TikTok Ads uses macros in the __MACRO__ format — two underscores on each side and strictly UPPERCASE. This is critical: TikTok is case-sensitive, and many generators force tags to lowercase, which breaks the macro. Turn off auto-lowercase for these values.
Level trap: __AID__ is the ad group ID, not the ad itself; the creative ID is __CID__; the ad ID in Smart+ campaigns is __ADID_V2__. TikTok adds the ttclid click ID automatically (it lives about 30 days). Mind the 125-character UTM string limit — anything longer is truncated.
Recommended template:
utm_source=tiktok&utm_medium=paid_social&utm_campaign=__CAMPAIGN_ID__&utm_content=__CID__&utm_term=__AID__&placement=__PLACEMENT__
| Parameter | Description |
|---|---|
| __CAMPAIGN_ID__ | Campaign ID. |
| __CAMPAIGN_NAME__ | Campaign name. |
| __AID__ | Trap: the AD GROUP ID, not the ad. |
| __AID_NAME__ | Ad group name. |
| __CID__ | Creative ID. |
| __CID_NAME__ | Creative name. |
| __ADID_V2__ | Ad ID (in Smart+ campaigns). |
| __ADID_V2_NAME__ | Ad name (in Smart+ campaigns). |
| __PLACEMENT__ | Placement: TikTok or TikTok Pangle. |
| __IDFA__, __GAID__, __IP__, __UA__, __CALLBACK_PARAM__ | Mobile app attribution parameters (for AppsFlyer, Adjust and other MMPs). |
Ad platform click IDs
A click ID is a unique identifier of a specific click that the ad platform adds to the link itself on the redirect. It is used for accurate conversion matching, including passing data back via postback and for offline conversions. There is no need — and it is harmful — to type these parameters into UTM by hand: the platform will insert its own value and yours only gets in the way.
| Parameter | Description |
|---|---|
| gclid | Google Ads — added automatically, do not type by hand. |
| yclid | Yandex.Direct — added automatically, do not type by hand. |
| fbclid | Meta Ads (Facebook/Instagram) — added automatically, do not type by hand. |
| ttclid | TikTok Ads — added automatically, do not type by hand. |
| tblci | Taboola — added automatically, do not type by hand. |
Push and pop networks: macros
Push and pop networks have no single standard: each network has its own macro wrapper, and you cannot mix them up. PropellerAds passes the click ID via ${SUBID} (its only macro with a dollar sign and in uppercase), while the rest are lowercase in single braces; RichAds uses square brackets and UPPERCASE — [CAPS]; Evadav uses curly braces and UPPERCASE — {CAPS}. Below are the macros of three networks, verified against official docs.
| Parameter | Description |
|---|---|
| PropellerAds: ${SUBID} | Click ID (the network’s only macro with a dollar sign and in uppercase). |
| PropellerAds: {campaign_id} | Campaign ID. |
| PropellerAds: {zoneid} | Zone (placement) ID. |
| PropellerAds: {bannerid} | Banner ID. |
| PropellerAds: {country} | Click country. |
| PropellerAds: {os} | Operating system. |
| PropellerAds: {cost} | Click price. |
| RichAds: [CLICK_ID] | Click ID. |
| RichAds: [CAMPAIGN_ID] | Campaign ID. |
| RichAds: [CREATIVE_ID] | Creative ID. |
| RichAds: [SITE_ID] | Site ID. |
| RichAds: [SUB_LIST_ID] / [ZONE_ID] | Source-list ID (push) / zone ID (pop). |
| RichAds: [COUNTRY_CODE] | Country code. |
| RichAds: [BID_PRICE] / [CPV_PRICE] | Bid (push) / impression price (pop). |
| Evadav: {CLICKID} | Click ID (no underscore). |
| Evadav: {CAMPAIGN_ID} | Campaign ID. |
| Evadav: {CREATIVE_ID} | Creative ID. |
| Evadav: {ZONE_ID} | Zone ID. |
| Evadav: {SOURCE_ID} | Source ID. |
| Evadav: {COUNTRY} | Country. |
| Evadav: {COST} | Click price. |
Native and teaser networks: macros
Native and teaser networks also use different wrappers. MGID, Taboola and Kadam write macros in lowercase single braces {...}; Outbrain uses double curly braces {{...}} (or square brackets). A Taboola specific: the network inserts the tblci click ID into the link itself (tblci={click_id}), but in the server-side (S2S) postback the same parameter is called click-id — with a hyphen, not an underscore.
| Parameter | Description |
|---|---|
| MGID: {click_id} | Click ID. |
| MGID: {campaign_id} | Campaign ID. |
| MGID: {teaser_id} | Ad (teaser) ID. |
| MGID: {widget_id} | Widget (placement) ID. |
| MGID: {geo} | Region. |
| MGID: {click_price} | Click price. |
| Taboola: {click_id} | Click ID. Taboola inserts tblci={click_id} itself; in the S2S postback the parameter is click-id (with a hyphen). |
| Taboola: {campaign_id} | Campaign ID. |
| Taboola: {campaign_item_id} | Ad ID. |
| Taboola: {site} / {site_id} | Site / site ID. |
| Taboola: {platform} | Device type (platform). |
| Taboola: {cpc} | Click price. |
| Outbrain: {{ob_click_id}} | Click ID. |
| Outbrain: {{campaign_id}} | Campaign ID. |
| Outbrain: {{ad_id}} / {{ad_title}} | Ad ID / ad title. |
| Outbrain: {{publisher_id}} / {{section_id}} | Publisher ID / section (placement) ID. |
| Outbrain: {{cpc}} | Click price. |
| Kadam: {click_id} | Click ID. |
| Kadam: {campaign_id} | Campaign ID. |
| Kadam: {ad_id} | Ad ID. |
| Kadam: {site_id} | Site ID. |
| Kadam: {country_code} | Country code. |
| Kadam: {platform} | Operating system (there is no {os} macro). |
| Kadam: {cpc} | Click price. |
Trackers: mapping tags and postbacks
A tracker sits between the ad platform and the offer: the click travels along the chain source → tracker → offer. In the ad you insert the platform’s macros into the tracker’s sub-slots (for example, track.domain.com/xYz?sub_id_1={{campaign.id}}&sub_id_2={{adset.id}}), the tracker records the click and redirects to the offer, passing its own click ID (?clickid={subid}). When a conversion happens, the affiliate network fires the tracker’s postback and reports the status and payout. UTM tags and tracker mode do not conflict: white verticals, e-commerce and GA4/Metrica reports need UTM, while affiliate work by click ID needs sub-slots and postbacks. Below is a Rosetta stone of equivalents across four trackers.
| Parameter | Description |
|---|---|
| Keitaro | Tag sub-slots: sub_id_1…sub_id_30. Click-ID token: {subid}. Postback: /PBKEY/postback?subid=X&status=lead&payout=25 (subid and status are required). |
| Binom | Tag sub-slots: t1…t10 (plus {externalid}). Click-ID token: {clickid}. Postback: /click.php?cnv_id=X&payout=Y&cnv_status=Z (cnv_id and payout are required). |
| Voluum | Tag sub-slots: {var1}…{var10}. Click-ID token: {clickid}. Postback: /postback?cid=X&payout=Y&et=Z (cid is required). |
| BeMob | Up to 10 custom variables plus External ID. Click-ID token: {clickId}. Postback: /postback?cid=X&status=Y&payout=Z (cid is required). |
Common UTM tagging mistakes
Put UTM after the anchor — site.com/page#section?utm_source=... — and analytics will not see it: everything after # stays in the browser and never reaches the server. Fix: place tags in the query part, before the hash: site.com/page?utm_source=...#section.
If the URL already has parameters (e.g. ?id=5), UTM must be joined with &, not a second ?. A link with two ? signs breaks and the tags are not read. Fix: the first parameter is separated by ?, all the rest by &: ?id=5&utm_source=google.
GA4 and Metrica treat utm_source=Google and utm_source=google as different sources, so one platform's traffic splits into two rows in the report. Fix: agree on a single case (usually lowercase) and keep it across every campaign.
A space in a tag encodes as %20 or +, and + decodes back into a space when read — the value breaks and Metrica/GA4 reports fill up with duplicates. Fix: avoid spaces and separate words with an underscore _.
Non-Latin letters in a tag turn into a long %D0%BA%D1%80..., hurt link readability and eat into the length limit, and some services break such links. Fix: write values in Latin or transliteration — the generator has a transliteration toggle.
Every platform has its own macro wrapper: {campaignid} — Google Ads, {{campaign.id}} — Meta, __CAMPAIGN_ID__ — TikTok. Paste the wrong format or miss a bracket and substitution fails, sending the macro text itself into reports. Fix: take macros from the right platform's table and do not lowercase them where uppercase matters (TikTok).
Tags on links between your own pages reset the analytics session: GA4 starts a new visit and attributes it to the source in the tag, so the original channel is lost and conversions are double-counted. Fix: tag only external incoming links and keep internal navigation clean.
If an intermediate redirect (a shortener, a domain bridge, an old tracker) strips the query string, UTM never reaches the final page and the visit falls into untagged traffic. Fix: check that the redirect forwards parameters; in trackers enable passing tags to the offer, and use the click ID and postback for conversion matching.
UTM parameters — FAQ
What is a UTM tag?
A UTM tag is a parameter added to the end of a link after the ? sign to pass visit data into analytics. The five standard tags — utm_source, utm_medium, utm_campaign, utm_content and utm_term — are recognised by Google Analytics 4, Yandex.Metrica and most analytics systems. They show which platform, campaign and ad a visitor came from.
Which UTM parameters are required?
Three are required: utm_source (source), utm_medium (traffic type) and utm_campaign (campaign). Two more — utm_content and utm_term — are optional and refine the ad and keyword. Skip any of the required ones and analytics may treat the visit as untagged traffic.
Does case matter, and can I use non-Latin characters?
Yes, case matters: GA4 and Metrica treat Google and google as different values, so keep your tags in one case — usually lowercase. Non-Latin characters technically work, but they encode into a long %D0%BA... form, hurt link readability and eat into the length limit. Latin or transliteration is safer, and for multi-word values use _.
How is utm_id different from utm_campaign?
utm_campaign is the campaign name, while utm_id is its identifier for tying to cost imports (Manual campaign ID in GA4). GA4 recognises utm_id, but shows it in Explore rather than in the standard reports. If you do not import costs manually, you can leave utm_id empty.
Where do I find UTM tags in GA4 and Yandex.Metrica?
In GA4 the data from utm_source and utm_medium lands in the Traffic acquisition reports (the Session source / medium / campaign dimensions); utm_term and utm_content are available there and in Explore. In Yandex.Metrica the tags appear in the UTM Tags report (Reports → Sources → UTM Tags). Data is not instant — usually within a few hours.
Do UTM tags work with redirects and trackers?
Yes, but the tags must survive to the final page. Trackers (Keitaro, Binom, Voluum, BeMob) can forward parameters to the offer on redirect, but if an intermediate redirect strips the query string, the tags are lost. In affiliate marketing the click ID is usually passed via the tracker's sub-slots and postback, while UTM is kept for GA4/Metrica and white verticals.
Why does a link with # not pass the tags?
Everything after the hash # (the anchor / fragment) is not sent by the browser to the server or to analytics — it stays in the browser. Put UTM after # and GA4 and Metrica will not see it. Tags must always go in the query part, before the #: first ?utm_..., and only then #.
Is there a length limit for a tagged link?
Yes. Yandex.Direct caps the link at 4096 bytes (and Cyrillic in UTF-8 uses it up twice as fast). TikTok Ads limits the UTM string to 125 characters — anything longer is truncated. The general rule: keep tags short, use IDs instead of long names, and do not duplicate parameters.
How should I replace spaces: +, %20 or _?
The safest option is an underscore _ directly in the tag value: it needs no encoding and reads the same everywhere. The + sign is risky: it decodes back into a space and can split the value in reports. %20 is the correct space code but less readable; if you keep a space, encode it that way rather than as a plus.










