# Bot filtering rules

> Bot filtering rules for User-Agents, crawlers, data centers and referrer spam, plus the interaction signal and the bot score for visits that get through.

Every hit the tracking script sends goes through the same bot checks
before it's counted. Bots are counted in aggregate (reason, country) with **no IP
stored**, and don't count toward your usage.

## Checks, in order

1. **Empty User-Agent** → `bot_empty_user_agent`.
2. **Known crawlers** (Googlebot, Bingbot, GPTBot and other User-Agents
   the bot list recognizes) → `bot_known_bot`.
3. **Automation and HTTP libraries** → `bot_automation`. User-Agents
   containing any of: `headless`, `phantomjs`, `puppeteer`, `playwright`,
   `selenium`, `webdriver`, `electron`, `slimerjs`, `lighthouse`,
   `pagespeed`, `gtmetrix`, `pingdom`, `uptimerobot`, `monitage`,
   `prerender`, `python`, `curl`, `wget`, `httpclient`, `okhttp`,
   `go-http`, `java/`, `axios`, `node-fetch`, `scrapy`.
4. **Data-center networks** (major cloud and hosting providers, by ASN) →
   `bot_datacenter`. VPN and relay networks such as iCloud Private Relay
   aren't on the list, so real people behind them count.
5. **Referrer spam** domains → `bot_referrer_spam`.

## Visits with no input seen

Some bots run a real browser with an ordinary User-Agent, so the checks
above let them through. They tend to load one page and leave without
touching it. To help you spot them, the tracker reports whether it saw any
real input during a visit: a pointer press or move, a key press, a touch or
a wheel turn. It sends a yes or no only, never what the input was (see
[What the tracker sends](/docs/tracker/payload#interaction-flag)).

Every visit then has one of three values in the `interaction` dimension:

| Value | Meaning |
|---|---|
| `seen` | Input was seen on at least one page of the visit |
| `none` | The tracker could tell, and saw none |
| `unknown` | Nothing can tell: a self-hosted copy of an older tracker, and all data from before 1 October 2026 |

These visits are **not dropped**, and they count toward your usage like any
other. A person who opens a page and closes it without touching it also
shows as `none`, so read it as a signal, not as proof.

- **Overview → Technology → Interaction** breaks visits down by the three
  values. Click a row to filter the dashboard by it.
- To leave them out of a report or an API call, filter with
  `["interaction", "is_not", "none"]`. Save it as a
  [segment](/docs/dashboard/filters-and-segments) to reuse it.
- **Site settings → Bots** shows how many visits in the last 30 days had no
  input seen, with links to both views.

## Bot score

On the Business and Enterprise plans, every visit also gets a **bot
score** from a machine learning model: likely human, unsure or likely
bot. Like the interaction value it is a label, not a filter: scored
visits are kept and counted. See
[Advanced Bot Detection](/docs/features/bot-detection#the-bot-score).

Every visit is scored while your workspace has Advanced Bot Detection.
The only visits with no score (`not_scored`) are from before it did:
history is not scored afterwards.

A hit from a copy of the tracking script older than 7 October 2026 sends
no time zone. Its visit is still scored, and the model reads the missing
zone as a signal.

## Turning filtering off

**Site settings → Bots** lets you switch bot filtering off for a site, for
diagnostics. Everything is then counted, including crawlers. Turn it back
on when you're done.

The bot summary on the same tab shows how many hits were filtered in the
last 30 days, by reason and country. For AI
crawler visibility (which never runs JavaScript), use the
[AI crawler logs](/docs/features/ai-crawlers).
