Server-side tracking
Most AI crawlers — GPTBot, ClaudeBot, PerplexityBot, CCBot — request your HTML and leave without executing JavaScript, so a browser snippet alone can never see them. Server-side tracking closes the gap: your backend (or edge) reports every request it serves, and AI Tag Manager classifies it. Events arrive with source: server in analytics.
The endpoint
POST https://visitortype.ai/api/c/AITM-XXXXXXX/server-collect
Content-Type: application/json
{ "userAgent": "<the request's User-Agent>", "path": "/pricing", "referrer": "" }
// or batched (up to 500):
{ "events": [ { "userAgent": "...", "path": "/a" }, { "userAgent": "...", "path": "/b" } ] }"includeHumans": true to the payload to keep human page views.Next.js (middleware)
Copy integrations/nextjs-middleware.ts into your project. It reports via event.waitUntil, adding zero latency to responses:
export function middleware(req: NextRequest, event: NextFetchEvent) {
event.waitUntil(
fetch(`${VISITORTYPE_HOST}/api/c/${CONTAINER_ID}/server-collect`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
userAgent: req.headers.get("user-agent") ?? "",
path: req.nextUrl.pathname,
referrer: req.headers.get("referer") ?? "",
}),
}).catch(() => undefined)
);
return NextResponse.next();
}middleware.ts to proxy.ts — the code is the same, only the filename changes.Cloudflare Workers
integrations/cloudflare-worker.js runs in front of any origin — no code changes to the site itself. It passes requests through and reports page-like URLs via ctx.waitUntil.
Express / Node
integrations/express-middleware.jsbuffers events and ships them in batches every 5 seconds, so busy sites don't pay one outbound request per page view:
const { aitmTrack } = require("./aitm-express");
app.use(aitmTrack);Anything else
Any environment that can send an HTTP POST works — nginx mirror, a log shipper, a cron job over access logs. Skip static assets (images, CSS, JS) and send page-like requests only.