← Learn

Advertising Click IDs & Cookies: The 2026 Reference

A current reference to the click IDs, browser IDs, first-party cookies, storage formats, lifetimes, and upload requirements used by ten advertising platforms in 2026.

Lester Visser
Tracking Specialist
Updated · 12 min read

What is an advertising click ID?

An advertising click ID is a platform-issued identifier for one paid ad click. Capture it when the visitor lands, persist it beyond the landing page, and send it back when an offline conversion occurs. The platform uses that identifier to connect the conversion with its recorded click and credit the correct campaign, ad, and keyword or audience.

Click ID vs browser ID

A click ID identifies one paid ad click. It exists only when the visitor arrives through an eligible ad and carries the information needed for campaign attribution.

A browser ID identifies a browser, not a click. A platform pixel can assign one to every visitor, including direct and organic traffic. Sending it through a conversions API can improve matching when no click ID is available, but it cannot identify which campaign should receive credit.

The distinction changes your collection logic. The presence of _ttp, for example, does not prove that a visit came from TikTok. An organic visitor can receive the same browser cookie. Use click IDs for attribution. Treat browser IDs only as additional matching signals.

Every identifier at a glance

The table separates identifiers for individual ad clicks from browser-level matching identifiers. Its format and extraction columns show what to store, not merely which landing-page parameter to detect.

PlatformIdentifierTypeURL parameterCookieServer-sideLifetimeWhat to extract
Google AdsgclidClick IDgclid
_gcl_aw
FPGCLAW90 daysDot-separated container, GCL.<timestamp>.<id>. Take the last segment. The server-side cookie instead wraps the ID between ".k" and "$i".
gbraidClick IDgbraid
_gcl_ag
FPGCLAG90 daysWrapped between ".k" and "$i" — not dot-separated like its siblings, even in the browser cookie.
wbraidClick IDwbraid
_gcl_gb
FPGCLGB90 daysDot-separated container. Take the last segment.
dclidClick IDdclid
_gcl_dc
FPGCLDC90 daysDot-separated container. Take the last segment.
_gcl_auBrowser ID
_gcl_au
90 daysSend the raw cookie value.
Meta (Facebook & Instagram)_fbcClick IDfbclid
_fbc
90 daysSend the whole cookie, not the bare fbclid. Four dot-separated parts: version.subdomainIndex.creationTime.fbclid — version is always "fb", subdomainIndex counts the domain level the cookie sits on (com = 0, example.com = 1, www.example.com = 2), creationTime is a UNIX timestamp in milliseconds.
_fbpBrowser ID
_fbp
90 daysSend the raw cookie value. Same four-part shape as _fbc — version.subdomainIndex.creationTime.randomNumber — but the last part is a number the Meta Pixel generates, not a click ID.
Microsoft AdvertisingmsclkidClick IDmsclkid
_uetmsclkid
uet_msclkid90 daysStrip the leading literal "_uet" from the value: _uet561f11b5eb0d… must be sent as 561f11b5eb0d…. The server-side cookie carries no prefix.
_uetvidBrowser ID
_uetvid
uet_vid390 daysSend the raw cookie value.
TikTok AdsttclidClick IDttclid
ttclid
30 daysSend the raw value.
_ttpBrowser ID
_ttp
13 monthsSend the raw value.
LinkedIn Adsli_fat_idClick IDli_fat_id
li_fat_id
90 daysSend the raw value.
Snapchat AdssccidClick IDScCid
_scclid
1 yearSend the raw value.
_scidBrowser ID
_scid
1 yearSend the raw value.
Reddit Adsrdt_cidClick IDrdt_cid
_rdt_cid
rdt_cid
30 daysSend the raw value. Read _rdt_cid first and fall back to rdt_cid.
_rdt_uuidBrowser ID
_rdt_uuid
30 daysFormat is <timestamp>.<uuid>. Reddit’s documentation describes sending the whole value; some implementations send only the UUID half. Decide deliberately.
Pinterest AdsepikClick IDepik
_epik
1 yearSend the raw value.
X (Twitter) AdstwclidClick IDtwclid
twclid
90 daysSend the raw value.
OpenAI (ChatGPT Ads)opprefClick IDoppref
__oppref
30 daysSend the raw value.
__obrefBrowser ID
__obref
365 daysSend the raw value.

