Bot traffic tracking
See which AI assistants, search engines, and training crawlers read your site, which pages they fetch, and how often. Tracking runs on your server or CDN, so it catches visits your analytics never sees.
Why it has to run server-side#
Analytics scripts run in the browser. Crawlers such as GPTBot, ChatGPT-User, or Googlebot download the HTML and leave without running JavaScript, so a tracking pixel never fires for them. The only place their visits show up is the request itself: at your server, your middleware, or your CDN.
Bot traffic tracking reads that request (URL, user agent, IP, and status code) and sends it to Rankealo. Your page is never delayed: every integration reports in the background.
Get started#
- 1
Open Agent Analytics Setup
In the app, go to Bot traffic → Agent Analytics Setup. Your site token and endpoint are shown there. - 2
Pick your provider
Choose how your site is served (Vercel, Cloudflare, Netlify, a framework such as Astro or SvelteKit, WordPress, or any backend) and follow the steps for it. We preselect the provider we detect. - 3
Confirm data is flowing
Press Check now. The first hit can take a while, since it depends on when a crawler next visits. Most sites see one within 24 hours.
What it tracks#
Every hit is grouped into one of three categories, based on why the crawler came:
| Category | What it means | Crawlers |
|---|---|---|
| AI answers | A person asked an assistant a question and it fetched your page to answer. These are the visits closest to a citation. | ChatGPT-User, Claude-User, Perplexity-User, PerplexityBot, DuckAssistBot, MistralAI-User |
| Indexing | Search and AI-search indexes crawling your pages so they can be found and cited later. | OAI-SearchBot, OAI-AdsBot, Claude-SearchBot, GoogleOther, Googlebot, Bingbot, Applebot, Amazonbot |
| Training | Crawlers collecting pages for model training. No user is waiting on the other end. | GPTBot, ClaudeBot, anthropic-ai, Google-Extended, Applebot-Extended, Meta-ExternalAgent, Bytespider, CCBot |
Humans and unknown user agents are dropped before anything is stored. Query strings are removed from URLs, and crawler IPs are stored only as a hash.
Crawler verification#
A user agent is a claim, not an identity: any client can send "GPTBot". By default we label a hit as a claimed identity (user agent only). When your CDN tells us the request came from a verified bot (for example Cloudflare's verified-bot flag, sent as ai.verifiedBot), the hit is upgraded to verified by CDN metadata. We never mark a hit as verified from the user agent alone.
Supported providers#
| Provider | Notes |
|---|---|
| Next.js / Vercel middleware | Full support. |
| Vercel Log Drain | Needs a Vercel Pro or Enterprise team. No code on your site. |
| Cloudflare Worker | Full support. |
| Cloudflare Logpush | Only on Cloudflare Enterprise |
| Netlify | Full support. |
| Astro | Middleware only runs for on-demand (server-rendered) routes. Prerendered pages served from a CDN are not seen; for static Astro sites use Netlify, the Vercel Log Drain, or Cloudflare. |
| Remix / React Router | Full support. |
| SvelteKit | Full support. |
| Nuxt | Full support. |
| Express | Full support. |
| WordPress | Limited features: PHP only runs on cache misses, so hits served from a page cache or CDN (often 60–95%) are not seen. Use the Cloudflare Worker if your site is behind Cloudflare. |
| Any backend (HTTP API) | Full support. |
Not supported yet: Amazon CloudFront, Fastly, Akamai, Google Cloud CDN, Shopify, and Adobe Experience Manager. Hosted builders (Webflow, Squarespace, Framer, Shopify) can use the Cloudflare Worker when the domain is proxied through Cloudflare.
HTTP API reference#
Every integration calls the same endpoint. You can call it directly from any backend.
POST https://app.rankealo.ai/api/ai-visibility/crawler-hits/ingest
Authorization: Bearer YOUR_SITE_TOKEN
Content-Type: application/json
{
"websiteId": "YOUR_WEBSITE_ID",
"domain": "www.your-site.com",
"href": "https://www.your-site.com/pricing",
"ai": {
"userAgent": "Mozilla/5.0 (compatible; ChatGPT-User/1.0; +https://openai.com/bot)",
"ip": "203.0.113.8",
"statusCode": 200
}
}Authentication. Send your site token as Authorization: Bearer YOUR_SITE_TOKEN. If the sender cannot set headers (Cloudflare Logpush, Vercel Log Drain), pass it as ?token=YOUR_SITE_TOKEN instead, with ?websiteId=YOUR_WEBSITE_ID. The token is tied to one website: it only works with that site's websiteId.
| Field | Required | Where to find it |
|---|---|---|
| websiteId | Required | Your website id, shown in Agent Analytics Setup. |
| href | Required | Full URL the crawler requested. Its host must match your site; the query string is dropped. |
| ai.userAgent | Required | The raw User-Agent header of the request. |
| domain | Optional | Request host. Used when href is missing a host. |
| ai.ip | Optional | Client IP. Hashed before storage, never stored raw. |
| ai.statusCode | Optional | HTTP status your server returned (100–599). |
| ai.verifiedBot | Optional | true when your CDN verified the bot (upgrades the hit to verified). |
Batches. Send up to 500 hits per request in a hits array. Each item takes href, user_agent, and optionally ip, statusCode, verified_bot, and occurred_at (ISO 8601; defaults to the time we receive it).
{
"websiteId": "YOUR_WEBSITE_ID",
"domain": "www.your-site.com",
"hits": [
{ "href": "https://www.your-site.com/", "user_agent": "GPTBot/1.2", "ip": "203.0.113.8", "occurred_at": "2026-09-25T10:00:00Z" },
{ "href": "https://www.your-site.com/blog", "user_agent": "Googlebot/2.1", "statusCode": 200 }
]
}Responses. skipped counts hits from another host or with an unknown user agent.
200 { "ingested": 2, "skipped": 0, "truncated": false }
400 { "error": "websiteId is required" } // or invalid JSON, or more than 500 hits
401 { "error": "Unauthorized" } // missing or wrong token
404 { "error": "onboarding_not_found" } // unknown websiteId
503 { "error": "AI crawler ingest is disabled" }Where to see the data#
Open Bot traffic in the app (/bot-traffic). It shows hits over time by crawler, splits them into AI answers, indexing, and training, and lists the pages each crawler read and whether AI engines cited them.
Pair it with citations
On LLM Visibility, the Crawled vs cited card joins the pages assistants fetched to whether they cited them, so you can see which fetched pages never turn into citations.Still stuck? Contact support
