Skip to content

AI and agent traffic

Who read your pages, who they sent, and how much of your traffic is not a person.

Why your Direct bucket grew

When someone asks an assistant a question and then visits the site it mentioned, the visit usually arrives with no referrer header. Analysis of hundreds of thousands of visits puts the share at roughly seven in ten. Every tool that reads the referrer, including Google Analytics, files those as Direct.

So the channel is invisible precisely when it matters most. Visits that began with an assistant recommendation tend to convert several times better than search traffic, because the person arrived already persuaded. They are the best traffic on the site and they are filed under "we do not know".

How Termind infers it

Termind records, server-side, when an assistant fetches one of your pages specifically to answer somebody — which is a different thing from indexing you or collecting training text. If ChatGPT read your pricing page on Tuesday, and unreferred arrivals to that same page ran well above their usual rate for the next three days, that is worth putting in front of you.

This is a correlation and Termind says so on the screen. The same pattern can come from a launch, a newsletter or somebody sharing a link. Each row shows the crawls, the page's own normal rate and the lift, so you can judge it rather than take it.

ReadingWhat it means
Likely sent peopleWell above this page's own baseline, on enough visitors to not be noise.
PossiblyAbove baseline, but not by enough to rule out coincidence.
No more than usualAn assistant read it. Arrivals did not change.
Nobody afterAn assistant read it and nothing followed.

A user-agent is a claim, not proof

A user-agent is a string the client chooses, so a scanner can announce itself as ChatGPT-User while requesting your /.aws/config. We saw exactly that in live data. Left alone it would be worse than noise: since crawls feed attribution, forging a user-agent would let an attacker invent an acquisition channel inside your dashboard.

Two checks run before a crawl counts. Paths that are always hostile — credential files, admin panels, config endpoints — are rejected outright and never earn credit. Then, if you forward the requesting IP, Termind confirms it by reverse-then-forward DNS: the address must resolve to a hostname belonging to the operator, and that hostname must resolve back to the same address. A forger controls neither direction.

Without an IP the visit is recorded as claimed rather than confirmed, and the interface says "unverified" instead of implying a check that never ran.

People, assistants and machines

Automated requests now make up more than half of web traffic, and Cloudflare expects agent traffic to overtake human traffic during 2027. Most analytics tools sort this into bot and not-bot, which throws away the interesting case.

Termind uses three buckets. People are driving the browser themselves. Assistants are AI browsing on somebody's behalf — there is still a person at the end of it, so those sessions count, separately. Machines are automation with no reader: scripts, monitors, scrapers.

The middle bucket is why bot filtering used to hurt you. Filtering on a generic bot pattern discards assistant sessions along with the scrapers, which means discarding the fastest-growing referral channel there is. Termind drops only the third bucket.

Every session records the evidence behind its classification, so a surprising number can be argued with rather than trusted. The strongest signal is navigator.webdriver, which the browser sets on itself under automation and a script cannot switch off.

Turning it on

Crawlers fetch your HTML and leave without running JavaScript, so the tracking snippet can never see one. Seeing them requires a call from your own server or edge middleware. The machine tracking page has the code for each platform.

ts
// Forward the crawler's user-agent and IP so the claim can be verified.
await fetch(
  "https://termind.tech/v1/crawl?key=" + process.env.TERMIND_KEY +
  "&path=" + encodeURIComponent(request.nextUrl.pathname) +
  "&ua=" + encodeURIComponent(request.headers.get("user-agent") ?? "") +
  "&ip=" + encodeURIComponent(request.headers.get("x-forwarded-for")?.split(",")[0] ?? "")
);
NextMCP: connect an AI to your analyticsLet Claude, Cursor or any MCP client answer questions from your real numbers.