Server-side cookies are written over HTTP as HttpOnly — readable by your server, never by JavaScript.

Platform by platform

Meta: fbclid, _fbc and _fbp

Meta’s landing-page value is not the value sent through the Meta Conversions API. The browser converts it into _fbc, a structured value that must be sent whole.

Preserve the cookie when it exists. If you generate it yourself, its timestamp must represent the click, not the later form submission or CRM update. _fbp has a similar shape but identifies the browser and cannot replace _fbc for attribution.

_fbcClick ID_fbpBrowser ID
  • _fbcWhen _fbc is absent you may build it from the fbclid — but creationTime must be the moment of the click, not of the conversion. Built later, server-side at form submit, it stamps the wrong time, looks perfectly valid and attributes wrongly. Meta says to use 1 for subdomainIndex when generating the value on a server without saving a cookie.

Sources: Meta — fbp and fbc parameters

Microsoft Advertising: msclkid and _uetmsclkid

Microsoft Advertising persists its click identifier in a cookie whose stored value includes an extra literal prefix. Strip that prefix before sending the identifier back through Microsoft Advertising.

Microsoft publishes the parameter and cookie names but does not document this stored prefix. Because the unprocessed value still resembles an identifier, incorrect implementations often reach production without producing an obvious parsing error.

msclkidClick ID_uetvidBrowser ID
  • msclkidMicrosoft rejects the prefixed form. Because the value still looks like a plausible ID, this fails as silently rejected uploads rather than an error you notice.

Sources: Microsoft — Universal Event Tracking · Microsoft Advertising — offline conversions

LinkedIn Ads: li_fat_id

LinkedIn can append li_fat_id when enhanced conversion tracking is enabled and the click is eligible. LinkedIn describes it as a first-party click identifier used to connect conversions with ads.

Capture it before navigation or form handling removes the landing query string. The absence of a separate browser identifier here does not change the role of the click ID: it remains the attribution key for LinkedIn Ads.

li_fat_idClick ID
  • li_fat_idLinkedIn calls it a "first party ads tracking UUID" rather than a click ID, but it is only appended on ad clicks. Treat it as a click ID while remembering it is not a pure click signal.

Sources: LinkedIn — Enabling Click IDs (first-party cookies)

Snapchat: ScCid, _scclid and _scid

Snapchat uses different capitalization for the landing-page parameter and the cookie written from it. Preserve the exact capitalization when reading the query string.

This is a collection failure, not a later attribution mismatch. Query-string keys are case-sensitive, so normalizing the parameter name to lowercase can make every paid Snapchat arrival look as though it has no click ID. The browser identifier remains a separate matching signal.

sccidClick ID_scidBrowser ID
  • sccidThe URL parameter is ScCid, with capitals, while the cookie is _scclid. Query string parsing is case-sensitive, so a lookup for "sccid" silently returns nothing on every single click.

Sources: Snapchat — Conversions API parameters · Snapchat — Conversions API overview

Reddit Ads: rdt_cid and _rdt_uuid

Reddit’s click ID connects a conversion with a specific ad interaction. Its browser identifier serves a different purpose and must not be treated as proof of a paid Reddit visit.

The click ID has a comparatively short attribution lifetime. Store the original click time alongside the identifier so you can reject stale CRM conversions before attempting an upload that the platform will no longer accept.

rdt_cidClick ID_rdt_uuidBrowser ID
  • rdt_cidrdt_cid without the underscore is the deprecated cookie. Reading only the new name loses returning visitors who still hold the old one.
  • _rdt_uuidA browser may hold more than one _rdt_uuid. Where implementations disagree, the convention is to take the one with the oldest timestamp.

Sources: Reddit — pixel and Conversions API parameters

X Ads: twclid

X uses twclid to connect an eligible website visit with its originating ad click. Capture the value from the landing URL and persist it beyond the first page rather than depending on the query string at conversion time.

twclidClick ID

Sources: X Ads API — web event tracking

OpenAI: oppref and __obref

OpenAI uses oppref for click-level attribution and a separate browser identifier for matching. Do not infer paid traffic from the browser identifier alone.

Its click identifier has a relatively short usable lifetime. Retain the click timestamp with the value so delayed conversions can be checked before upload.

