A practical audit for campaign parameters
Trace UTMs, click IDs and custom fields through redirects, catch encoding mistakes and test the conversion return path before spending on traffic.

A campaign link can reach the right page and still produce an unusable report. The page opens, but the creative field is empty. Two spellings of the source split one channel into separate rows. A partner returns a conversion with an identifier that no longer matches the original visit.
These failures are hard to spot by looking at the landing page. They become easier to find when you treat the URL as a small, explicit data contract: which values enter, which values leave and which identifier comes back with a conversion.
Campaign parameters are the query fields a link carries between the ad and the destination: UTM labels, click identifiers and custom values.
This audit uses a fictional product campaign. The examples are ordinary web URLs, not a TapBaton endpoint specification or a partner’s macro syntax.
Key takeaways
- Campaign labels describe groups of visits; click identifiers connect one particular visit to a later conversion event.
- Assign an owner to every field and agree collision rules before two systems set the same parameter.
- Compare decoded names and values at every hop: source link, tracking link, redirects and final page.
- Test awkward values such as spaces, literal plus signs, ampersands and non-ASCII to expose a broken encoding step.
Separate campaign labels from individual identifiers
Campaign labels describe groups of visits. Click identifiers connect a particular visit to a later event. Both may travel in the same URL, but they answer different questions.
| Field in this example | Purpose | Example value |
|---|---|---|
utm_source |
Where the campaign was distributed | instagram |
utm_medium |
The marketing channel | paid_social |
utm_campaign |
A readable campaign label | autumn_bags |
utm_id |
A stable campaign identifier | cmp_204 |
utm_content |
The creative variant | video_blue_02 |
subid |
The visit identifier expected by this fictional partner | visit_7K2 |
Google documents the UTM fields and treats different capitalizations as different values. Its guidance recommends a consistent tagging scheme rather than varying labels from campaign to campaign. See Google Analytics’ campaign URL documentation.
The choice of subid here is deliberate: it illustrates a partner contract, not a universal standard. Your destination might require a different field. Write down the exact name, who supplies its value and the field in which it will return. Do not assume a platform click ID, your tracker’s visit ID and a partner transaction ID are interchangeable.
Build a small parameter inventory
Before testing, assign an owner to every field. The source platform may supply a click ID; your campaign template may supply UTMs; the tracking system may supply its own visit identifier; the destination may already contain a product variant.
Then define collision rules. Suppose the destination already contains utm_source=newsletter, while the incoming campaign says utm_source=instagram. Which value is intended? Appending both values postpones the decision until a receiving system interprets them.
Do the same for custom fields. A parameter called id is difficult to maintain if one team uses it for a product and another uses it for a visit. Prefer names that make the relationship clear, and keep an inventory even if it is only a short shared table.
Keep customer names, email addresses, access tokens and secrets out of this inventory of campaign URL fields. A URL is routinely copied into tickets and shared during debugging. An opaque visit reference is easier to handle than a link containing a customer’s details.
Compare the actual values at each hop
Check every hop against the inventory, comparing decoded values rather than the page that finally opens. Imagine this starting URL:
https://go.example/offer?utm_source=instagram&utm_medium=paid_social&utm_campaign=autumn_bags&utm_content=video_blue_02
The destination you intend to open is:
https://shop.example/bags/blue?variant=medium&utm_source=instagram&utm_medium=paid_social&utm_campaign=autumn_bags&utm_content=video_blue_02&subid=visit_7K2
Check the source link, tracking link, intermediate redirects and final page. At each point, compare decoded names and values with the inventory. Retain the original URL as well, because its encoded form can explain a failure.
For the example above, the acceptance criteria are concrete: variant remains medium, utm_content remains video_blue_02, and the partner receives visit_7K2 in its expected field. “The URL looks right” is too vague to be useful when someone else repeats the test.
Where a platform replaces dynamic macros, test a real generated click. A template that still contains a macro placeholder does not show what the platform actually sent. If a placeholder reaches the destination unchanged, investigate substitution before adjusting the receiving report.
Use awkward values on purpose
Simple letters and numbers can hide a broken encoding step. Add a small set of deliberate edge cases to a non-production test:
| Test value | What to check |
|---|---|
blue bag |
A space survives as a space after decoding |
summer+bonus |
A literal plus does not become a space |
A&B |
The ampersand stays inside the value |
Київ |
Non-ASCII characters survive the whole journey |
| An empty value | The receiver distinguishes your intended empty state from a missing field |
Use a URL parser when building URLs in code. With URLSearchParams, parsing a query string interprets a literal + as a space; setting a raw value through the API handles its encoding. Repeated fields are also possible: get() returns the first, while getAll() returns all of them. These behaviours are documented in MDN’s URLSearchParams reference.
For a team reviewing links manually, the lesson is simple: inspect decoded values and look for duplicate names. Repeatedly encoding an already encoded value can produce a different identifier even though the URL still opens.
A nested destination URL deserves its own test. If one query value contains another full URL, its separators must remain part of that value until the receiving system parses it. Avoid fixing these cases with a series of string replacements; identify which layer is responsible for decoding.
Test the fallback as a separate route
A primary route and its fallback can construct different destination URLs. Passing the primary test tells you nothing about a fallback that uses an older template.
Open the campaign from the source app and device combination you intend to buy. Check the preferred route. Then exercise the relevant fallback, such as the website route when a destination app is not installed. Compare both against the same inventory.
The Parameter Inspector can help you examine a copied URL, including repeated query keys. It parses the URL locally in your browser. It does not open the destination, inspect redirects or certify that a source app will preserve the parameters.
Close the loop with a returned event
Now create a test event using the destination’s supported test process. Record the visit identifier and the partner’s transaction identifier separately. Inspect the returned message and confirm that its visit reference matches the one the partner received.
If the final page had the correct visit ID but the returned event does not, focus on the destination’s storage and postback configuration. If the ID was already missing from the page, focus on the outbound route. This division avoids repeatedly changing a working redirect while the problem sits in a conversion template.
Before launch, keep one compact test record: original URL, final URL, expected fields, observed fields, test device and returned event reference. Repeat the check after changing a tracking domain, destination template, partner macro or fallback. Those are the points where a previously correct campaign contract can change without anyone touching the ad creative.
Frequently asked questions
What is the difference between a UTM and a click ID?
UTM fields are campaign labels that describe groups of visits. A click ID identifies one visit so a later conversion can be connected to it. Both travel in the same URL.
Why does one campaign source split into two rows?
Google treats different capitalizations as different values, so two spellings of the same source become separate rows. Use a consistent tagging scheme rather than varying labels per campaign.
Why is my click ID missing from the conversion?
Focus on the destination’s storage and postback configuration. If the identifier was already missing from the final page, focus on the outbound route instead.
Related
- UTM Builder: build tagged campaign URLs with consistent field names.
- Parameter Inspector: inspect a copied URL, including repeated query keys.
- Affiliates: keep the click ID available to your offer or network.
- Testing browser handoff: test how visitors reach the destination.
- Testing the conversion loop: follow the visit identifier into a returned conversion.