LLM Analytics
LLM Analytics shows when an observable AI agent requests your website. It is separate from Google Analytics 4 referral traffic:
- LLM Analytics records server requests from documented crawler user agents.
- GA4 referral traffic records people who arrive from an AI product.
Connect your website
Section titled “Connect your website”You can complete setup inside ReachLLM without creating a shared account-wide secret:
- Open Traffic.
- Choose LLM Analytics from the traffic-source menu.
- Select where your website is hosted.
- Select Create connection key.
- Follow the numbered instructions for your provider.
- Select Test connection.
Connections belong to the selected brand. After the test passes, the setup instructions collapse to a simple Connected status with the provider and domain. Switching brands shows that brand's own connection. Use Manage only when you need to retest, create a new key, or disconnect.
The connection key is shown once. ReachLLM stores only a secure fingerprint. Keep the key in a server-side secret store and never put it in browser code, a tag manager, a public repository, or a URL.
The setup test requests your website with a synthetic GPTBot user agent and a one-time verification value. It proves that the request-forwarding pipeline works. It does not claim to be a real OpenAI visit, and the test is not included in your traffic totals.
For providers that need an adapter, the setup screen includes a downloadable starter file. Review it with the person who manages your hosting account, add the required provider resources, and keep the connection key in the provider's server-side secret store.
Connection fields
Section titled “Connection fields”Every provider uses these fields:
| Field | Value |
|---|---|
| Endpoint | https://app.reachllm.com/api/ai-crawler-traffic/ingest |
| Header name | X-ReachLLM-Site-Token |
| Header value | The connection key shown in ReachLLM |
ReachLLM accepts provider log batches and filters them for crawler signatures on the server. A normalized event can contain:
{ "domain": "example.com", "path": "/guide", "user_agent": "GPTBot/1.0", "timestamp": "2026-07-15T10:30:00Z", "method": "GET", "status_code": 200, "referer": "", "country": "AE", "response_time_ms": 142, "request_id": "provider-request-id"}You can also send { "events": [...] }. ReachLLM strips query strings, derives crawler identity from the raw user agent, rejects domains outside the selected brand, and deduplicates retries by request ID.
Cloudflare
Section titled “Cloudflare”Use this option when website traffic passes through Cloudflare and the relevant DNS record is Proxied.
- Open Workers & Pages and create a Worker. If another Worker already owns the route, add this handler to that Worker.
- Store the ReachLLM connection key as the secret
REACHLLM_SITE_TOKEN. - Add the route
yourdomain.com/*. - Deploy the Worker.
- Return to ReachLLM and select Test connection.
This minimal handler returns the origin response immediately and sends crawler analytics with waitUntil, so visitors do not wait for analytics:
const AI_CRAWLER = /GPTBot|OAI-SearchBot|ChatGPT-User|OAI-AdsBot|ClaudeBot|Claude-SearchBot|Claude-User|anthropic-ai|Claude-Web|PerplexityBot|Perplexity-User|Google-CloudVertexBot|Google-Agent|Google-NotebookLM|Applebot|meta-externalagent|meta-externalfetcher|Amazonbot|Amzn-SearchBot|Amzn-User|MistralAI-Index|MistralAI-User|YouBot|DuckAssistBot|CCBot|AI2Bot|DeepSeekBot|Grok-DeepSearch|xAI-Web-Crawler|xAI-SearchBot|Bytespider|cohere-ai/i;
export default { async fetch(request, env, context) { const startedAt = Date.now(); const response = await fetch(request); const url = new URL(request.url); const userAgent = request.headers.get("user-agent") || ""; const verificationNonce = url.searchParams.get("reachllm_verify") || "";
if (AI_CRAWLER.test(userAgent) || verificationNonce) { context.waitUntil(fetch("https://app.reachllm.com/api/ai-crawler-traffic/ingest", { method: "POST", headers: { "Content-Type": "application/json", "X-ReachLLM-Site-Token": env.REACHLLM_SITE_TOKEN, }, body: JSON.stringify({ domain: url.hostname, path: url.pathname, user_agent: userAgent, timestamp: Date.now(), method: request.method, status_code: response.status, response_time_ms: Date.now() - startedAt, country: request.cf?.country || "", request_id: request.headers.get("cf-ray") || crypto.randomUUID(), verification_nonce: verificationNonce, }), })); }
return response; },};Cloudflare documents background work with waitUntil. The ReachLLM production Worker also retries transient delivery failures and uses request IDs to prevent double counting.
Download the Cloudflare Worker starter
Vercel
Section titled “Vercel”Vercel Drains require a Pro or Enterprise plan.
- Open Team Settings, then Drains.
- Add a custom HTTP Drain for Logs with JSON encoding.
- Choose Production, 100% sampling, and the
static,lambda,edge,external, andredirectsources. - Paste the ReachLLM endpoint.
- Add
X-ReachLLM-Site-Tokenas a custom header and paste the connection key. - Save the Drain, then test the connection.
ReachLLM normalizes Vercel's native proxy.host, proxy.path, proxy.userAgent, proxy.statusCode, and proxy.requestId fields. See Vercel Drains and the Vercel log schema.
Netlify
Section titled “Netlify”The recommended setup is a Netlify Edge Function. Native Netlify Log Drains are Enterprise-only and do not offer the same custom-header setup in every account.
- Add a ReachLLM Edge Function to your site and apply it to
/*. - Store the connection key as the server-side variable
REACHLLM_SITE_TOKEN. - Send the normalized request fields to the ReachLLM endpoint with
context.waitUntil. - Deploy the site, then test the connection.
Do not add the key to PUBLIC_ variables or frontend code. See the Netlify Edge Functions API.
Download the Netlify Edge Function starter
AWS CloudFront
Section titled “AWS CloudFront”CloudFront real-time logs require Kinesis, IAM, and a Lambda adapter. AWS usage charges apply.
- Create a real-time log configuration with 100% sampling.
- Include these fields:
timestamp,sc-status,cs-method,cs-host,cs-uri-stem,x-edge-request-id,cs-user-agent,cs-referer,cs-uri-query, andc-country. CloudFront delivers selected fields in its documented canonical order. - Attach the configuration to every public cache behavior.
- Send the logs to Kinesis Data Streams.
- Deploy a Lambda consumer that converts each row to the normalized ReachLLM event format.
- Store the connection key as an encrypted Lambda variable or secret.
- Post batches to ReachLLM, then test the connection.
CloudFront sends real-time logs within seconds but describes delivery as best effort. See CloudFront real-time logs.
Download the CloudFront Kinesis Lambda starter
Fastly
Section titled “Fastly”Use a Fastly Compute adapter for the current setup:
- Add a background request-forwarding handler to the Fastly Compute service.
- Store the connection key in a Fastly Secret Store.
- Post normalized events to the ReachLLM endpoint.
- Activate the service version, then test the connection.
Direct Fastly HTTPS log streaming requires a destination-ownership challenge at /.well-known/fastly/logging/challenge. Do not configure the direct stream until that challenge has been enabled for your service. See Fastly HTTPS log streaming.
Download the Fastly Compute helper
Akamai
Section titled “Akamai”Akamai DataStream 2 can send a custom named header:
- Create a DataStream 2 stream and select the relevant property.
- Include request time, host, path, query, method, User-Agent, Referer, response status, request ID, and country.
- Choose Custom HTTPS and JSON.
- Paste the ReachLLM endpoint.
- Choose no built-in authentication.
- Add
X-ReachLLM-Site-Tokenas a custom header with the connection key. - Validate, save, activate the stream, then test the connection.
ReachLLM accepts Akamai's access_validation probe without recording a crawler request. Akamai does not allow Authorization as a custom header value, which is why ReachLLM uses its own header. See Akamai DataStream 2 custom HTTPS.
Google Cloud CDN
Section titled “Google Cloud CDN”Google Cloud uses a Logs Router, Pub/Sub, and a Cloud Function adapter:
- Enable request logging with a sampling rate of
1.0on every backend service. - Create a Logs Router sink filtered to the website's load balancer.
- Route the sink to Pub/Sub.
- Deploy an adapter that reads the Pub/Sub envelope and posts normalized events to ReachLLM.
- Store the connection key in Secret Manager.
- Connect the subscription, then test the connection.
Pub/Sub cannot post directly to ReachLLM because Pub/Sub uses its own signed Authorization header and wraps log entries. See Cloud CDN logging, log routing, and Pub/Sub push delivery.
Download the Google Cloud Pub/Sub Function starter
WordPress and WP Engine
Section titled “WordPress and WP Engine”ReachLLM does not need a WordPress username, password, or administrator account for this setup. The customer's WordPress administrator installs the ReachLLM Connector and pastes a brand-scoped connection key.
Customer-installed WordPress plugin
Section titled “Customer-installed WordPress plugin”- In ReachLLM, select WordPress plugin.
- Select Create connection key.
- Download the ReachLLM Connector and select Copy customer instructions.
- Send the instructions and plugin to the customer's WordPress administrator.
- Share the connection key separately through a secure one-time secret link. Do not put it in regular email.
- The administrator opens WordPress Admin > Plugins > Add New > Upload Plugin, uploads the zip, and activates it.
- The administrator opens Settings > ReachLLM, pastes the key under LLM Analytics, and selects Save connection.
- After the administrator confirms completion, return to ReachLLM and select Test connection.
Download the ReachLLM Connector
The plugin filters observable crawler user agents inside WordPress, removes arbitrary query strings, does not collect visitor IP addresses, and keeps a bounded local queue. WP-Cron sends batches in the background with retries. Normal visitor requests never make an external ReachLLM analytics call.
Understand WordPress and WP Engine coverage
Section titled “Understand WordPress and WP Engine coverage”WordPress plugins run only after a request reaches WordPress and PHP. A host or CDN can return a cached page before WordPress runs, so the plugin cannot see that request.
| Source | What it includes | Coverage label |
|---|---|---|
| ReachLLM WordPress plugin | Requests that reach WordPress and load the plugin | WordPress application coverage |
| WP Engine Origin logs | Uncached origin requests and requests served by WP Engine Varnish cache | Origin coverage |
| WP Engine Edge logs | Cached Cloudflare edge requests and uncached requests forwarded to origin | Complete WP Engine edge coverage |
WP Engine's Advanced Network can serve static files and full HTML pages from Cloudflare. NitroPack and other page caches can add another layer. Do not disable those caches for analytics, because that would slow the site and increase origin load.
For a complete WP Engine review, ask the customer's hosting administrator to open WP Engine User Portal > Production environment > Advanced > Logs > Access > Edge. WP Engine says Edge logs can include up to 20 million requests from the previous 72 hours. Its documented Customer API does not list an access-log endpoint, so a connection key alone cannot retrieve those logs.
WP Engine can also export Nginx access logs to a customer-owned Amazon S3 bucket each night. An S3 log processor can filter crawler requests and send normalized batches to ReachLLM without adding request latency. This is origin coverage, not complete Cloudflare edge coverage.
References: WP Engine Access and Edge logs, WP Engine caching, WP Engine request and page-cache flow, WP Engine nightly S3 log export, and WP Engine Customer API capabilities.
Nginx, Apache, or another server
Section titled “Nginx, Apache, or another server”- Write JSON access logs with domain, path, User-Agent, timestamp, status, method, Referer, and request ID.
- Configure Fluent Bit or another server-side log forwarder to read the logs.
- Use HTTPS output with JSON Lines.
- Add
X-ReachLLM-Site-Tokenand the connection key as a custom header. - Restart the forwarder, request a page, then test the connection.
See Fluent Bit HTTP output and Apache custom logs.
Download the Nginx and Fluent Bit starter
Webflow, Shopify, Wix, and Squarespace
Section titled “Webflow, Shopify, Wix, and Squarespace”These builders do not share the same network setup:
- Webflow: Supported through Cloudflare after moving to Webflow's current
cdn.webflow.comsetup, validating SSL with DNS-only records, and enabling Cloudflare Orange-to-Orange. Then follow the Cloudflare guide. See Webflow's reverse-proxy guide. - Shopify: Do not enable Cloudflare Proxy or Orange-to-Orange. Shopify says those configurations are unsupported. A Shopify-native integration is required. See Shopify domain troubleshooting.
- Wix: Keep Cloudflare records DNS only. Wix says proxied records are unsupported, so a Cloudflare Worker cannot observe requests. See Wix Cloudflare settings.
- Squarespace: Squarespace does not expose complete server request logs for this integration. A browser script is not an accurate workaround because many crawlers do not run JavaScript.
ReachLLM shows these limitations in the setup screen instead of claiming that an incomplete browser tracker is connected.
Crawler identities
Section titled “Crawler identities”ReachLLM tracks an HTTP request only when its raw user agent contains an observable crawler signature. A matching user agent is a claimed identity, not proof that the source IP belongs to that company.
Documented observable signatures
Section titled “Documented observable signatures”| Organization | Observable user agents | Meaning |
|---|---|---|
| OpenAI | OAI-SearchBot, GPTBot, ChatGPT-User, OAI-AdsBot |
Search indexing, training, user-requested fetches, and ads validation |
| Anthropic | ClaudeBot, Claude-SearchBot, Claude-User |
Training, search indexing, and user-requested fetches |
| Perplexity | PerplexityBot, Perplexity-User |
Search indexing and user-requested fetches |
Google-CloudVertexBot, Google-Agent, Google-NotebookLM |
Site-owner or user-requested agent fetches | |
| Apple | Applebot |
Mixed Apple search, Siri, and AI product crawling |
| Meta | meta-externalagent, meta-externalfetcher |
Automated AI indexing and user-requested fetches |
| Amazon | Amazonbot, Amzn-SearchBot, Amzn-User |
Training, search, and user-requested fetches |
| Mistral | MistralAI-Index, MistralAI-User |
Search indexing and user-requested fetches |
| You.com | YouBot |
Search indexing |
| DuckDuckGo | DuckAssistBot |
AI-assisted answer indexing |
| Common Crawl | CCBot |
Open web dataset collection |
| AllenAI | AI2Bot |
Open model training collection |
ReachLLM also recognizes the legacy Anthropic aliases anthropic-ai and Claude-Web.
Observed aliases without current official verification
Section titled “Observed aliases without current official verification”ReachLLM can label DeepSeekBot, Grok-DeepSearch, xAI-Web-Crawler, xAI-SearchBot, Bytespider, and cohere-ai when they appear. The product marks these as unverified aliases because ReachLLM could not confirm a current first-party crawler specification for them.
What ReachLLM does not misattribute
Section titled “What ReachLLM does not misattribute”Googlebotis a generic Google Search crawler. Google says its crawl data can support AI Overviews and AI Mode, but request logs cannot identify which product used the crawl. ReachLLM does not label Googlebot as an AI Mode visit.bingbotis a generic Bing Search crawler. Microsoft does not provide a dedicated Copilot user agent, so ReachLLM does not label bingbot as a Copilot visit.Google-ExtendedandApplebot-Extendedarerobots.txtpolicy controls, not HTTP user agents.facebookexternalhitandFacebotare link-preview crawlers, not Meta AI traffic.
Official references: OpenAI crawlers, Anthropic crawlers, Perplexity crawlers, Google common crawlers, Google user-triggered fetchers, DuckAssistBot, Applebot, Meta crawlers, Amazonbot, and Mistral robots.
Understand the dashboard
Section titled “Understand the dashboard”The dashboard separates data that answer different questions:
- Requests, detected agents, and pages reached: server request volume and coverage.
- Request activity: a daily timeline with visible date and value axes. Quiet dates remain visible with a zero request count, so the line never skips across missing days.
- Response time: switch the activity chart to daily average response time when the connected provider supplies timing data.
- AI providers: provider share with recognizable provider logos.
- Why they visit: documented purpose such as AI search discovery, user-requested fetch, model training, ads validation, or public dataset collection.
- Access health: successful, redirected, access-issue, and failed responses.
- Average response: measured origin response time where the connected provider supplies it. The sample count is shown because some providers do not report timing.
- Crawler infrastructure: coarse country for the crawler server, not a human audience location.
- Top pages and recent requests: requested paths, status codes, agent identity, purpose, time, and available response timing.
These are server requests, not human sessions, citations, referrals, or conversions. A crawler whose purpose includes training may request a page without that page ultimately being used for model training.
What each traffic source can show
Section titled “What each traffic source can show”The Your traffic picture panel links the three types of traffic data without combining unlike metrics:
- AI agent requests: this installation shows observable AI agent requests, requested pages, crawler purpose, response health, and available crawler server location.
- Search discovery: Google Search Console and Bing Webmaster Tools show search clicks, impressions, queries, pages, and positions. Google also supplies search country and device dimensions. Request logs cannot reconstruct these search-engine metrics.
- Human visits: Google Analytics 4 shows collected sessions, referral sources, visitor countries, devices, engagement, and conversions. The AI agent request installation does not collect browser sessions or human device data.
ReachLLM never presents crawler server country as visitor country. Connect the matching source from the Traffic menu when you need search or human audience analysis.
References: Google Search Console Search Analytics API, Google Analytics Data API dimensions and metrics, Google Analytics Measurement Protocol, and Bing Webmaster rank and traffic data.
Live updates and connection status
Section titled “Live updates and connection status”The Traffic page refreshes visible crawler data while the page is open. Recent 7-day views update every 20 seconds, 30-day views update every minute, and longer views update every 5 minutes. This keeps the recent view responsive without repeatedly rebuilding a large historical range. You can select Refresh at any time. Provider delivery time varies:
- Cloudflare Worker and Netlify Edge Function: usually within seconds.
- Vercel Drains and Fastly adapters: short near-live batches.
- CloudFront: usually within seconds, best effort.
- Akamai: approximately 30 seconds or longer.
- Google Cloud: usually seconds to minutes.
- WordPress plugin: background batches, usually within one minute when WP-Cron or WP Engine Alternate Cron runs normally.
- Nginx or Apache: depends on the log-forwarder flush interval.
The interactive crawler dashboard supports exact custom ranges up to 90 days. This keeps live aggregation responsive for high-traffic sites.
A quiet date range does not disconnect the integration. Connected and listening stays visible even when the selected dates contain zero crawler requests.
Troubleshooting
Section titled “Troubleshooting”The website responds, but the test is not received
Section titled “The website responds, but the test is not received”- Confirm that the endpoint and header name match the values shown in ReachLLM.
- Confirm that the full connection key is stored on the server.
- Confirm that the request passes through the Worker, Edge Function, Drain, or log stream you configured.
- Confirm that cached pages are included. Some platform logs exclude cached or static responses unless you select every source.
- For Cloudflare, confirm the DNS record is Proxied and the Worker route matches the hostname.
- For a redirect from the apex domain to
www, confirm both hostnames pass through the configured traffic source. - For WordPress, confirm the key is saved under Settings > ReachLLM and that WP-Cron is enabled. On WP Engine, a successful plugin test still proves only WordPress application coverage, not cached edge coverage.
The key is no longer visible
Section titled “The key is no longer visible”This is expected. ReachLLM shows a connection key only once. Select Rotate key to create a replacement, update the traffic source, and test again. Rotation invalidates the previous key immediately.
A crawler row looks spoofed
Section titled “A crawler row looks spoofed”User agents can be copied. ReachLLM currently reports claimed user-agent signatures and does not claim verified source-IP ownership. Use the request details and provider logs when investigating suspicious traffic.
I disconnected the integration
Section titled “I disconnected the integration”ReachLLM stops accepting new events for the revoked key. Historical analytics remain available. You can create a new key later without deleting the previous history.