opprefClick ID__obrefBrowser ID

Sources: OpenAI — Ads Conversions API

Maintaining this yourself vs. using a tool

Capturing these identifiers is a small piece of code. Keeping it correct is the ongoing part, and it is where most setups quietly degrade. Every rule on this page is one a platform can change: a cookie gets renamed, a new ad surface introduces a new identifier, a stored value gains a prefix. None of those changes announce themselves. The collector keeps running, the uploads keep returning success, and the match rate drifts down over months.

Building it yourself is reasonable when one or two platforms matter and someone owns the code. Budget for reviewing the extraction rules a few times a year and for monitoring match rates per platform, because a silent parsing failure looks identical to a quiet quarter.

The alternative is a tool that captures and normalizes the identifiers for you and keeps the rules current. LeadTrackr does this: every click ID and browser ID listed above, read from the URL or the cookie, stored with the lead and sent back to the ad platform when the deal closes. Which route makes sense depends on how many platforms you run and whether maintaining parsing rules is work your team wants to own.

Four parsing mistakes that fail silently

Four parsing mistakes account for most silent failures.

  1. 1.Parsing gbraid like the other Google identifiers

    The containers for gclid, wbraid, and dclid place the identifier in the final dot-separated segment. gbraid sits inside _gcl_ag, between .k and $i. Splitting on dots and taking the last segment returns a mangled value rather than an empty result. The parser appears to work, but the uploaded identifier does not.

  2. 2.Uploading Microsoft’s stored prefix

    _uetmsclkid stores a value beginning with the literal _uet. Microsoft accepts only the identifier after that prefix. Strip it before storage or upload. Leaving it attached produces a plausible-looking value that Microsoft rejects without making the extraction error obvious.

  3. 3.Lowercasing Snapchat’s parameter

    The landing parameter is ScCid; its cookie is _scclid. Query-string lookup is case-sensitive. Searching for sccid therefore returns nothing on every qualifying click, while the rest of the collection code continues normally.

  4. 4.Building Meta’s _fbc incorrectly

    Meta specifies four fields: version.subdomainIndex.creationTime.fbclid. The version is fb. The subdomain index records the cookie’s domain level: com is 0, example.com is 1, and www.example.com is 2. The creation time is the click time as a Unix timestamp in milliseconds. The final field is the original fbclid.

    Send the complete _fbc, never the bare landing-page value. _fbp follows the same four-field shape but ends with a pixel-generated random number. If _fbc is missing, you may construct it. Do not stamp it at form submission: that records the conversion time instead of the click time. Meta specifies a subdomain index of 1 when a server generates the value without saving a cookie.

Reading every click ID in one pass

URL parameter first, then the platform’s cookie. Three of these need more than a plain read: Snapchat’s capitalization, Microsoft’s prefix, and Google’s two container formats.

function readCookie(name) {
  const prefix = name + '=';
  for (const part of document.cookie.split('; ')) {
    if (part.indexOf(prefix) === 0) return part.slice(prefix.length);
  }
  return '';
}

const params = new URLSearchParams(location.search);

// URL parameter wins: it is the freshest copy, and it is there even when the
// platform's pixel has not written its cookie yet.
function clickId(urlParam, ...cookieNames) {
  const fromUrl = urlParam && params.get(urlParam);
  if (fromUrl) return fromUrl;
  for (const name of cookieNames) {
    const value = readCookie(name);
    if (value) return value;
  }
  return '';
}

const ttclid   = clickId('ttclid', 'ttclid');
const epik     = clickId('epik', '_epik');
const twclid   = clickId('twclid', 'twclid');
const liFatId  = clickId('li_fat_id', 'li_fat_id');
const oppref   = clickId('oppref', '__oppref');

// Snapchat capitalizes its parameter. Query keys are case-sensitive, so
// 'sccid' would return nothing on every single paid click.
const scclid = clickId('ScCid', '_scclid');

// Reddit renamed its cookie; returning visitors still carry the old one.
const rdtCid = clickId('rdt_cid', '_rdt_cid', 'rdt_cid');

// UET writes the cookie's own name into the value: '_uet561f11…' has to be
// sent as '561f11…'. Microsoft rejects the prefixed form.
const msclkid = clickId('msclkid', '_uetmsclkid').replace(/^_uet/, '');

