How-to
How to measure ChatGPT-referred purchases (without guessing)
Identify ChatGPT referrals, persist first-touch attribution across the session, and stamp it on your server-side Purchase event so you can segment in analytics and Meta.
ChatGPT recommends your product, someone clicks through and buys three pages later — and your analytics files it under "direct." Here is the full pipeline to make those purchases countable: identify the referral, persist it, stamp it on the server-side event, then segment.
How do you identify ChatGPT referrals?
Check the referrer host and the query string. ChatGPT traffic arrives with a referrer of chatgpt.com (or the older chat.openai.com), and OpenAI appends utm_source=chatgpt.com to many outbound links — which is useful, because referrers are sometimes stripped in transit while query parameters survive.
So your detection is a simple OR:
document.referrerhost ischatgpt.comorchat.openai.com- URL contains
utm_source=chatgpt.com
The same pattern extends to other assistants (perplexity.ai, copilot.microsoft.com), but this guide sticks to ChatGPT since it sends the most volume for most stores.
Why do you have to persist it?
Because the referrer only exists on the landing pageview, and the purchase happens later. By the time the buyer reaches your thank-you page, document.referrer is your own checkout URL. If you don't capture first touch and carry it forward, the attribution is gone before the money arrives.
Store it once, on first touch, and never overwrite it within the visit:
js(function () {
var KEY = "first_touch";
try {
if (localStorage.getItem(KEY)) return; // first touch only
var ref = document.referrer || "";
var params = new URLSearchParams(location.search);
var utmSource = params.get("utm_source") || "";
var isChatGPT =
/(^|\.)chatgpt\.com$|(^|\.)chat\.openai\.com$/.test(
ref ? new URL(ref).hostname : ""
) || utmSource === "chatgpt.com";
localStorage.setItem(
KEY,
JSON.stringify({
referrer: ref,
utm_source: utmSource,
ai_source: isChatGPT ? "chatgpt" : null,
ts: Date.now(),
})
);
} catch (e) {}
})();Whether you use localStorage (persists across sessions, better for stores with multi-day consideration) or sessionStorage (single visit, cleaner definition) depends on the attribution window you want. For most stores, localStorage with the timestamp lets you decide the window later.
How do you get it onto the Purchase event?
Send the stored value to your server at checkout, and stamp it on the server-side Purchase as a custom property. The browser-side capture is only half the job — the event that matters is the Conversions API Purchase your server sends to Meta.
Concretely: read first_touch from storage at checkout, pass it in your order payload (a hidden field, a cart attribute, or a header your backend reads), and include it in custom_data on the CAPI event — something like custom_data.ai_source: "chatgpt" and custom_data.first_referrer: "chatgpt.com". Shopify stores can carry it as a cart attribute through checkout; see Shopify checkout tracking for how events flow there.
Now every Purchase carries its own origin, server-side, permanently.
How do you segment it?
Two places:
- Your analytics / order data. Filter orders where
ai_source = chatgpt. Compare AOV, repeat rate, and product mix against your other channels. This is the number you'll want when someone asks "is ChatGPT actually sending us buyers?" - Meta, via custom conversions. In Events Manager, create a custom conversion on the Purchase event filtered by your
custom_dataproperty. That gives you a ChatGPT-referred Purchase you can view in reporting — useful for understanding how assistant-seeded demand overlaps with your paid traffic.
Keep the property values low-cardinality (chatgpt, perplexity, other_ai, null) so the segments stay usable.
The trap: ChatGPT fetches that never run your JavaScript
One warning that saves you a confusing week: requests identifying as ChatGPT-User — the agent fetching pages on a user's behalf — may not execute JavaScript at all. Your first-touch snippet never runs, your Meta Pixel never fires, and browser analytics records nothing. The same goes for crawler agents like GPTBot and OAI-SearchBot.
This is why the server side of this setup is not optional. Server logs catch the agent fetches your Pixel can't see, and a server-sent Purchase event exists regardless of what did or didn't run in a browser. If your only tracking is browser-side, agentic traffic is invisible to you by construction. Our server-side tracking guide covers the architecture in depth.
If you'd rather not build and babysit this pipeline, this is what Caply does: one snippet plus managed servers that send every Purchase to Meta CAPI with hashed email and phone, deduplicated by event_id, with retries and a per-event Match Forecast score — and custom properties like your ai_source ride along. Run the scanner to check what your current setup captures, or start a 14-day trial from pricing.
Measure it now, while the numbers are small. When ChatGPT-referred revenue becomes a line item your CFO asks about, you'll have a year of clean data instead of a guess.
Caply
Match Forecast on every purchase. Tracking radar on competitor storefronts. Managed server-side tracking without a tagging server.
Start 14-day trial