utm_campaign Parameter: How to Name and Track Marketing Campaigns in GA4

The utm_campaign parameter is the one UTM value that should appear identically on every link in a marketing initiative — the LinkedIn ad, the email send, the Google Ads campaign, and the organic social post. It answers the question: which campaign drove this traffic? When it's consistent, GA4 can aggregate cross-channel performance for a single initiative. When it's inconsistent — Q2-Launch on one channel and q2launch on another — the data fragments into unconnected rows and cross-channel attribution breaks entirely.

Four channel cards (LinkedIn, Google, Email, Facebook) each showing the same utm_campaign=q2-launch-2026 value, connected by dashed lines to a central campaign badge, showing how one campaign name ties attribution together across channels.

What utm_campaign is for

utm_campaign is the campaign identifier — the name of the marketing initiative that the link belongs to. It's the third most-parsed UTM parameter in GA4 after utm_source and utm_medium, and it's the one you use to answer questions like "how did our Q2 product launch perform across all channels?"

The key distinction from the other parameters:

  • utm_source names who sent the traffic (linkedin, google, newsletter)
  • utm_medium names how it was sent (cpc, email, organic)
  • utm_campaign names why it was sent — the initiative, promotion, or theme

Where utm_source and utm_medium vary per channel, utm_campaign stays the same across all channels for a single initiative. That's what lets GA4 roll up a Q2 launch's LinkedIn ad spend, email opens, and organic social clicks into one campaign view.

How to name utm_campaign values

GA4 is case-sensitive: Q2-Launch and q2-launch appear as two separate campaigns. The most common cause of campaign fragmentation in GA4 is inconsistent capitalisation across team members. Follow these rules and you won't have to clean up the data later:

Lowercase, hyphens only
Use q2-product-launch, not Q2 Product Launch, Q2_product_launch, or q2ProductLaunch. mlz build normalises your input to lowercase automatically, but consistent input prevents the error entirely. Hyphens are more readable in URLs than underscores and less likely to be confused with spaces.
Date-scoped where useful
Including the year or quarter prevents two similarly-named campaigns from colliding in GA4 reports. spring-sale-2026 is unambiguous; spring-sale used year after year creates a single row that aggregates data from multiple campaigns. Use q2-2026-launch or may-2026-newsletter for campaigns that repeat seasonally.
Initiative-scoped, not creative-scoped
The campaign name should describe the marketing initiative, not the specific ad creative or audience segment. If you're running five ad variations in a campaign, they all share the same utm_campaign value and use utm_content to differentiate the creative. If you're targeting two different audiences, they still share the same utm_campaign — audience segmentation belongs in ad platform reporting, not UTM parameters.
Agreed across the team
Document your campaign taxonomy. A shared naming sheet (or better, a programmatic taxonomy file) prevents the situation where the paid team tags a campaign as q2-launch and the email team tags it as q2-email-campaign. They'll appear as two separate campaigns in GA4.
Campaign type Poor utm_campaign value Better utm_campaign value
Seasonal sale Spring Sale spring-sale-2026
Product launch newProduct_Launch_Q2 q2-2026-product-launch
Newsletter MayNewsletter newsletter-may-2026
Retargeting retarget q2-2026-retargeting
Brand awareness brand brand-awareness-q2-2026

Building utm_campaign links from the CLI

The mlz build command takes a --campaign flag. It normalises the value to lowercase and appends it correctly in the output URL. Run the same command with different --source values to generate the cross-channel link set for a single campaign — the --campaign value stays identical across all of them.

mlz build — same campaign across three channels
# LinkedIn paid social
$ mlz build \
  --url "https://example.com/landing" \
  --source "linkedin" \
  --medium "cpc" \
  --campaign "q2-launch-2026"

{
  "tracked_url": "https://example.com/landing?utm_source=linkedin&utm_medium=cpc&utm_campaign=q2-launch-2026",
  "params": {
    "utm_source": "linkedin",
    "utm_medium": "cpc",
    "utm_campaign": "q2-launch-2026"
  }
}

# Google Ads — same campaign name
$ mlz build \
  --url "https://example.com/landing" \
  --source "google" \
  --medium "cpc" \
  --campaign "q2-launch-2026"
"tracked_url": "...?utm_source=google&utm_medium=cpc&utm_campaign=q2-launch-2026"

# Email newsletter — same campaign name
$ mlz build \
  --url "https://example.com/landing" \
  --source "newsletter" \
  --medium "email" \
  --campaign "q2-launch-2026"
"tracked_url": "...?utm_source=newsletter&utm_medium=email&utm_campaign=q2-launch-2026"

All three links share utm_campaign=q2-launch-2026. In GA4's traffic acquisition report, you can filter by campaign name to see the total sessions from the Q2 launch across all three channels in a single view — LinkedIn CPC, Google CPC, and email side by side.

utm_campaign vs utm_content vs utm_term

The three optional-ish UTM parameters get confused because they all add detail below the source/medium level. Here's how they differ:

