Mark

Track AI assistant traffic

Install the tracking file on a Next.js site, check that it works, read which AI assistants fetch your pages, and see who clicks through from their answers.

Page actions

AI assistants like ChatGPT, Claude, Perplexity, Gemini, and Copilot fetch web pages, but they don't run the site tag, so the tag never sees them. A small file on your site records each fetch in your PostHog project. Performance then shows the hits in its AI assistant traffic section.

A hit means an assistant fetched a page. It doesn't mean the assistant cited or recommended you.

Before you start

  • The site runs Next.js 16 or later. Other site builders aren't supported yet.
  • PostHog is connected in Connections > PostHog. Without it, the site shows "Connect PostHog" instead of the file.

Install the file

  1. Open Presence > Websites.
  2. Pick the website from the menu on its name if you have more than one.
  3. Under AI assistant tracking, select Copy on the file.
  4. Save it as proxy.ts at the root of the site's project and deploy. If the site already has a proxy.ts, the comment at the top of the file says how to merge the two.

The file already holds your PostHog project's public token, the same one the site tag uses. Copy a fresh file from Mark rather than editing it by hand.

An AI assistant connected to Mark can fetch the same file with list_sites, so it can add the file to the site's code for you. See Connect your AI agent.

The file records every request whose user agent looks like a crawler, and Mark picks out the AI assistants when it reports. When Mark adds an assistant, it counts on your site within a day, without a new file. Other crawlers, such as SEO tools and uptime checks, reach PostHog too, but Mark drops them before PostHog stores them, so they don't count toward your event usage. The exception is when Mark couldn't add its verification step to PostHog, which shows a red banner in AI assistant traffic. Until the banner clears, those crawlers may be stored and count.

Installed the file before 30 September 2026? Copy it again. The older file only records OpenAI, Anthropic, and Perplexity.

Check the install

Select Check AI assistant tracking. Mark loads the site's home page as Mark-Probe, then waits up to 30 seconds for that visit to reach PostHog. Mark-Probe is Mark's own check. It never counts as an assistant.

ResultWhat it means
ReceivingAn AI assistant fetched a page in the last 7 days.
InstalledMark's check reached PostHog. No assistant has visited in the last 7 days yet; on a small site that can take days.
Not installedThe site answered, but nothing reached PostHog. Deploy the file, or check again in a minute if you just did.
Blocked by the site's firewallThe site refused Mark's check, so Mark can't tell. Let Mark-Probe through, then check again.
Site didn't answer or Site couldn't be reachedMark couldn't load the home page. Check that the site is up.
Check failedMark couldn't read your PostHog project. Check again in a few minutes.

Each website keeps its own last result under the button, with the time Mark checked. If the page says The check didn't finish, Mark has no result for that run; select the button again.

Let assistants and Mark-Probe through your firewall

A firewall in front of your site runs before the tracking file. When it blocks a request, the file never sees it and no hit is recorded. Mark's check only tests Mark-Probe, so a firewall can block real assistants while the check still says Installed. If Performance shows no hits for weeks, check the firewall first.

Let these user agents through: GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-SearchBot, Claude-User, PerplexityBot, Perplexity-User, Googlebot, bingbot, Applebot, DuckAssistBot, Amazonbot, meta-externalagent, meta-webindexer, meta-externalfetcher, and Mark-Probe. Rules that match on a user agent let in anyone who sends that name, so allow only these.

Vercel Firewall

  1. Open the site's project in Vercel and select Firewall.
  2. Select Configure, then Add New > Rule.
  3. Under If, pick User Agent, choose a contains operator, and enter Mark-Probe. Add one condition per assistant name, joined with OR.
  4. Under Then, pick Bypass.
  5. Select Save Rule, then Review Changes and Publish.
  6. Drag the rule above any rule that denies or challenges traffic.

A Bypass rule gets a request past your other custom rules and past Bot Protection. Under Bot Management, keep AI Bots Ruleset on Allow. Attack Mode lets known bots through, but it may still challenge Mark-Probe, so check again after you turn it off.

