Architecture

Click-IDs explained: gclid, fbclid, ttclid, li_fat_id side by side

When someone clicks an ad and lands on your site, the platform appends a token to the URL. That token, the click-ID, is the strongest single attribution signal the platform has. Each network does it slightly differently. The mechanics, lifetime and capture rules in one place.

Reading time: ~6 minPublished: 2026-05-02

What a click-ID actually is

An ad-click takes the visitor from the ad surface (Google Search, Facebook feed, TikTok For You, LinkedIn timeline) to your landing URL. Right before the redirect, the platform appends a query parameter to the URL: ?gclid=..., ?fbclid=..., ?ttclid=..., ?li_fat_id=.... The value is a signed, opaque token that only the platform can decode. It encodes the campaign, ad-group, creative, the timestamp of the click and a checksum that proves the click came from the platform's own ad server.

Once you send that token back to the platform alongside a conversion event, the platform can match the conversion to the original click with certainty. No fingerprinting, no cookie matching, no probabilistic attribution. Just a one-line proof.

The four click-IDs side by side

PlatformParameterLifetimeServer field
Google Adsgclid (also wbraid, gbraid)90 days, click-throughgclid on click_conversion upload
Metafbclid7 days for cookie matchingfbc field on CAPI event
TikTokttclid30 days, signedttclid on Events API event
LinkedInli_fat_id180 days for B2B funnelsconversionEventToken on CAPI

Capture: read once, store immediately

Click-IDs only exist in the URL of the very first page the visitor lands on. After they navigate to a second page, the parameter is gone. If you don't capture and persist the value before the visitor moves, you lose attribution for everything that comes after.

Beaconry's nl-data.js reads document.location.search on the very first page-view, extracts every known click-ID parameter at once and stores them in a single first-party cookie called nl_ext. The structure is JSON: {"gclid":"...","fbclid":"...","ttclid":"...","li_fat_id":"..."}. Cookie scope is your domain only, expiry is 90 days, consent-gated.

Persistence and decay

Each platform has its own attribution window. After that window passes, the platform stops accepting the click-ID for matching even if you still send it. The practical effect:

  • If the visitor converts within 7 days for Meta, sending fbclid works.
  • If they convert at day 8, the fbclid is technically still in nl_ext but Meta will reject the match.
  • Meta's first-party fbp cookie (set by the browser pixel in hybrid mode) extends this to 90 days as a backup signal.

Beaconry sends every click-ID it has on every event. Platforms ignore expired values, no harm done. The opposite mistake, deliberately stripping out expired IDs, costs you the boundary cases where the platform's window happened to extend.

What Beaconry sends, per channel

  • Meta CAPI: fbc field constructed from fbclid + landing timestamp, plus the fbp cookie when hybrid mode is on.
  • TikTok Events API: ttclid field as captured, plus _ttp cookie in hybrid mode.
  • Google Ads API: gclid on every conversion-action upload. wbraid and gbraid sent when present (mobile and iOS-attribution variants).
  • LinkedIn CAPI: conversionEventToken built from li_fat_id, attached to the event.

For the conversion event payload, Beaconry attaches whichever click-IDs match the channel being dispatched to. A purchase event sent to Meta gets fbc, the same purchase event sent to Google Ads gets gclid. No cross-contamination.

What goes wrong without click-IDs

Conversion attribution falls back to the next-strongest signal the platform has:

  1. First-party cookie set by the platform's own browser pixel (only available with hybrid mode).
  2. Hashed PII match (email, phone) submitted in a form during the same session.
  3. IP plus user-agent fingerprint, the weakest signal, often dropped entirely on iOS.

For ad-click visitors who convert without filling a form, click-ID is the difference between "attributed correctly" and "untracked". Net effect on a typical e-commerce setup: 30-50 % of paid-search conversions become invisible to Google Ads if gclid isn't captured and replayed.

Direct visits and organic traffic

Visitors who arrive without a click-ID, organic search, direct traffic, referral, never have one. There's nothing to capture, the nl_ext cookie stays empty for them. Beaconry sends the conversion event with the click-ID field empty; platforms simply don't credit the conversion to a paid click. That's correct behaviour, since it wasn't a paid click.

Common pitfalls

  • URL stripping. Some CDNs and security tools strip query parameters they don't recognise. If you see no click-IDs landing in nl_ext, check Cloudflare Page Rules and any "Always Online" tooling for parameter stripping. Whitelist the four click-ID names.
  • Server-side redirects. If your landing URL redirects to a canonical path, make sure the redirect preserves the query string. 301 /landing?fbclid=... → /home drops the fbclid.
  • Single-page apps. SPAs that handle navigation client-side without page-loads don't trigger Beaconry's URL-parsing on subsequent navigations. Capture happens on initial load only, which is what you want, but make sure the SPA doesn't replace the URL via history.replaceState before Beaconry runs.
  • iOS Mail privacy and email click-throughs. iOS Mail prefetches links, which means the click-ID gets "spent" by Apple's prefetcher, not the human visitor. Mitigation: campaigns to email lists should expect 10-15 % attribution loss on iOS audiences regardless of tracking tool.

Take-away

Four query parameters, four platforms, one architectural pattern: read on landing, persist in a first-party cookie, replay on every conversion event. Beaconry handles all four out of the box, in the same nl_ext cookie, with the right server-side mapping per channel. The only thing the customer has to think about is whether the URL actually arrives intact, which is usually a CDN configuration question rather than a tracking question.