utm_campaign — the initiative
Names the marketing initiative the link belongs to. Shared across all channels, creatives, and audience segments in that initiative. Use it to answer: "how did this campaign do overall?"
utm_content — the creative or placement
Differentiates individual elements within a single source/medium/campaign combination. Use it for A/B testing ad creatives or tracking which placement in an email was clicked. See utm_content parameter guide for full examples.
utm_term — the keyword
Records the paid search keyword that triggered the ad click. Specific to paid search channels where keyword-level attribution matters. See utm_term parameter guide for how it works with Google Ads and GA4.

A common mistake is encoding campaign details that belong in utm_content inside utm_campaign — for example, naming the campaign q2-launch-linkedin-blue-cta to track both the channel and creative variant. This prevents cross-channel aggregation (the Google Ads version would need a different campaign name) and inflates the campaign list in GA4. Keep campaign names at the initiative level and push variant details into utm_content.

How GA4 reports utm_campaign

In GA4, utm_campaign is mapped to the Session campaign dimension (also called Manual campaign name in some report views). To see campaign performance:

  • Go to Reports → Acquisition → Traffic acquisition
  • Change the primary dimension from "Session default channel group" to Session campaign

This shows each unique utm_campaign value as a row, with sessions, engaged sessions, and conversion data alongside. From here you can add a secondary dimension of Session source / medium to break down how each channel contributed to the campaign total.

If you see the same campaign appearing under multiple names (e.g., q2-launch and Q2-Launch as separate rows), you have a case consistency issue. Fix it at the source — in the links themselves — not by trying to merge the data in GA4. The mlz build --campaign flag automatically lowercases the value, preventing this class of error when link generation goes through the CLI.

Validating campaign links before publishing

UTM parameter naming consistency is one concern; destination readiness is another. A campaign link with a perfect utm_campaign value can still fail if the landing page returns a 404, the SSL cert has expired, or a redirect chain strips the UTM parameters before GA4 records the session. The --validate flag on mlz build runs these checks at build time:

mlz build --validate — build and check in one step
$ mlz build \
  --url "https://example.com/landing" \
  --source "linkedin" \
  --medium "cpc" \
  --campaign "q2-launch-2026" \
  --validate

{
  "tracked_url": "https://example.com/landing?utm_source=linkedin&utm_medium=cpc&utm_campaign=q2-launch-2026",
  "params": {
    "utm_source": "linkedin",
    "utm_medium": "cpc",
    "utm_campaign": "q2-launch-2026"
  },
  "validation": {
    "valid": true,
    "checks": [
      { "check": "ssl", "status": "pass", "message": "URL uses HTTPS." },
      { "check": "resolution", "status": "pass", "message": "Destination responded with 200." },
      { "check": "redirects", "status": "pass", "message": "No redirects detected." }
    ]
  }
}

For multi-channel campaign launches where you're generating links for LinkedIn, Google, and email simultaneously, run --validate on all of them before distributing to ad platforms and email systems. A broken landing page caught at link-build time is far cheaper than discovering it after a campaign has been running for 24 hours. See how to validate UTM links before publishing for the full pre-launch checklist.

FAQ

Is utm_campaign required?
Technically no — GA4 only requires utm_source and utm_medium for channel attribution. But without utm_campaign, you lose campaign-level aggregation entirely. You can see that LinkedIn CPC traffic came in but not which campaign it belonged to. For any campaign with more than one link, utm_campaign is effectively required for useful reporting.
Can two different campaigns share the same utm_campaign value?
Not intentionally. If two different marketing initiatives use the same utm_campaign value, GA4 will aggregate their traffic into a single row and you'll lose the ability to measure each initiative separately. Use distinct, initiative-specific names for every campaign — include the date or quarter if needed to ensure uniqueness.
Does utm_campaign affect GA4 channel groupings?
Not directly. GA4's default channel groupings are determined by utm_medium (and sometimes utm_source). A link with utm_medium=cpc maps to "Paid Search" or "Paid Social" regardless of what's in utm_campaign. The campaign name is a reporting dimension, not a routing rule.
What happens if utm_campaign has spaces or special characters?
Spaces and most special characters in UTM parameter values get percent-encoded in the URL (q2 launch becomes q2%20launch). GA4 decodes them for display, so you'll see "q2 launch" in reports, but the encoded form can cause issues in some ad platforms that parse URLs differently. Using hyphens avoids encoding entirely. mlz build validates the format before generating the URL.
How is utm_campaign different from the campaign name in Google Ads or LinkedIn Campaign Manager?
Ad platform campaign names are internal labels that live only in the ad platform. utm_campaign is the value that gets passed to your analytics tool via the URL. They don't have to match — but for clarity, most teams use the same value in both places. If your Google Ads campaign is named "Q2 2026 Product Launch," set utm_campaign=q2-2026-product-launch (lowercase, hyphens) for the corresponding UTM links.

Build utm_campaign links from the terminal

Pass --campaign "your-campaign-name" to mlz build and get a normalised, validated URL in one command. Values are automatically lowercased and hyphen-formatted so GA4 receives consistent campaign names every time.

npm install -g missinglinkz

Free plan: 50 links/month. No credit card. See the UTM tracking for developers guide for the full programmatic workflow.