Cloudflare

  1. In Security Settings, open Configure AI bot policies. Set Search and Agent to Allow (do not block). Agent covers ChatGPT-User, Claude-User, and Perplexity-User, which fetch a page when a person asks about it. Training covers GPTBot and ClaudeBot; allow it if you want to count those too.
  2. If you use AI Crawl Control, open Crawlers and set each assistant to Allow.
  3. On the Free plan, turn off Bot fight mode under Security Settings > Bot traffic. Cloudflare doesn't let a rule skip it.
  4. On Pro and above, add a skip rule instead. Open Security rules > Create rule > Custom rules, enter the expression http.user_agent contains "Mark-Probe", pick Skip, and select All Super Bot Fight Mode rules, All managed rules, and All remaining custom rules. Add the assistant names with or. Place the rule first.

Arcjet

Arcjet's rules live in your site's code, not a dashboard.

  • In detectBot, add "CATEGORY:AI", "CATEGORY:SEARCH_ENGINE", and "AMAZON_CRAWLER" to allow. Together they cover every assistant above.
  • Arcjet has no allow entry for Mark-Probe. Mark-Probe only loads your home page, so skip protect when the path is / and the user agent contains Mark-Probe. Or run the tracking file before Arcjet in your proxy, which records the hit even when Arcjet then denies the request.

After you change a firewall, select Check AI assistant tracking again.

Read AI assistant traffic

Open Performance and pick a range. The AI assistant traffic section shows:

  • Hits: every assistant fetch in the range.
  • Hits per assistant, by kind:
    • Crawler collects pages for training or an index (GPTBot, ClaudeBot, PerplexityBot, Amazonbot, meta-externalagent).
    • Search builds a search index that AI answers draw on (OAI-SearchBot, Claude-SearchBot, Googlebot, bingbot, Applebot, DuckAssistBot, meta-webindexer). Googlebot and bingbot also crawl for regular search, so expect them to lead.
    • User fetch loads a page because a person asked the assistant about it (ChatGPT-User, Claude-User, Perplexity-User, meta-externalfetcher).
  • Top pages: the 10 pages fetched most. Fonts, images, styles, and scripts are left out, so these counts won't add up to Hits. The icon beside a path opens the page on your primary site in a new tab. A 404 badge means the page answered 404 when Mark last checked it. Select the badge to see it under Pages AI assistants can't find on the site's Overview, with a redirect suggestion.
  • A "Data through" line with the newest hit.

If the section has no traffic to show, it shows one of these messages.

MessageWhat it means
"Mark reads AI assistant traffic from your PostHog project. Connect PostHog and install the tracking file on the Websites page."No PostHog project is connected. Connect PostHog, then install the file.
"PostHog hasn't received any events from your site yet, so there is no AI assistant traffic to show. Install the snippet from the Websites page, then check the PostHog connection."PostHog has never received an event from your site. Install the site tag, then select Refresh on the PostHog connection.
"PostHog didn't answer in time. Reload in a minute."PostHog was busy: it didn't answer within 15 seconds, or said it was overloaded. PostHog runs only a few queries at once for each project, so reloading again and again can keep it busy. Wait a minute, then reload once. Your PostHog connection is fine.
"Could not read AI assistant traffic from PostHog. Check the PostHog connection, or reload in a few minutes."Mark couldn't read your PostHog project for a reason other than a timeout, and Connections doesn't list PostHog as Needs You. For example, Mark lost access to the project. If the PostHog connection shows a problem, fix it there. Otherwise reload in a few minutes.
"No AI assistant fetched a page in this range. If the tracking file isn't installed yet, set it up and check it on the Websites page."PostHog answered, and no assistant fetched a page in the range. If the file isn't installed, install it and check the install.

The "hasn't received any events" message shows only when the read fails and Connections lists PostHog as Needs You, which means the project has never received an event. Any other failed read shows "didn't answer in time" for a timeout, or "Could not read" for anything else. Mark updates that status once a day, or when you select Refresh, so it can be out of date. When PostHog returns traffic, the section shows it even if Connections still says Needs You.

Select a path in Top pages to see that one page. Each assistant gets a row with its hits on the page in the range and the date of its newest fetch, or "None in range". Pick a 30-day range to see which assistants haven't fetched the page in 30 days. All pages goes back, and the range and filters stay as you set them. The one-page view shows hits only, without the verification split. If no assistant fetched the page in the range, it says "No AI assistant fetched this page in this range."

A hit counts when the request's user agent names an assistant. Anyone can send a request that claims to be GPTBot, so Mark also checks where it came from.

Read AI referrals

Hits are bots. Bots run in the vendors' data centers, so where they are says nothing about your buyers. The AI referrals card, under AI assistant traffic, counts people instead: visitors who opened your site from a link in an assistant's answer.

