utm-link-generator/SKILL.md
Generates properly tagged UTM links with consistent naming conventions. Maintains a UTM registry file (utm-registry.json) to enforce naming consistency, prevent duplicates, generate short links, and output ready-to-copy links for LinkedIn, email, social, and ads.
npx skillsauth add onewave-ai/claude-skills utm-link-generatorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
A disciplined UTM link generation system that enforces consistent naming conventions across all campaigns, maintains a registry to prevent duplicates and naming drift, and outputs platform-ready links. This is not a simple URL concatenator -- it is a naming governance system for marketing attribution.
UTM chaos is the number one cause of broken marketing attribution. When team members use "linkedin" vs "LinkedIn" vs "linked-in" vs "li" as a source, your analytics become useless. This skill enforces a single source of truth: the UTM registry.
| Parameter | Required | Purpose | Example |
|-----------|----------|---------|---------|
| utm_source | Yes | Where the traffic comes from | linkedin, google, newsletter |
| utm_medium | Yes | Marketing medium | cpc, email, social, organic |
| utm_campaign | Yes | Campaign identifier | q1-2026-product-launch |
| utm_term | No | Paid keyword (search ads) | project-management-software |
| utm_content | No | Differentiates similar links | hero-cta, sidebar-banner, variant-a |
| utm_id | No | Campaign ID for GA4 | camp-2026-q1-001 |
These conventions are non-negotiable. The skill will reject or auto-correct any violations.
LinkedIn, always linkedinproduct launch, always product-launch-campaign-name-my--campaignq[N]-[YYYY] or [YYYY]-[MM] prefixOnly these source values are allowed. Any new source must be explicitly added to the registry.
| Canonical Source | Aliases (auto-corrected) | Platform |
|-----------------|-------------------------|----------|
| google | goog, google-ads, adwords | Google Ads / Organic |
| linkedin | li, linked-in, linkedin-ads | LinkedIn |
| facebook | fb, meta, facebook-ads | Facebook / Meta |
| instagram | ig, insta | Instagram |
| twitter | x, x-com, tw | X (Twitter) |
| youtube | yt, you-tube | YouTube |
| tiktok | tt, tik-tok | TikTok |
| reddit | rd | Reddit |
| email | mail, e-mail, em | Email campaigns |
| newsletter | nl, news-letter | Newsletter specifically |
| bing | microsoft-ads, msn | Bing / Microsoft |
| direct | none, (direct) | Direct traffic |
| referral | ref, partner | Referral traffic |
| podcast | pod, spotify | Podcast channels |
| slack | sl | Slack communities |
| producthunt | ph, product-hunt | Product Hunt |
| hackernews | hn, hacker-news | Hacker News |
| Canonical Medium | Aliases (auto-corrected) | Use Case |
|-----------------|-------------------------|----------|
| cpc | ppc, paid-click, cost-per-click | Paid search / paid social clicks |
| cpm | display, paid-impression | Display / impression campaigns |
| email | e-mail, mail | Email campaigns |
| social | social-media, organic-social | Organic social posts |
| organic | seo, organic-search | Organic search traffic |
| referral | ref, partner, affiliate | Referral / partner links |
| video | vid, youtube, pre-roll | Video ad placements |
| retargeting | remarketing, retarget | Retargeting campaigns |
| content | blog, article, content-syndication | Content marketing |
| webinar | web, event, virtual-event | Webinar / event registrations |
| podcast | pod, audio | Podcast mentions / ads |
| sms | text, mms | SMS / text campaigns |
| qr | qr-code, print | QR code / print materials |
| push | push-notification, notification | Push notifications |
Campaigns follow this structure:
[quarter-or-month]-[year]-[campaign-name]-[optional-variant]
Examples:
q1-2026-product-launch2026-03-spring-webinarq2-2026-brand-awareness-linkedinevergreen-demo-request (for always-on campaigns, skip the date prefix)The user provides some or all of these:
If the user provides a brief like "I need links for our Q1 product launch campaign on LinkedIn and email pointing to our pricing page," extract the parameters from natural language.
For each parameter:
LinkedIn becomes linkedinproduct launch becomes product-launch[a-z0-9-]fb to facebook)Report any corrections made:
## Parameter Validation
- Source: "LinkedIn" -> "linkedin" (normalized to lowercase)
- Medium: "paid" -> "cpc" (corrected to canonical value)
- Campaign: "Q1 Product Launch!" -> "q1-product-launch" (normalized)
- URL: https://example.com/pricing -- Valid
Read the utm-registry.json file (or create it if it does not exist). Check for:
Build the UTM-tagged URL:
{base_url}?utm_source={source}&utm_medium={medium}&utm_campaign={campaign}[&utm_term={term}][&utm_content={content}][&utm_id={id}]
Rules:
& not ?For each platform requested, generate an optimized link:
## LinkedIn
**Post Link** (organic social):
https://example.com/pricing?utm_source=linkedin&utm_medium=social&utm_campaign=q1-2026-product-launch&utm_content=organic-post
**Ad Link** (paid):
https://example.com/pricing?utm_source=linkedin&utm_medium=cpc&utm_campaign=q1-2026-product-launch&utm_content=sponsored-post
**Message Link** (InMail/DM):
https://example.com/pricing?utm_source=linkedin&utm_medium=social&utm_campaign=q1-2026-product-launch&utm_content=inmail
**Profile Link** (bio/featured):
https://example.com/pricing?utm_source=linkedin&utm_medium=social&utm_campaign=q1-2026-product-launch&utm_content=profile-link
## Email
**Primary CTA**:
https://example.com/pricing?utm_source=email&utm_medium=email&utm_campaign=q1-2026-product-launch&utm_content=primary-cta
**Secondary CTA**:
https://example.com/pricing?utm_source=email&utm_medium=email&utm_campaign=q1-2026-product-launch&utm_content=secondary-cta
**Header Link**:
https://example.com/pricing?utm_source=email&utm_medium=email&utm_campaign=q1-2026-product-launch&utm_content=header-link
**Footer Link**:
https://example.com/pricing?utm_source=email&utm_medium=email&utm_campaign=q1-2026-product-launch&utm_content=footer-link
## Social
**Twitter/X**:
https://example.com/pricing?utm_source=twitter&utm_medium=social&utm_campaign=q1-2026-product-launch
**Facebook**:
https://example.com/pricing?utm_source=facebook&utm_medium=social&utm_campaign=q1-2026-product-launch
**Instagram** (bio link):
https://example.com/pricing?utm_source=instagram&utm_medium=social&utm_campaign=q1-2026-product-launch&utm_content=bio-link
**Reddit**:
https://example.com/pricing?utm_source=reddit&utm_medium=social&utm_campaign=q1-2026-product-launch
## Paid Ads
**Google Ads**:
https://example.com/pricing?utm_source=google&utm_medium=cpc&utm_campaign=q1-2026-product-launch&utm_term={keyword}
**LinkedIn Ads**:
https://example.com/pricing?utm_source=linkedin&utm_medium=cpc&utm_campaign=q1-2026-product-launch
**Facebook/Meta Ads**:
https://example.com/pricing?utm_source=facebook&utm_medium=cpc&utm_campaign=q1-2026-product-launch
Note: For Google Ads, use {keyword} as a dynamic placeholder that Google will auto-replace.
Append all generated links to utm-registry.json:
{
"version": "1.0",
"lastUpdated": "2026-04-10T12:00:00Z",
"namingConventions": {
"sources": ["google", "linkedin", "facebook", "instagram", "twitter", "email", "newsletter"],
"mediums": ["cpc", "cpm", "email", "social", "organic", "referral", "video", "retargeting"]
},
"campaigns": [
{
"name": "q1-2026-product-launch",
"createdAt": "2026-04-10T12:00:00Z",
"description": "Q1 2026 product launch campaign",
"links": [
{
"id": "utm-001",
"url": "https://example.com/pricing?utm_source=linkedin&utm_medium=social&utm_campaign=q1-2026-product-launch&utm_content=organic-post",
"source": "linkedin",
"medium": "social",
"campaign": "q1-2026-product-launch",
"content": "organic-post",
"platform": "linkedin",
"variant": "organic-post",
"createdAt": "2026-04-10T12:00:00Z",
"status": "active"
}
]
}
],
"stats": {
"totalLinks": 1,
"totalCampaigns": 1,
"sourcesUsed": ["linkedin"],
"mediumsUsed": ["social"]
}
}
Present the final output in a clean, copy-paste-ready format:
## UTM Links Generated
**Campaign**: q1-2026-product-launch
**Destination**: https://example.com/pricing
**Generated**: 2026-04-10
### Ready-to-Copy Links
| Platform | Variant | Link |
|----------|---------|------|
| LinkedIn (organic) | organic-post | [full URL] |
| LinkedIn (paid) | sponsored-post | [full URL] |
| Email (primary CTA) | primary-cta | [full URL] |
| Email (secondary CTA) | secondary-cta | [full URL] |
| Twitter | default | [full URL] |
| Facebook | default | [full URL] |
### Registry Updated
- New links added: 6
- Total links in registry: 6
- Registry file: ./utm-registry.json
### Validation Report
- All parameters normalized to convention
- No duplicate links found
- No naming conflicts detected
For generating links across many campaigns or many URLs at once.
The user can provide a table or list:
Generate UTM links for these pages:
- /pricing -- linkedin, email, twitter -- q1-2026-product-launch
- /demo -- linkedin, google-ads -- q1-2026-demo-push
- /case-studies -- email, linkedin -- q1-2026-social-proof
## Bulk UTM Generation -- 3 campaigns, 8 platform variants, 24 total links
| Campaign | URL | Platform | Variant | Full Link |
|----------|-----|----------|---------|-----------|
| q1-2026-product-launch | /pricing | linkedin-organic | organic-post | [URL] |
| q1-2026-product-launch | /pricing | linkedin-paid | sponsored-post | [URL] |
| q1-2026-product-launch | /pricing | email | primary-cta | [URL] |
| ... | ... | ... | ... | ... |
Registry updated: 24 new links added.
The user can also invoke this skill for registry operations:
"Audit my UTM registry"
Reads utm-registry.json and reports:
"Add 'partnerstack' as a UTM source"
Adds the new value to the canonical list in the registry and documents it.
"Show me all links for the q1-2026-product-launch campaign"
Filters the registry and displays all links for that campaign, grouped by platform.
"Export my UTM registry as CSV"
Generates a CSV file with columns: Campaign, URL, Source, Medium, Content, Term, Full Link, Created Date, Status.
| Error | Response |
|-------|----------|
| Invalid URL (no protocol) | Auto-prepend https:// and warn |
| Unknown source | Suggest closest canonical match, ask for confirmation |
| Unknown medium | Suggest closest canonical match, ask for confirmation |
| Campaign name too long | Suggest abbreviated version |
| Duplicate link exists | Show existing link, ask if user wants to create anyway |
| Registry file missing | Create new registry with default conventions |
| Registry file corrupted | Attempt to parse what exists, back up, create fresh |
| Base URL has existing UTMs | Strip existing UTM params, warn user, apply new ones |
tools
Uses MCP Connectors to read Gmail inbound leads, score them by ICP fit, draft personalized responses, and log qualified leads to your CRM. Turns your inbox into an automated pipeline.
development
Uses 1M context window to ingest an entire codebase and output a file-by-file migration plan. Supports JS to TS, React class to hooks, framework migrations, and more. Generates migration-plan.md with file inventory, dependency graph, migration order, file-by-file changes, estimated effort, and risk assessment.
development
Extract and analyze data from invoices, receipts, bank statements, and financial documents. Categorize expenses, track recurring charges, and generate expense reports. Use when user provides financial PDFs or images.
tools
Identifies upsell and cross-sell opportunities within existing customer accounts. Analyzes product usage, feature gaps, team growth, industry benchmarks, and competitive pressure to surface revenue expansion plays scored by potential, effort, and likelihood. Generates an expansion-playbook.md with account-by-account opportunities, recommended pitch, timing, and approach.