Campaign Link Validation — The Complete Guide

Campaign link validation is the practice of programmatically checking every campaign URL before it goes live — confirming that the destination resolves, the SSL certificate is valid, redirect chains don't strip your UTM parameters, and the landing page is ready for social sharing. Done right, validation is a single command that runs in seconds and catches the problems that cost marketing teams clicks, attribution data, and budget. This guide covers everything: what to check, why, how to do it from the terminal, how to automate it in CI/CD, and how to wire it into an AI agent workflow.

Validation checklist clipboard showing pass, warn, and fail states for ssl, resolution, redirects, og_tags, twitter_card, viewport, and utm_valid checks

What is campaign link validation?

Campaign link validation is a pre-publish quality check that runs against every URL you plan to share in a marketing campaign. Instead of manually clicking a link and hoping it works, validation programmatically verifies a checklist of technical requirements: the URL resolves with a 200 status, HTTPS is configured, redirect chains preserve your UTM parameters, and the landing page has the Open Graph and Twitter Card meta tags required for rich social previews.

Think of it as the marketing equivalent of a compiler check. You wouldn't ship code without verifying it compiles. You shouldn't publish a campaign link without verifying it passes a validation suite. The difference is that campaign link failures are invisible until after you've spent money — a 404 page, a stripped UTM parameter, or a missing og:image tag won't throw a runtime error. It will silently drain your budget while your analytics data deteriorates.

The validation workflow has three stages:

  1. Build — generate a UTM-tagged URL with consistent, properly formatted parameters
  2. Check — verify the destination URL resolves correctly with SSL, no broken redirect chains, and acceptable response time
  3. Inspect — confirm the landing page is social-sharing-ready with OG tags, Twitter Cards, viewport meta, canonical URL, and favicon

MissingLinkz runs all three stages in a single mlz preflight command. The result is a structured JSON report with a top-level ready flag that tells you (and any AI agent in your workflow) whether the link is safe to publish.

Why marketing teams skip campaign link validation (and what it costs)

Most marketing teams skip validation for three reasons: they don't have a tool for it, they trust that someone else checked it, or they assume that if the URL looks right it probably works. All three are expensive assumptions.

No dedicated tool
The standard marketing toolkit doesn't include a link validator. Google's Campaign URL Builder generates UTM links but checks nothing. UTM builder dashboards store your parameters but don't verify the destination. So teams build links in one tool, manually test in a browser, and publish — hoping the landing page behaves the same way in production as it did during their one manual click.
The "someone else checked it" assumption
In multi-person marketing teams, no one person owns link validation. The copywriter assumes the developer set up the landing page correctly. The developer assumes QA tested the redirects. QA assumes someone else checked the social preview. The result is a campaign where everyone assumed validation happened and no one actually did it.
The "it looks right" assumption
A URL can look completely valid — HTTPS, no obvious typos, the right domain — and still fail in ways that are invisible to manual inspection. A page that loads in 4 seconds looks fine in a browser but kills 20% of your conversions. An og:image tag pointing to an image that returns 404 won't show up in your browser but will render a blank preview on LinkedIn. Redirect chains that strip UTM parameters look like normal redirects when you click them. Validation catches these because it tests programmatically, not just visually.

The cost of skipping validation is documented. According to research cited in how broken campaign links waste ad budget, broken attribution affects the majority of marketing campaigns. Missing OG images reduce social post click-through rates by 2–3x. A single second of extra page load time costs roughly 7% in conversions. These aren't edge cases — they're the default outcome when validation is optional.

The 9 things every campaign link should be checked for

Not all checks are equal in importance, but all of them have a real failure mode. Here is the complete list of what every campaign link needs before it publishes:

