Skip to content
All articles
6 min read

TikTok Ads URL Parameters and Macros: Sub ID Setup for Tracking

Hand-etched campaign and creative signals passing through a tracking relay into a conversion ledger

TikTok Ads macros look simple until AID, CID and Smart+ ad IDs end up in the wrong tracker columns. The reliable setup is to map the stable hierarchy first, keep placement in a sub ID, and prove the expansion on a delivered click.

For a standard TikTok campaign, use this DarkCore parameter string:

campaign_id=__CAMPAIGN_ID__&adset_id=__AID__&ad_id=__CID__&sub1=__PLACEMENT__&sub2=__CAMPAIGN_NAME__&sub3=__AID_NAME__&sub4=__CID_NAME__

In a complete URL:

https://go.example.com/?campaign_id=__CAMPAIGN_ID__&adset_id=__AID__&ad_id=__CID__&sub1=__PLACEMENT__&sub2=__CAMPAIGN_NAME__&sub3=__AID_NAME__&sub4=__CID_NAME__

TikTok macros use two underscores before and after the token. They are case-sensitive. Meta-style {{campaign.id}} syntax does not work here.

TikTok’s official UTM and macro reference currently lists campaign, ad-group, creative, placement and upgraded Smart+ ad macros.

Incoming parameterTikTok macroActual levelDarkCore use
campaign_id__CAMPAIGN_ID__CampaignStable campaign key
adset_id__AID__Ad groupStable group/audience key
ad_id__CID__Creative in a standard structureGranular creative key
sub1__PLACEMENT__TikTok or Pangle placementPlacement reporting and routing
sub2__CAMPAIGN_NAME__Campaign labelHuman-readable context
sub3__AID_NAME__Ad-group labelHuman-readable context
sub4__CID_NAME__Creative labelHuman-readable context

The naming trap is AID: it means ad group ID, not ad ID. CID is the creative ID, not campaign ID. Copying the letters into similarly named columns without checking their definitions silently corrupts reporting.

Smart+ adds a separate ad level

Upgraded Smart+ has four reportable levels: campaign, ad group, ad and creative. TikTok documents __ADID_V2__ and __ADID_V2_NAME__ for the Smart+ ad bundle, while __CID__ and __CID_NAME__ identify the individual creative.

Use this Smart+ mapping:

campaign_id=__CAMPAIGN_ID__&adset_id=__AID__&ad_id=__ADID_V2__&sub1=__PLACEMENT__&sub2=__CAMPAIGN_NAME__&sub3=__AID_NAME__&sub4=__ADID_V2_NAME__&sub5=__CID__&sub6=__CID_NAME__

This keeps the Smart+ ad ID in DarkCore’s ad_id field and preserves the underlying creative ID in sub5. TikTok’s Smart+ reporting guide is the source of truth when the account UI and an older template disagree.

A four-level campaign hierarchy feeding separate attribution rails

Do not force standard and Smart+ campaigns into one ambiguous ad_id definition. Record which template the campaign uses and keep the mapping stable inside that campaign family.

TTCLID is not a replacement for the hierarchy

When a TikTok click reaches the destination with ttclid, DarkCore captures that click identifier. It helps preserve click continuity and attribution, but it does not tell an operator which campaign, ad group, placement or creative to optimize.

Think of the fields as two layers:

  • ttclid identifies the individual TikTok click when present.
  • campaign_id, adset_id, ad_id and the sub fields describe the advertising context around that click.

Do not hard-code a fake ttclid and do not put a campaign ID into a ttclid field. Let the platform supply the click identifier; use macros for the hierarchy.

Auto-attach versus a deliberate tracker template

TikTok’s URL parameter setup guide supports automatic UTM attachment and manual custom parameters.

Auto-attach is useful for GA-style acquisition reporting. It is not automatically a complete tracker mapping. If DarkCore needs campaign_id, adset_id, ad_id and sub1, add those custom keys deliberately and inspect the combined preview for duplicates.

A practical rule:

  • Keep auto-attached UTMs if another analytics system consumes them.
  • Keep tracker identity in dedicated DarkCore fields.
  • Do not define the same key twice with different values.
  • Use IDs as keys and names only as labels.

Passing the captured values to an offer

Once the click reaches DarkCore, an outbound Track Link can reuse the captured context:

https://affiliate.example/click?cid={click_id}&campaign={campaign_id}&adgroup={adset_id}&ad={ad_id}&placement={sub1}&creative={sub5}&ttclid={ttclid}

For a standard campaign, use the sub slot that actually contains the creative value; for Smart+, the example above reserves sub5 for __CID__.

TikTok expands __CAMPAIGN_ID__ before the landing request. DarkCore expands {campaign_id} and {click_id} only when constructing the outbound URL. If those two syntaxes are mixed, literal macros leak through the funnel.

The pass/fail launch test

Use a delivered or platform-generated test click, then verify facts rather than the appearance of the template.

TestExpected factPass?
Query stringOne ?, valid key=value pairs, later keys separated by &
TikTok expansionNo literal __CAMPAIGN_ID__, __AID__ or __CID__ remains
Campaign hierarchyCampaign and ad-group IDs land in the correct fields
Ad definitionStandard uses the documented creative mapping; Smart+ preserves ad and creative separately
Placementsub1 contains the delivered placement
Click identifierttclid is captured when TikTok supplies it
Outbound URLEvery required DarkCore macro expands once
ConversionOne test postback attaches to the same click without duplicate revenue

A live click being checked before validated values reach the attribution ledger

The final URL matters more than a clean-looking Ads Manager form. A literal macro in the click record means the platform did not expand it; an empty field means the key was omitted, renamed or lost on a redirect.

Common failures

AID is mapped as the ad ID

__AID__ is the ad-group ID. Putting it in ad_id makes every creative inside the group look identical in tracker reporting.

CID is treated as campaign ID

__CID__ is the creative ID. Campaign ID is explicitly __CAMPAIGN_ID__.

Smart+ ad and creative are collapsed

In upgraded Smart+, __ADID_V2__ and __CID__ describe different levels. Preserve both if you need to reconcile tracker and platform reporting.

Meta syntax is copied into TikTok

TikTok expects __CAMPAIGN_ID__, not {{campaign.id}}. If the wrong syntax survives as literal text, every click can be grouped under one useless placeholder value.

Only the page load is tested

A loaded landing page does not prove that the IDs were stored or that a postback can return to the original click. Test the full route. The S2S postback guide explains the conversion concept, the postback macro mapping guide covers click_id={subid}-style syntax, and DarkCore Streams covers routing and Track Links.

FAQ

Which TikTok macro should go into sub1?

Use sub1=__PLACEMENT__ in the recommended mapping. Campaign, ad-group and ad IDs have dedicated DarkCore fields.

What is the TikTok ad-group macro?

__AID__ is the ad-group ID and __AID_NAME__ is the ad-group name.

What is the difference between CID and ADID_V2?

__CID__ identifies a creative. In upgraded Smart+, __ADID_V2__ identifies the ad bundle above that creative level.

How many custom sub IDs can DarkCore capture?

DarkCore captures sub1 through sub10 and can reuse them as {sub1} through {sub10} in outbound Track Links.

  • tiktok ads macros
  • tiktok url parameters
  • tiktok sub id
  • ttclid
  • affiliate tracking