Adobe Analytics Tracking Code vs UTM Parameters
Last updated · published
Adobe Analytics does not report UTM parameters the way GA4 does. Its campaign tracking runs on one dimension, Tracking Code, filled from whichever query string parameter your implementation captures, usually cid. The detail GA4 spreads across five UTM fields lives in Adobe as classifications: columns of metadata uploaded against each tracking code.
So the real decision is where your campaign metadata lives, and what keeps the link and the metadata in step.
TL;DR
- The Tracking Code dimension is populated by the campaign variable:
s.campaignin AppMeasurement,marketing.trackingCodein Web SDK XDM. It holds one value, up to 255 bytes.- Adobe does not fill Tracking Code from the URL by default. Capture
cid(or a UTM) with the getQueryParam plugin, the Analytics extension’s Campaign setting, or a Web SDK Query string parameter data element.- Classifications turn an opaque code into channel, region and campaign columns. Upload them through classification sets; Adobe set August 31, 2026 as the deprecation date for the legacy importer.
- During a GA4 and Adobe overlap, put both on the link:
cidfor Adobe, UTMs for GA4 and your agencies. Derive both from the same record so they cannot disagree.- A tracking code with no classification row reports as a string nobody can read. Plan the upload before the campaign launches.
What the Tracking Code Dimension Is
Adobe’s Tracking Code dimension lists the tracking codes collected on your site. It is populated by the campaign variable, sent in image requests as v0.
A few properties matter before you design anything:
| Property | Value |
|---|---|
| AppMeasurement variable | s.campaign |
| Web SDK XDM field | xdm.marketing.trackingCode |
| Web SDK data object field | data.__adobe.analytics.campaign |
| Maximum length | 255 bytes, truncated beyond that |
| Behaves like | an eVar, per Adobe’s campaign variable reference |
| Expiration | based on when the value was set |
Expiration is one reason your Tracking Code report and your Marketing Channels report disagree. Adobe lists three. An earlier Marketing Channel processing rule (Social Networks, say) can claim the hit before your tracking code rule runs. Channel credit can move to a later visit under last touch. And the two expire differently: marketing channels use a rolling 30-day visitor engagement window, while a tracking code expires relative to the moment it was set. Different rules, different clocks. Expect different numbers.
And look at what is missing from the table. Source. Medium. Content. Adobe gives you a single slot, and everything else about the campaign has to be packed into that value or attached to it later.
UTMs Spread the Metadata, Tracking Codes Look It Up
A UTM-tagged link carries its own description. utm_source=google&utm_medium=cpc&utm_campaign=q3_launch arrives in GA4 already split into three reportable fields. (For the GA4 side in depth, see how utm_campaign, utm_medium and utm_source work in Google Analytics.)
An Adobe tracking code usually carries a key. The description sits in a classification file somewhere else.
| UTM parameters (GA4) | Tracking code (Adobe Analytics) | |
|---|---|---|
| Where the metadata lives | In the URL, one parameter per field | In classifications keyed to the code |
| Fields at collection | Five classic parameters, plus utm_id and utm_source_platform in GA4 | One value |
| Fixing a wrong value | Collected as sent; fix it downstream | Correct the classification row; reports apply it to every date the code appears |
| URL length | Grows with every field | Stays short |
| Typical failure | Free-typed spelling variants | Codes that never got a classification row |
Neither model wins in the abstract. Tracking codes buy short URLs and correctable metadata, and they pay for it with a second artifact somebody has to maintain. UTMs need no upload, and every typo is permanent.
Adobe teams we talk to tend to pack a lot into that one value. Some encode five or six fields into a single cid to keep URLs short. Others put a channel prefix at the front so an analyst can filter on “begins with” before any classification exists. Some run several codes per campaign that differ only by a numeric suffix, one per placement.
Decide What the Code Itself Means
Before any implementation work, pick one of two designs.
Meaningful codes. The fields are in the value, in a fixed order: ps-na-q3_launch-1042 for paid search, North America, the Q3 launch, placement 1042. Hyphens separate segments and underscores join words inside one. Skip colons and pipes, which many link tools percent-encode and Adobe’s Marketing Channel processing rules do not decode. These codes survive a missed upload, because an analyst can still read them, and rules can parse them. They also break the moment someone reorders a segment or types a region the convention never listed.
Opaque codes. A sequential or random ID, 1042, with every attribute in the classification file. Short, never needs renaming, and meaningless until the upload lands.
If your classification uploads lag behind launches, use meaningful codes. If uploads are reliable and URL length matters more, use opaque ones.
Most teams end up in between. A readable channel prefix, then an ID, gives you the “begins with” filter on day one and gives your Marketing Channel processing rules a prefix to match on the cid query string parameter. The classification handles the rest.
Whichever you choose, the parsing is the same problem as any packed campaign field. The cid section of our marketing taxonomy guide shows how a structured cid breaks into classifications, and the data teams chapter covers positional and key-value parsing in a warehouse.
Capture the Parameter Into Tracking Code
Adobe does not copy cid, utm_campaign or anything else from the URL into the campaign variable on its own. Your implementation has to. Pick the route that matches how you deploy Adobe.
AppMeasurement, in code. The getQueryParam plugin extracts a query string value:
// Tracking code from ?cid=
s.campaign = getQueryParam('cid');
The plugin takes a comma-delimited list of parameters, an optional delimiter for when several match, and an optional URL to read instead of the current page. Two caveats from Adobe’s own page. Adobe Consulting provides it, and Adobe Customer Care does not support it. And for simple query string needs, Adobe recommends the URL parameter features in the Web SDK or the Analytics extension instead.
The Adobe Analytics extension in Tags. In a Set Variables action, the Campaign setting accepts either a fixed value or a query parameter name. Type cid and you are done.
The Web SDK. Create a data element of type Query string parameter with the parameter name (no ? or =). Map that data element to marketing.trackingCode in your XDM object. Adobe’s XDM variable mapping lists that field as the one that sets the Tracking Code dimension, and fields in the Adobe Analytics ExperienceEvent Template field group map without extra configuration.
Processing rules, when you cannot touch the implementation. In Admin, a rule can overwrite Campaign with a query string parameter when Campaign is not already set. Adobe treats this as the fallback, so use it until the implementation catches up.
Want raw UTM values in Adobe too? Capture them the same way into eVars. Mind the limits: eVars stop at 255 bytes in reports, props at 100 bytes.
Then test it. Load a landing page with ?cid=test-0001 and confirm the value arrives before you tag a single live link.
Classifications: Put the Metadata on the Code
A classification categorizes the values of a dimension so you can report on them in different ways. Tracking Code is one of the dimensions you can classify, and one code can carry many classification columns: channel, region, campaign name, agency, fiscal quarter.
Classifications are not stamped onto hits when they are collected. Adobe applies them when a report runs, across any date range where the code appears, so a corrected row fixes last year’s reports too. That cuts both ways. Fix a typo and history improves. Change what a code means and history changes with it.
Adobe now manages this through classification sets. The older tools are on their way out:
- The legacy Classification importer had a deprecation date of August 31, 2026.
- The Classification Rule Builder is scheduled for deprecation on February 28, 2027.
If your upload process still depends on the old importer or its FTP route, move it now.
A move to Customer Journey Analytics does not strand this work. Classifications become lookup datasets there, and Adobe’s Analytics Classifications source connector brings them across, so the convention you define now carries over as a table.
Three terms to know in a classification set:
- Key dimension: the dimension you are classifying, here Tracking Code.
- Classifications: the attribute columns you add to the set’s schema.
- Subscriptions: each pairing of a report suite and a key dimension. One set can serve several report suites.
The upload itself is short. Go to Components > Classification sets, open your set, and add the columns on the Schema tab. Download a template (comma separated or tab separated, UTF-8 or Latin-1). Fill it in with the key in the first column and your classification names in the header row:
Key,Channel,Region,Campaign,UTM Source,UTM Medium
ps-na-q3_launch-1042,Paid Search,North America,q3_launch,google,cpc
em-na-q3_launch-1043,Email,North America,q3_launch,newsletter,email
Then Upload, check the preview, and decide on Overwrite data on conflict. Checked, your file replaces existing values for matching keys. Unchecked, existing values stay. Classification sets also accept JSON, and a cloud location can automate recurring uploads.
Two cautions.
Pre-classifying has a price, usually a small one. Adobe’s classification importer FAQ says each dimension item classified before it is collected counts as a billable server call. One call per code is trivial for a launch’s worth of rows. It adds up when someone bulk-loads every code a generator could ever produce. Upload each campaign’s rows shortly before it launches.
Rules are powerful and blunt. A classification rule can overwrite existing keys, so a loose regular expression reclassifies codes it was never meant to touch. Adobe recommends testing rules before activating them. Rules suit meaningful codes, where the attributes can be parsed out of the value. Opaque codes need uploads. Rules also only reach codes collected within their lookback window: typically one month in the legacy Rule Builder, and a choice of one to six months in classification set rules.
Now name the failure. We call it the orphan code: a tracking code live in URLs with no classification row behind it. It reports as a bare string, falls into Unspecified in every classified breakdown, and shrinks whichever campaign it belonged to.
Every orphan code is a campaign someone paid for that no classified report can find.
Put cid and UTMs on the Same Link
Plenty of Adobe teams also run GA4, some permanently and some for a migration window. Others work with agencies that report from ad platforms or their own analytics and never see the client’s Adobe instance. One Adobe team described that split to us: Adobe owns the house reporting, and UTMs exist because the partners need them.
Put both on the link:
https://www.example.com/pricing/?cid=ps-na-q3_launch-1042&utm_source=google&utm_medium=cpc&utm_campaign=q3_launch&utm_id=1042
On paid platforms, keep the parameters out of the landing page URL itself. Google Ads and Microsoft Advertising take them in a Final URL suffix, which you can set at the account, campaign, ad group or ad level. Set it at the level your cid identifies, because a suffix set higher up gives every ad beneath it the same code. Meta takes them in the URL parameters field on each ad. Google Ads auto-tagging adds gclid, which GA4 reads and Adobe does not, so the manual parameters still carry the Adobe side.
If a partner controls the URL and will only pass UTMs, build the tracking code from them instead: concatenate utm_source, utm_medium and utm_campaign into the campaign variable in a Tags data element. You lose the short code, and every free-typed UTM variant becomes its own row to classify.
Then hold to these.
Derive both from one record. The cid and the UTM values have to describe the same campaign. If one person types the code and another types the UTMs, they drift within a quarter, and two analytics platforms tell two stories. Generate both from the same fields.
Share a join key. Put the same identifier in the ID segment of cid and in GA4’s utm_id. When the platforms disagree, you line up rows instead of arguing about them.
Put the UTM values in the classification file. Add UTM Source and UTM Medium columns, as in the template above. Adobe reports can then group by the same source and medium values GA4 shows, without collecting a second set of variables.
Watch the length. Every UTM you add grows the URL, and some channels (SMS, print, QR codes) punish long links. A short link in front of the tagged URL fixes that.
One law holds through all of it. Never rename a live code. Once a cid is in a published URL, it is permanent. Rename it and the Tracking Code report splits one campaign across two codes, and classified reports only rejoin them if someone remembers to give the new code an identical row. Fix wrong metadata in the classification file instead, knowing the fix rewrites every past date. If a code needs to mean something new, mint a new code, and never recycle a retired one.
Keep the Code and the Classification File in Step
Everything above reduces to one maintenance problem. Two artifacts, the link and the classification row, describe the same campaign, and nothing in Adobe checks that they agree.
The usual setup is a spreadsheet that builds the code with a formula and doubles as the upload file. It works until someone edits a formula, sorts one column without the others, or builds a link outside the sheet. The tools and platforms chapter of our guide explains why a builder alone does not solve this and a governed system does.
Terminus, the marketing taxonomy governance platform, fits here, and we want to be precise about how. Terminus has no native Adobe integration. What a governance model does is generate the cid consistently, as a concatenated field assembled from governed picklist values, and hold the classification columns (channel, region, campaign, UTM source and medium) as fields on the same record. Pattern validation holds casing and allowed characters inside the convention, and uniqueness checks across every record stop two campaigns from sharing one code. Export the records to CSV, rename the headers to match your classification template, with Key first, and upload.
The link and the classification row come from one record. They cannot disagree.
See how a governance model assembles values in the no-signup playground, or start from a template.
FAQ
What is a tracking code in Adobe Analytics?
A tracking code is the value collected in the campaign variable, which populates the Tracking Code dimension. It is usually read from a query string parameter such as cid. Adobe does not assign it; your team decides what it contains.
Does Adobe Analytics read UTM parameters automatically?
Not into Tracking Code. Your implementation has to capture them, using the getQueryParam plugin in AppMeasurement, the Campaign setting in the Analytics extension, a Query string parameter data element in the Web SDK, or, as a fallback, a processing rule that copies the parameter into Campaign. You can capture utm_campaign into Tracking Code, or individual UTM values into eVars.
Do classification changes apply to past data?
Yes. Adobe applies classifications at report time to any date range in which the code appears, so an uploaded correction changes historical reports too. Fix metadata in the classification file, and never rename the code.
Should I use cid or UTM parameters with Adobe Analytics?
If Adobe is your only analytics platform, a cid plus classifications keeps URLs short and lets you correct metadata after launch. If GA4, ad platforms or agencies also need to read the link, use both, generated from the same record.
How do I upload classifications for tracking codes?
Open Components > Classification sets, add your classification columns on the set’s Schema tab, download the template, fill it in with the tracking code in the Key column, and upload it. Choose whether to overwrite existing values on conflict.
Is the Adobe classification importer still available?
Adobe set August 31, 2026 as the deprecation date for the legacy Classification importer, and February 28, 2027 for the Classification Rule Builder. Classification sets replace both.
Why don’t my Tracking Code and Marketing Channels reports match?
They expire differently. Marketing channels use a rolling 30-day visitor engagement window, while a tracking code expires based on when it was set. Processing rule order and last-touch logic add further differences.
How long can an Adobe tracking code be?
The campaign variable accepts 255 bytes and truncates anything longer. Delimiters and multibyte characters count toward the limit.
Does Terminus integrate with Adobe Analytics?
Not natively. A Terminus governance model can generate the cid and the classification columns from the same governed fields, and a CSV export feeds the classification upload.
Every account starts with a 21-day trial, no credit card required.