1. SSL / HTTPS
The destination URL must use HTTPS. HTTP pages trigger browser security warnings that immediately erode trust. Paid traffic sent to an HTTP page is effectively wasted — most users bounce on sight of the "Not Secure" indicator. This is the simplest check and the most embarrassing to miss.
2. Resolution (HTTP status)
The URL must respond with a 200 OK. Checks against 404 not-found, 301/302 redirects as the final destination, 500 server errors, and completely unreachable domains. A 404 in a campaign is particularly damaging for paid channels where you pay per click regardless of whether the page exists.
3. Redirect chains
Every redirect hop is an opportunity to lose your UTM parameters and add latency. The check traces the full redirect path from the initial URL to the final destination, flags chains longer than one hop, and verifies that UTM parameters survive each hop intact. This is the check that catches the most insidious attribution problem in marketing: silently stripped parameters that show up as "direct" traffic in GA4.
4. Response time
Slow pages kill conversions. A threshold of 1.5 seconds triggers a warning; 3 seconds is a failure. This check uses actual HTTP response time, not simulated lab conditions, so it reflects what real users will experience when they click your campaign link.
5. Open Graph tags
Checks for og:title, og:description, and og:image. These three tags control how your link appears when shared on LinkedIn, Facebook, Slack, iMessage, and most other social surfaces. Missing any one of them degrades the preview quality. A missing og:image in particular means your post renders as a plain URL — no image card, no visual hook, dramatically fewer clicks. See the complete guide to checking OG tags for details.
6. Twitter Card tags
Twitter/X uses its own meta tag system separate from Open Graph. Checks for twitter:card, twitter:title, and twitter:description. Without these tags, your link renders as plain text in the X feed regardless of how well-configured your OG tags are.
7. Viewport meta tag
Confirms the page includes <meta name="viewport" content="width=device-width, initial-scale=1">. Pages without this tag render at desktop width on mobile devices, making them nearly unreadable. Given that over 60% of social traffic comes from mobile, a missing viewport tag is a conversion killer.
8. Canonical URL
Compares the page's <link rel="canonical"> value against the destination URL. A mismatch — for example, canonical pointing to https://example.com/landing while your campaign link uses https://example.com/landing/ — splits analytics data across two URLs and creates SEO confusion about which page to index.
9. UTM parameter integrity
Verifies that all required UTM parameters (utm_source, utm_medium, utm_campaign) are present, properly formatted, lowercase, and free of special characters that can break tracking. Also verifies they survive the full redirect chain intact. For naming consistency guidelines, see the UTM naming convention guide.

Manual validation vs. automated validation

Manual validation means clicking the link, viewing source, using the Facebook Debugger, and inspecting the browser's network tab. It works, takes 5–10 minutes per link, and checks maybe 3 of the 9 items above reliably. It doesn't scale to 20 campaign links. It doesn't run in CI/CD. It doesn't fit into an AI agent workflow.

Automated validation runs all 9 checks programmatically in under 3 seconds per URL. It produces machine-readable output (structured JSON) that can be consumed by CI pipelines, agent workflows, Slack bots, or any other downstream tool. It's consistent: it runs the same checks every time, with the same thresholds, and produces comparable results across campaigns.

The table below shows which checks each approach can reliably cover:

Check Manual (browser) Google URL Builder Automated (mlz)
SSL / HTTPS Visible Not checked Always
Resolution (200 OK) Visible Not checked Always
Redirect chain / UTM preservation Not visible Not checked Always
Response time ≈ Approximate Not checked Precise
Open Graph tags ≈ Via view-source Not checked Always
Twitter Card tags ≈ Via view-source Not checked Always
Viewport meta Not obvious Not checked Always
Canonical URL match Not obvious Not checked Always
UTM parameter integrity ≈ Partially ≈ Partially Always

The most important column is "Redirect chain / UTM preservation." Manual inspection and URL builders both fail this check because neither one programmatically follows redirect chains to verify parameter survival. Automated validation does this by default on every run.

How to validate a campaign link from the terminal

The fastest way to run campaign link validation is with mlz preflight. Install once, then run against any URL.

npm install -g missinglinkz

Then run a preflight check against your campaign landing page:

mlz preflight --url "https://example.com/landing" --campaign "spring-launch" --source "linkedin" --medium "social"

The command builds the tracked URL, validates the destination, and inspects the landing page metadata. The JSON response looks like this:

mlz preflight — JSON output
{
  "ready": true,
  "tracked_url": "https://example.com/landing?utm_source=linkedin&utm_medium=social&utm_campaign=spring-launch",
  "checks": [
    { "check": "og_tags",      "status": "pass", "message": "All essential Open Graph tags present." },
    { "check": "twitter_card",  "status": "pass", "message": "Twitter Card tags configured." },
    { "check": "viewport",      "status": "pass", "message": "Viewport meta tag present." },
    { "check": "ssl",           "status": "pass", "message": "URL uses HTTPS." },
    { "check": "resolution",    "status": "pass", "message": "Destination responded with 200." }
  ],
  "summary": { "total": 12, "passed": 12, "warnings": 0, "failed": 0 },
  "recommendation": "All checks passed. Campaign link is ready to publish."
}

The ready: true flag is the single signal your workflow needs to proceed. When ready: false, the checks array lists exactly which checks failed and why — no guessing about what broke.

You can also run destination validation or metadata inspection independently if you want narrower checks:

mlz check "https://example.com/landing"
mlz inspect "https://example.com/landing"

mlz check runs the URL-level checks (SSL, resolution, redirects, response time). mlz inspect runs the metadata checks (OG tags, Twitter Card, viewport, canonical, favicon). mlz preflight runs both, plus builds and stores the UTM link.

How to validate campaign links in CI/CD

For teams that manage campaign links in a repository — config files, spreadsheets exported as JSON, or any structured list of URLs — validation belongs in CI/CD. Every time the campaign config changes, the pipeline validates all affected links and fails the build if any check doesn't pass.

This is particularly valuable for agencies and performance marketing teams who manage large numbers of links across multiple campaigns. See the full guide at automating campaign link validation in CI/CD for working GitHub Actions and GitLab CI examples. The short version: use --format json to get machine-readable output, then parse the ready field and exit with a non-zero code on failure:

RESULT=$(mlz preflight --url "$URL" --campaign "$CAMPAIGN" --source "$SOURCE" --medium "$MEDIUM" --format json)
echo "$RESULT" | jq -e '.ready == true'

The jq -e flag causes a non-zero exit when the expression evaluates to false or null, which is exactly what you want for a CI gate. If ready is false, the pipeline fails and no broken links ship to production.

How to validate campaign links from an AI agent

AI agents can't reliably use web-form UTM builders. They can't fill out GUI forms, they can't navigate multi-step web UIs, and they can't read visual feedback. What they can do is call tools that accept structured input and return structured output. That's exactly what the MissingLinkz MCP server provides.

Start the MCP server:

mlz mcp

Add it to your MCP client config (Claude Code, Cursor, Claude Desktop, or any MCP-compatible agent):

MCP config
{
  "mcpServers": {
    "missinglinkz": {
      "command": "mlz",
      "args": ["mcp"]
    }
  }
}

Once connected, the agent can call mlz_preflight as a tool — passing the destination URL, UTM parameters, and post copy as structured arguments — and receive a JSON report with a ready verdict. The agent gets a clear go/no-go signal without touching a web form. For a full walkthrough of AI agent campaign link workflows, see why your AI agent can't use your UTM builder and how to build UTM links with an AI agent.

Common campaign link validation failures and how to fix them

These are the failures that show up most often when teams run validation for the first time:

Missing og:image
The most common failure. The landing page has og:title and og:description but no og:image. Fix: add a <meta property="og:image" content="https://yoursite.com/og-image.jpg"> tag pointing to an image that is at least 1200×630 pixels. Use an absolute URL, not a relative path. After adding the tag, re-run mlz inspect to confirm it's detected, then clear the Facebook Debugger cache if you've already shared the URL.
UTM parameters stripped in redirect
The URL resolves correctly but UTM parameters are missing from the final destination. This usually happens at a redirect from HTTP to HTTPS, from www to non-www, or through a URL shortener. Fix: update the campaign URL to target the final destination directly (skip the redirect chain), or configure the redirect to preserve query strings. If you're using a URL shortener, verify it passes through query parameters by checking its documentation.
Slow response time (> 1.5s warning, > 3s failure)
The page is slow to respond. This is a landing page performance problem, not a campaign link problem, but it still blocks a clean validation result. Fix: run a performance audit (Lighthouse, WebPageTest), address the largest contributors to load time (uncompressed images, render-blocking scripts, no CDN), and re-run validation. Don't publish a paid campaign to a page that's consistently above 3 seconds.
Canonical URL mismatch
The page's canonical tag points to a different URL than the one you're targeting. Often caused by a trailing slash discrepancy (/landing vs /landing/) or a CMS that hardcodes canonical URLs. Fix: either update your campaign link to match the canonical exactly, or update the page's canonical tag to match your campaign URL. Both values should be identical.
Missing Twitter Card tags
Open Graph tags are present but Twitter Card tags are absent. Twitter/X requires its own separate twitter:card meta tag; OG tags are not automatically read by X. Fix: add at minimum <meta name="twitter:card" content="summary_large_image"> along with twitter:title, twitter:description, and twitter:image. Use X's Card Validator tool to confirm after adding.
UTM parameter casing inconsistency
Parameters contain uppercase letters (utm_source=LinkedIn instead of utm_source=linkedin). GA4 treats these as different values, which fragments your data. Fix: enforce lowercase across all UTM parameters. MissingLinkz does this automatically when you build with mlz build or mlz preflight. See the UTM naming convention guide for a complete taxonomy.

Frequently asked questions

How is campaign link validation different from a link checker?
A standard link checker only verifies that a URL resolves (returns 200 vs. 404). Campaign link validation goes further: it checks SSL, follows redirect chains while verifying UTM parameter preservation, measures response time, inspects Open Graph and Twitter Card meta tags, checks viewport and canonical configuration, and validates UTM parameter formatting. The output is a structured report with a clear go/no-go verdict, not just a status code.
Do I need to validate every link in a campaign?
Yes, if the links go to different destination URLs or use different UTM sources. If you're sending the same URL to three different platforms (LinkedIn, X, newsletter), run validation once per source/medium combination because each generates a different tracked URL. Validation for the same base destination URL is fast — under 3 seconds — so the overhead is minimal relative to the cost of publishing a broken link.
Can validation catch a page that loads correctly in the browser but fails for some users?
Validation catches server-side issues that affect all users: missing meta tags, HTTP status codes, SSL configuration, response time, and redirect chains. It doesn't emulate browser-side rendering or test JavaScript-dependent content. If your landing page's OG tags are dynamically injected by JavaScript rather than in the static HTML, validation won't see them — which is itself a problem, since most social media crawlers don't execute JavaScript either.
How often should I validate campaign links?
Before every campaign goes live, and again if the destination URL or landing page changes. If you're running automated campaigns from a pipeline, add validation as a pre-deploy step so any change to a campaign config triggers a fresh validation run. For high-budget campaigns, consider re-validating 24 hours after launch to catch issues that develop after go-live (expired certs, CDN misconfigurations, A/B test interference).
Does MissingLinkz store my campaign links?
Yes, when you're authenticated with an API key. The mlz preflight command builds, validates, and stores the tracked URL so you can retrieve it later with mlz links list. For offline or unauthenticated use, UTM generation works without an API key but the link isn't stored. Free tier includes 50 links per month; paid plans start at $9/month for 2,000 links.

Try campaign link validation now

Install MissingLinkz and validate your next campaign link before it goes live. One command checks everything.

npm install -g missinglinkz
mlz preflight --url "https://yoursite.com/landing" --campaign "your-campaign" --source "linkedin" --medium "social"