// Google uses two container formats. gbraid is the exception: its browser
// cookie carries the server-side format, so parsing it like _gcl_aw returns
// a mangled value rather than an empty one.
function unwrapGcl(value, serverFormat) {
  if (!value) return '';
  if (serverFormat) return (value.match(/\.k(.+)\$i/) || [])[1] || '';
  if (!value.includes('.')) return '';
  return value.split('.').pop();
}

const gclid  = params.get('gclid')  || unwrapGcl(readCookie('_gcl_aw'), false);
const wbraid = params.get('wbraid') || unwrapGcl(readCookie('_gcl_gb'), false);
const gbraid = params.get('gbraid') || unwrapGcl(readCookie('_gcl_ag'), true);
const dclid  = params.get('dclid')  || unwrapGcl(readCookie('_gcl_dc'), false);

// Meta is the exception: send the whole _fbc cookie, never the bare fbclid.
const fbc = readCookie('_fbc');
const fbp = readCookie('_fbp');

Server-side cookies are missing here on purpose. FPGCLAW, uet_msclkid and the rest are written over HTTP as HttpOnly, so document.cookie never contains them. Read those on your own server instead.

Lifetimes and what each API accepts

An identifier’s lifetime determines whether a delayed CRM conversion can still be attributed. TikTok, Reddit, and OpenAI use roughly 30-day windows, while Snapchat and Pinterest retain eligible identifiers for about a year. That difference matters for long sales cycles: successful capture does not guarantee that a later upload remains valid.

Store the click time with the identifier and check platform limits before sending. An expired identifier is rejected; refreshing its timestamp does not extend the original click’s eligibility.

Google Ads also separates identifiers by destination API. Its ClickConversion resource accepts gclid, gbraid, and wbraid. It does not accept dclid. That identifier belongs to Campaign Manager 360 and Display & Video 360 workflows, which use a separate API. Sending every Google-family identifier through one upload path therefore fails even when extraction is correct.

FAQ

Frequently asked questions

UTM parameters are labels added by an advertiser to describe source, medium, campaign, or creative. A click ID is generated by the advertising platform for one recorded click. UTMs remain useful for analytics and reporting, but they cannot upload an offline conversion. The ad platform has no click record keyed to your UTM values, so it cannot use them as an attribution identifier.
Yes. The URL parameter exists only on the landing request. It can disappear after navigation, a redirect, or a later visit. The first-party cookie preserves a copy so the identifier remains available when the conversion happens on another page or after the original session. Capturing the parameter without persisting it only works when collection and conversion occur together.
The platform rejects the upload or leaves the conversion unattributed. The allowed window depends on the platform and varies by more than a factor of ten. Check the identifier’s lifetime before building the upload. For longer sales cycles, retain both the original value and click timestamp so your integration can distinguish an expired click from a malformed identifier or API error.
Not for campaign attribution. A browser ID helps a conversions API match an event with a browser or platform profile, but it contains no record of a specific ad click. Send it as an additional matching signal where the platform accepts it. Do not substitute it for a missing click ID or classify the visitor as paid merely because the browser cookie exists.
Both identifiers cover privacy-constrained iOS traffic. gbraid supports web-to-app measurement, while wbraid supports app-to-web measurement. Google does not also issue a gclid for those clicks. A collector that accepts only gclid therefore drops eligible iOS attribution completely. Store each supported identifier independently and send the one received through the compatible Google Ads upload field.
They are first-party cookies written on your domain by the corresponding platform tag. That makes their ordinary variants available to same-site collection code and server-side requests. A server-side tagging setup can instead write an HttpOnly variant. The browser still sends that cookie to the permitted server, but JavaScript cannot read it. Your capture method must match how the cookie was created.

Correct attribution depends on preserving the platform’s value, not merely finding something that resembles an ID. Validate the extraction rules, timestamp, lifetime, and destination API before shipping. See how LeadTrackr captures these automatically when you want the same identifiers carried from landing page to closed-deal upload.

Get started free

Capture every click ID automatically

LeadTrackr stores the identifier with the lead and sends the closed deal back to the ad platform — no parsing rules to maintain.

Start Free

5-min setup · cancel anytime