Skip to content
TraceLead

Channel classification

How UTMs, click IDs and referrers become source, medium and channel.

Overview: Leads from AI search, Paid social lead tracking

Where did this visitor come from?

Landing URL · referrer

https://example.co.uk/pricing?utm_source=google&utm_medium=cpc&utm_campaign=brand-uk&gclid=EAIaIQobChMI…

referrer: www.google.com

  1. 1. UTM parameters Decides
  2. 2. Click identifiers Present, outranked
  3. 3. Referrer Present, outranked
  4. 4. Direct Not reached
Source
google
Medium
cpc
Channel
paid_search
Campaign
brand-uk
Click ID
gclid
First touch
2026-10-02 09:14Z

Why: utm_source and utm_medium are present, so they are used as written and cpc maps to paid search. The gclid and the Google referrer are noted but outranked.

Snippet v1.4.0 applies these rules in this order. A direct return visit never overwrites a recorded touch.

Read the rules below

Implemented in tracker/src/classify.ts, exercised by tracker/src/classify.test.ts. The classifier is a pure function of the parsed signals (tracker/src/signals.ts) and the page host. It produces three fields that can be mapped into hidden inputs: source, medium, channel.

Precedence (first match wins)

  1. Explicit UTM parameters. If utm_source or utm_medium is present they are used verbatim (trimmed, lowercased, ≤ 100 chars). A missing utm_medium is inferred from a click ID (cpc), else from an external referrer (organic, social or referral; this is how a ChatGPT link, which carries utm_source=chatgpt.com, becomes a referral), otherwise unknown. A missing utm_source is inferred from a click ID or the referrer, otherwise (direct). Channel comes from the medium:

    medium channel
    cpc, ppc, paidsearch, paid_search, sem, paid paid_search (or paid_social when the source is a known social network)
    paid_social, paidsocial, paid-social, social_paid paid_social
    social, social-network, social-media, sm organic_social
    email, e-mail, newsletter email
    display, banner, cpm, cpv, video display
    affiliate, affiliates, partner affiliate
    organic, seo organic_search (or organic_social for a social source)
    referral, referer, referrer, link referral
    anything else other
  2. Click identifiers. gclid / gbraid / wbraid → google / cpc / paid_search; msclkid → bing / cpc / paid_search; ttclid → tiktok / paid_social / paid_social; li_fat_id → linkedin / paid_social / paid_social; twclid → twitter / paid_social / paid_social (TikTok, LinkedIn and X only append these ids to ad clicks); fbclid → facebook / social / organic_social (Facebook attaches fbclid to every outbound click, so it is never treated as paid on its own). When several are present the order above wins: Google, then Microsoft, then TikTok, LinkedIn and X, then fbclid.

  3. Referrer. Known search engines (google, bing, yahoo, duckduckgo, ecosia, baidu, yandex, ask, aol, startpage, brave, qwant, seznam, naver; mail.*, gemini.* and bard.* hosts excluded, so Gemini is a referral rather than Google search) → <engine> / organic / organic_search. Known social networks (facebook incl. l./m. hosts, instagram, twitter/t.co, x.com, linkedin/lnkd.in, pinterest, tiktok, youtube/youtu.be, reddit, threads, snapchat) → <network> / social / organic_social. Any other host → <host> / referral / referral. Matching uses whole hostname labels, so notgoogle.example is a referral.

  4. Direct. No referrer, a non-http(s) referrer, or a self-referral (same registrable domain, approximated as the last two labels, or three when the second-level label is ≤ 3 characters such as co.uk) → (direct) / (none) / direct.

Notes

  • Conflicts resolve by precedence: utm_medium=email with a gclid is email.
  • The classifier never reads the URL or DOM itself; it only consumes RawSignals.
  • First-touch retention (ADR-002) is handled separately: a later direct visit never overwrites an earlier classification.