> ## Documentation Index
> Fetch the complete documentation index at: https://agent-traffic.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# How classification works

> The checks agent-traffic runs, in order.

Checks run in order, and the first one that answers wins.

**1. Known agent or crawler**

The request is matched against [`agents.json`](https://agent-traffic.mintlify.site/reference/dataset) in this order:

* the `User-Agent` header;
* an exact `Accept` fingerprint, compared ignoring case and spacing;
* the `Signature-Agent` header, but only on requests that also carry `Signature` and `Signature-Input`.

When the match runs on its operator's servers and you pass the client IP, the IP is checked too. See [Verification](https://agent-traffic.mintlify.site/concepts/verification.md).

**2. Asks for markdown**

If `Accept` ranks `text/markdown` or `text/x-markdown` above `text/html`, the request is an `agent`. Browsers never do this; AI tools that read pages do.

**3. Generic HTTP client or headless browser**

The user agent is matched against [`http-clients.json`](https://agent-traffic.mintlify.site/reference/dataset). A match is a `bot`, with kind `http-client` or `headless`.

**4. Browser**

A user agent counts as a browser when all of these hold:

* it starts with `Mozilla/`;
* it carries a rendering-engine token such as `KHTML, like Gecko`, `Gecko/` or `Trident/`;
* it shows no sign of automation, such as a `bot` token, a URL, an email address, or a testing tool's name.

Browsers are `human` unless their headers contradict it (see below).

**5. Everything else**

Anything else is a `bot` with kind `unidentified`. That includes empty user agents, truncated browser strings and one-off scripts. `unknown` is reserved for requests with no user agent and no headers at all.

## Browser checks

Real browsers send a predictable set of headers. Many automated clients that borrow a browser user agent don't. A browser user agent becomes a `fake-browser` bot when:

* `Accept` ranks `text/plain` above `text/html`, or asks for metalink downloads. This is checked whenever `Accept` is present.
* These three are checked only when you pass `headersComplete: true`:
  * a recent Chrome, Firefox or Safari sends no `sec-fetch-*` headers;
  * a Firefox or Safari user agent sends `sec-ch-ua`, which only Chromium-based browsers send;
  * there's no `Accept-Language`.

> [!WARNING]
>
> Only set `headersComplete: true` for HTTPS traffic that reaches you unmodified. Browsers don't send `sec-fetch-*` over plain HTTP, and some proxies strip it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.