Append nod_source and the nod_* join parameters to your ad platforms so nod. can match orders back to the exact ad and channel that drove them.
nod. matches orders back to ads by reading a handful of URL parameters that your ad platforms attach to the click. Add them once per platform and every ad you run afterward gets attributed at the ad level — and to the right channel — automatically.
nod_source to every platform you run ads on. It names the channel explicitly (meta, google, tiktok, microsoft, snapchat, linkedin, pinterest, x, reddit, chatgpt) so attribution never depends on a click id surviving or a referrer being guessed right.nod_adid, nod_adset, nod_campaign — nod_adid is the strong join key nod. uses to match an order to the exact ad.nod_source — it's the same string on every ad and only declares the channel. The ad-level identity there comes from the platform's own click id, captured automatically.utm_* parameters keep working. Append nod's string after yours with a leading &.gclid, fbclid, ttclid, msclkid, sccid, twclid, li_fat_id, epik, rdt_cid, oppref) are still captured as a fallback, but they break if a platform strips them or a link shortener rewrites the URL. nod_source doesn't depend on that.Click ids like gclid and fbclid are useful, but they are not guaranteed to survive the trip from ad click to landing page. Redirects, link shorteners, and some app-to-browser handoffs strip query parameters the platform doesn't own. When that happens, nod. loses the signal it had to identify which ad — and which channel — drove the visit.
nod_source solves the channel half of that problem: it names the network directly (meta, google, tiktok, and so on), in a format nod. controls, so classification never depends on a click id surviving or a referrer being parsed correctly.
nod_adid, nod_adset, and nod_campaign solve the ad-level half. nod_adid is the strong key — it's what nod. uses to join an order back to a specific ad, deterministically. nod_adset and nod_campaign group that ad into its ad set and campaign for reporting. Not every platform exposes click-time macros for these — where they don't, the platform's own click id carries the ad-level identity instead, and nod_source alone still guarantees the channel is right.
These parameters coexist with any utm_* parameters you already use for your own analytics. nod. reads both — they don't collide.
Paste this string:
nod_source=meta&nod_adid={{ad.id}}&nod_adset={{adset.id}}&nod_campaign={{campaign.id}}
Paste it into the ad's URL parameters field — not the destination URL. Meta strips query strings appended directly to the destination URL, so if you add this to the destination URL instead, it will not reach nod.
Paste this string:
nod_source=google&nod_adid={creative}&nod_adset={adgroupid}&nod_campaign={campaignid}
Paste it into the Final URL suffix field, at the account or campaign level (Settings → Account Settings → Tracking → Final URL suffix). {creative} resolves to the ad id and {adgroupid} to the ad group id. Google also auto-appends gclid to the URL — nod. captures that separately as a fallback, so you don't need to add it yourself.
Paste this string:
nod_source=tiktok&nod_adid=__CID__&nod_adset=__AID__&nod_campaign=__CAMPAIGN_ID__
Append it to the destination URL. TikTok expands the __…__ tokens at click time. ttclid is captured separately as a fallback.
Paste this string:
nod_source=microsoft&nod_adid={AdId}&nod_adset={AdGroupId}&nod_campaign={CampaignId}
Paste it into the Final URL suffix field, at the account or campaign level (Shared Library → Tracking template settings → Final URL suffix). {AdId}, {AdGroupId}, and {CampaignId} expand at click time. msclkid is auto-appended and captured separately as a fallback.
Paste this string into the ad's Website URL:
nod_source=snapchat&nod_medium=paid
Snapchat has no click-time URL macros, so this string is the same on every ad — it only declares the channel. sccid is auto-appended and captured separately as the fallback that carries the actual ad identity.
Append this string to the Destination URL:
nod_source=linkedin&nod_medium=paid
LinkedIn has no click-time URL macros, so this string is the same on every ad — it only declares the channel. li_fat_id is captured separately as the fallback.
Paste this string:
nod_source=pinterest&nod_adid={adid}&nod_adset={adgroupid}&nod_campaign={campaignid}
Append it to the Destination URL. Pinterest expands the {…} tokens at click time. epik is captured separately as a fallback.
Append this string to the Website URL:
nod_source=x&nod_medium=paid
X has no click-time URL macros, so this string is the same on every ad — it only declares the channel. twclid is captured separately as the fallback.
Append this string to the Destination URL:
nod_source=reddit&nod_medium=paid
Reddit has no click-time URL macros, so this string is the same on every ad — it only declares the channel. rdt_cid is captured separately as the fallback.
Paste this string into Landing page query parameters (per campaign):
nod_source=chatgpt&nod_medium=paid&nod_campaign={campaign_id}&nod_adset={ad_group_id}&nod_adid={ad_id}
OpenAI expands {campaign_id}, {ad_group_id} and {ad_id} at click time. oppref (OpenAI's own click id, appended to the landing URL at click time) is captured separately as the fallback.
One asymmetry to expect on this platform: the Advertiser API reports spend, impressions and clicks at campaign level only. The ad-set and ad ids still buy you deterministic attribution — nod. can tell you which ad group and which ad drove a lead or a sale — but there is no spend to divide by below campaign, so cost, CPA and ROAS are dashed on those rows rather than guessed. OpenAI syncs no ad-group or ad names either, so those rows label by raw id.
Whichever platform you're on, copy these strings exactly. The macro tokens ({{ad.id}}, {creative}, __CID__, and so on) are platform syntax that expands at click time — don't reformat, lowercase, or otherwise "clean up" them, or the platform won't recognize them.
nod_source doesn't have to be the exact channel slug. nod. normalizes common aliases (from ad platforms and anything organic) to a canonical channel, so you can paste whatever the platform's own naming convention is:
fb, ig, facebook, instagram, meta all resolve to Meta.google, adwords, googleads, youtube, yt all resolve to Google.tiktok, tt resolve to TikTok. Snapchat: snapchat, snap. Microsoft: microsoft, bing, msft. LinkedIn: linkedin, li. Pinterest: pinterest, pin. X: x, twitter. ChatGPT Ads: chatgpt, openai.newsletter, klaviyo, mailchimp resolve to Email; sms to SMS; whatsapp to WhatsApp; podcast to Podcast.A bare nod_source naming a known ad network mints a paid channel on its own — nod_source=fb mints meta_paid with no other signal required. A bare utm_source never does that: utm_source=facebook with no paid medium, no click id, and no nod_adid stays classified as organic social, so a share button that sets utm_source=facebook on an organic share doesn't get reclassified as a paid Meta ad.
But utm_source isn't exempt from normalization once a paid signal is already present. A click id, a paid utm_medium or nod_medium (cpc, paid_social, and similar), or nod_adid all trigger the same alias lookup on utm_source to pick the network — utm_source=fb&utm_medium=cpc mints meta_paid with no nod_source involved at all. nod_source is still worth adding on its own: it mints the paid channel outright, without needing a medium value set correctly or a click id to survive the trip.
Because nod_source is read before nod. falls back to click ids or referrer parsing, it guarantees the right channel even when a click id gets stripped by a redirect or a link shortener rewrites the URL.
If you already use utm_* parameters for Google Analytics or another tool, keep them. Append nod's string after yours with a leading &:
utm_source=meta&utm_medium=paid&nod_source=meta&nod_adid={{ad.id}}&nod_adset={{adset.id}}&nod_campaign={{campaign.id}}
nod. reads its own parameters and ignores the rest.
Once the parameters are live on an ad, click through it yourself (or wait for real traffic) and check the Tracking settings page for a recent event. Orders placed after the change carry the ad-level id and channel and show up attributed to that specific ad in your reporting — no separate activation step is needed.
{{Ad.ID}} or __cid__ won't expand and will be sent to nod. as a literal string instead of the actual ad id.nod_source left off on Snapchat, LinkedIn, X, or Reddit because "there's no ad id to carry anyway." Add it regardless — it's the only guaranteed channel signal on platforms without URL macros; the click id fallback covers the ad-level identity.nod_source or nod_adid added. Click ids still work as a fallback, but they're the parameters most likely to get stripped by redirects — the deterministic join and channel assignment only work when nod's own parameters are present.