A visit counts as an AI referral when its pageview came from an assistant's site, such as chatgpt.com, perplexity.ai, claude.ai, gemini.google.com, or copilot.microsoft.com, or when its link has a utm_source such as chatgpt.com. ChatGPT adds that utm_source to many links in its answers. The card needs the site tag, not the tracking file, and reads your PostHog project for the range and time zone you picked.

The card shows:

  • Visitors: people who came from an assistant in the range.
  • Countries and Top country, with its share of visitors.
  • The 10 countries with the most visitors, each with its share.
  • Unknown location: visitors PostHog couldn't place. Cookieless visitors always land here, because PostHog drops their IP addresses. A note under the table says how many of them were cookieless. GeoIP turned off in PostHog, or a reverse proxy that hides visitor IPs, also puts visitors here.

The count is a floor. Some assistant apps open links with no referrer and no utm_source, so the visit looks like someone typed your address, and Mark can't count it. Google's AI Overviews send people from google.com, which Mark counts as search, not as an assistant.

The card shows the same messages as the Visitors tab when PostHog isn't connected, hasn't received events, or couldn't be read. See When PostHog can't be read. With no AI referrals in the range, it says "No visits from AI assistants in this range yet."

From an AI agent, get_visitor_locations with source: "ai_referral" returns the same numbers, with every country.

Verified, failed, and can't-check hits

The section hides these shares until a workspace admin turns them on. Select the gear icon on AI assistant traffic, then turn on Show verification. The setting applies to everyone in the workspace. With it on, the totals and each assistant row add Verified, Failed check, and Can't check. Hover a percentage for the count behind it. The MCP tools return these counts whether the setting is on or off.

OpenAI, Anthropic, Perplexity, Google, Microsoft, Apple, and DuckDuckGo publish the IP addresses their bots use. Mark reloads the lists once a day. Your PostHog project checks each hit against them as it arrives, and every hit lands in one of three groups:

  • Verified: the hit came from an address on its assistant's list.
  • Failed check: the list loaded and the address isn't on it. Usually someone sent a fake assistant user agent. Now and then a vendor starts using an address before adding it to its list.
  • Can't check: Mark had nothing to check against. That happens when:
    • The vendor publishes no list Mark can read. Amazon and Meta hits always land here.
    • The request had no IP address, or an IPv6 address checked against a list with IPv4 addresses only (Anthropic's, today).
    • The vendor's list couldn't be loaded. With verification shown, the section says so.
    • The hit arrived while Mark's verification step wasn't working in your PostHog project and the project discards client IP data. See below.

Anthropic publishes one list for all its bots. A verified ClaudeBot, Claude-SearchBot, or Claude-User hit came from Anthropic, but the list can't show which of the three sent it. OpenAI and Perplexity publish a list per bot.

Verified doesn't mean the assistant cited or recommended your site. It only means the fetch really came from that company.

Mark's verification step in PostHog

Mark adds one transformation to your PostHog project, named Mark: AI assistant verification. You'll see it under Data pipelines > Transformations. It runs only on hits the file records. It drops crawlers that aren't AI assistants and keeps Mark-Probe. For each assistant hit, it checks the IP address against its assistant's list and stores the result on the hit before PostHog does anything else with the address. That's why Verified and Failed check keep working when Discard client IP data is on in your project: PostHog drops the address after the check, and the country and city stay.

Don't turn it off or delete it. Mark checks it every day and turns it back on, but hits that arrive while it's off can't be verified if your project discards client IP data. If you manage your own PostHog project, the transformation is there because you invited Mark as an Admin.

If Mark couldn't set it up, AI assistant traffic shows a red banner with the last time Mark tried. What each one means:

  • Most transformations PostHog allows: PostHog limits how many transformations a project can have turned on, and yours is at that limit. Turn one off under Data pipelines in PostHog. Mark adds its step on its next daily try, and the banner goes away.
  • Couldn't reach your PostHog project: Mark lost access. If you manage the project, check that Mark's Admin invite is still there, then open the PostHog connection from the banner.
  • PostHog returned an error: our team has been told, and Mark tries again every day. There's nothing for you to do.

If Mark runs your PostHog project for you, the banner always says the team has been told. There's nothing for you to do in that case either.

Until a banner clears, new hits still count. They land under Can't check only if your project discards client IP data.

Last updated Nov 5, 2026

On this page