How to Automate UTM Parameter Generation for Ads
Generate consistent UTM tags for every ad automatically to fix attribution.
Jay Banlasan
The AI Systems Guy
When you automate UTM parameters for ad campaigns, you fix the attribution mess that comes from inconsistent manual tagging. I have seen accounts where the same campaign had five different UTM formats because different people built the ads. One system, one format, zero confusion.
This takes 20 minutes to build and saves hours of debugging analytics later.
What You Need Before Starting
- Python 3.8+
- A URL encoding library (built into Python)
- Your naming convention documented
- Google Analytics or any analytics tool that reads UTMs
Step 1: Define Your UTM Convention
UTM_CONFIG = {
"source_map": {
"meta": "facebook",
"google": "google",
"tiktok": "tiktok",
"linkedin": "linkedin",
},
"medium_map": {
"paid": "cpc",
"organic": "organic",
"email": "email",
},
"separator": "_",
}
Step 2: Build the UTM Generator
from urllib.parse import urlencode, urlparse, urlunparse, parse_qs
def generate_utm(base_url, platform, campaign_name, adset_name, ad_name, medium="paid"):
source = UTM_CONFIG["source_map"].get(platform, platform)
medium_val = UTM_CONFIG["medium_map"].get(medium, medium)
sep = UTM_CONFIG["separator"]
# Clean names for UTM use
def clean(name):
return name.lower().replace(" | ", sep).replace(" ", sep).replace("--", sep).strip(sep)
utm_params = {
"utm_source": source,
"utm_medium": medium_val,
"utm_campaign": clean(campaign_name),
"utm_content": clean(adset_name),
"utm_term": clean(ad_name),
}
# Parse existing URL and append UTMs
parsed = urlparse(base_url)
existing_params = parse_qs(parsed.query)
existing_params.update(utm_params)
new_query = urlencode(existing_params, doseq=True)
final_url = urlunparse(parsed._replace(query=new_query))
return final_url
Step 3: Batch Generate for All Ads
def generate_all_utms(ads_config, base_url):
results = []
for ad in ads_config:
url = generate_utm(
base_url=base_url,
platform=ad["platform"],
campaign_name=ad["campaign"],
adset_name=ad["adset"],
ad_name=ad["ad_name"],
)
results.append({
"ad_name": ad["ad_name"],
"platform": ad["platform"],
"tagged_url": url,
})
return results
# Example usage
ads = [
{"platform": "meta", "campaign": "JB | Lead | UK | Assessment", "adset": "Broad | 28-55 | Lead", "ad_name": "01 | iMessage | Native | TomAgency"},
{"platform": "meta", "campaign": "JB | Lead | UK | Assessment", "adset": "Broad | 28-55 | Lead", "ad_name": "02 | Salary | PASTOR | CostMath"},
{"platform": "google", "campaign": "JB | Lead | US | Quiz", "adset": "Broad | 25-45 | Lead", "ad_name": "01 | Search | DR | AIAudit"},
]
tagged = generate_all_utms(ads, "https://jaybanlasan.com/assessment/")
for t in tagged:
print(f"{t['ad_name']}:\n {t['tagged_url']}\n")
Step 4: Validate UTMs Before Launch
def validate_utm(url):
parsed = urlparse(url)
params = parse_qs(parsed.query)
required = ["utm_source", "utm_medium", "utm_campaign"]
missing = [p for p in required if p not in params]
issues = []
if missing:
issues.append(f"Missing required params: {missing}")
for key, values in params.items():
if key.startswith("utm_"):
val = values[0]
if " " in val:
issues.append(f"{key} contains spaces: '{val}'")
if val != val.lower():
issues.append(f"{key} has uppercase: '{val}'")
return {"valid": len(issues) == 0, "issues": issues, "url": url}
# Validate all generated URLs
for t in tagged:
result = validate_utm(t["tagged_url"])
if not result["valid"]:
print(f"INVALID: {t['ad_name']}: {result['issues']}")
Step 5: Export for Ads Manager
import csv
def export_utm_sheet(results, output_path="utm_tags.csv"):
with open(output_path, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["ad_name", "platform", "tagged_url"])
writer.writeheader()
writer.writerows(results)
print(f"Exported {len(results)} URLs to {output_path}")
Hand this CSV to whoever builds the ads, or feed it directly into your campaign creation API. Every ad gets the right UTM, every time, with zero manual typing.
What to Build Next
Connect this to your Meta campaign creation script so UTMs are applied automatically during ad creation. Then build a UTM audit tool that scans all live ads and flags any with missing or malformed tags.
Related Reading
- The Feedback Loop That Powers Everything - closing the attribution loop
- Map Before You Automate - mapping your process before automating it
- Building Your First Automation: A Complete Guide - automation fundamentals
Want this system built for your business?
Get a free assessment. We will map every system your business needs and show you the ROI.
Get Your Free Assessment