AI Detections
WebDecoy provides comprehensive detection of AI-related activity on your website, including server-side AI crawlers, client-side browser extensions, LLM referral tracking, and suspicious signals that indicate AI-assisted browsing.
For the crawl-to-referral model and reporting capabilities, see the AI Traffic product overview.
Overview
Section titled “Overview”AI activity falls into six main categories:
| Category | Detection Method | Needs a server-side sensor? | Examples |
|---|---|---|---|
| AI Scrapers | User-Agent analysis | Yes | GPTBot, ClaudeBot, CCBot |
| AI Browser Plugins | DOM/JavaScript analysis | No | Claude extension, ChatGPT sidebar |
| Vision AI Bots | Form behavior analysis | No | Claude Computer Use, Stagehand, Browser Use |
| LLM Referrals | Referrer header analysis | No | Visitors clicking links shared by ChatGPT, Perplexity, Claude |
| AI Tools | Behavioral signals | No | Automated form filling, content extraction |
| Suspicious Signals | API monitoring | No | Wrapped fetch, modified observers |
┌─────────────────────────────────────────────────────────────────┐│ AI DETECTION LAYERS │├─────────────────────────────────────────────────────────────────┤│ ││ SERVER-SIDE CLIENT-SIDE ││ ─────────── ─────────── ││ ││ ┌─────────────────┐ ┌─────────────────┐ ││ │ AI Scrapers │ │ Browser Plugins │ ││ │ (User-Agent) │ │ (DOM Detection) │ ││ └────────┬────────┘ └────────┬────────┘ ││ │ │ ││ │ ┌────────┴────────┐ ││ │ │ Vision AI Bots │ ││ │ │ (Form Behavior)│ ││ │ └────────┬────────┘ ││ ▼ ▼ ││ ┌─────────────────┐ ┌─────────────────┐ ││ │ AI Scraper │ │ AI Plugin + │ ││ │ Score (0-100) │ │ Vision Flags │ ││ └────────┬────────┘ └────────┬────────┘ ││ │ │ ││ └──────────────┬───────────────┘ ││ ▼ ││ ┌─────────────────┐ ││ │ Detection │ ││ │ Record │ ││ └─────────────────┘ ││ │└─────────────────────────────────────────────────────────────────┘AI Scrapers (Server-Side)
Section titled “AI Scrapers (Server-Side)”AI scrapers are bots that crawl websites to collect content for training AI models. WebDecoy detects these through User-Agent analysis and assigns an AI Scraper Score.
The score in these tables is the agent’s base score in WebDecoy’s agent registry (186 known agents; browse them all in Bot Directory). A matched user agent gets that score as its AI scraper score.
Training Crawlers (High Score)
Section titled “Training Crawlers (High Score)”These crawlers collect content for AI/ML model training:
| Crawler | Company | Score | User-Agent Pattern | Purpose |
|---|---|---|---|---|
| GPTBot | OpenAI | 85 | GPTBot |
Training GPT models |
| ClaudeBot | Anthropic | 85 | ClaudeBot |
Training Claude models |
| Anthropic | Anthropic | 85 | anthropic-ai |
Anthropic’s general crawler |
| CCBot | Common Crawl | 80 | CCBot |
Open dataset used for AI training |
| Google-Extended | 80 | Google-Extended |
Gemini AI training | |
| Cohere | Cohere | 80 | cohere-ai |
Cohere model training |
| ByteSpider | ByteDance | 75 | Bytespider |
TikTok and AI training |
| Meta-ExternalAgent | Meta | 75 | Meta-ExternalAgent |
Meta AI training |
| Applebot-Extended | Apple | 75 | Applebot-Extended |
Apple Intelligence training |
| YouBot | You.com | 75 | YouBot |
You.com AI search training |
| Amazonbot | Amazon | 70 | Amazonbot |
Alexa and Amazon AI |
| FacebookBot | Meta | 70 | FacebookBot |
Meta AI training |
AI Search Crawlers, Assistants and Commercial Scrapers
Section titled “AI Search Crawlers, Assistants and Commercial Scrapers”| Crawler | Company | Category | Score | User-Agent Pattern |
|---|---|---|---|---|
| OAI-SearchBot | OpenAI | AI search crawler | 80 | OAI-SearchBot |
| PerplexityBot | Perplexity | AI search crawler | 80 | PerplexityBot |
| ChatGPT-User | OpenAI | AI assistant (user-triggered fetch) | 85 | ChatGPT-User |
| Diffbot | Diffbot | Commercial scraper | 70 | Diffbot |
Search Crawlers (Lower Score)
Section titled “Search Crawlers (Lower Score)”Traditional search engines that may also feed AI features:
| Crawler | Company | Score | User-Agent Pattern | Note |
|---|---|---|---|---|
| Googlebot | 30 | Googlebot |
Primary search indexing | |
| Bingbot | Microsoft | 30 | bingbot |
Bing search + Copilot |
| DuckDuckBot | DuckDuckGo | 30 | DuckDuckBot |
Privacy-focused search |
| Applebot | Apple | 30 | Applebot |
Siri and Spotlight |
| YandexBot | Yandex | 35 | YandexBot |
Russian search + AI |
| Baiduspider | Baidu | 40 | Baiduspider |
Chinese search + AI |
SEO and Analytics Crawlers
Section titled “SEO and Analytics Crawlers”| Crawler | Company | Score | User-Agent Pattern |
|---|---|---|---|
| SemrushBot | Semrush | 50 | SemrushBot |
| AhrefsBot | Ahrefs | 50 | AhrefsBot |
| MJ12bot | Majestic | 50 | MJ12bot |
| DotBot | Moz | 50 | DotBot |
HTTP Client Libraries and CLI Tools
Section titled “HTTP Client Libraries and CLI Tools”Matched by User-Agent like any other agent:
| Library | Pattern | Score |
|---|---|---|
| Python Requests | python-requests |
55 |
| Go HTTP Client | Go-http-client |
55 |
| Java HTTP Client | Apache-HttpClient |
55 |
| Scrapy | Scrapy |
65 |
| cURL | curl/ |
45 |
| Wget | Wget/ |
45 |
Where crawler activity is reported
Section titled “Where crawler activity is reported”Individual crawler hits land in the Detections table like anything else, but the report built for them is AI Crawlers & Agents (AI Crawlers in the sidebar, at /verified-agents). It answers a question a score alone cannot: whether the crawler was who it said it was.
Requests that claimed a known agent are split three ways, at the request level:
| Bucket | Meaning |
|---|---|
| Proven | a Web Bot Auth signature verified, or the address matched the operator’s published ranges with forward-confirmed reverse DNS |
| Unproven | the claim stands alone, with nothing corroborating it either way |
| Forged | the claim was made and the proof failed, which is an impersonation attempt |
The report’s Overview carries those totals for the whole property, its Agents tab breaks them down per crawler, and its Handshakes tab reports clients whose TLS handshake contradicts the identity they claimed. See Verified Agents for how each proof is produced.
A GPTBot row with a high AI scraper score therefore means two different things depending on which bucket it fell into, and only the report tells you which.
AI Browser Plugins (Client-Side)
Section titled “AI Browser Plugins (Client-Side)”WebDecoy’s Detection Script detects AI browser extensions installed by visitors. These extensions inject DOM elements, global variables, and content scripts that can be identified.
Primary AI Assistants
Section titled “Primary AI Assistants”High-confidence detection of major AI assistant extensions:
| Extension | Detection Flags | Score Impact |
|---|---|---|
| Claude Extension | claude_extension |
+15 points |
| ChatGPT Extension | chatgpt_extension |
+15 points |
| GitHub Copilot | copilot_extension |
+15 points |
| Gemini/Bard Extension | gemini_extension |
+15 points |
| Perplexity Extension | perplexity_extension |
+15 points |
Secondary AI Tools
Section titled “Secondary AI Tools”Other AI-powered browser extensions:
| Extension | Detection Flags | Score Impact |
|---|---|---|
| Monica AI | monica_extension |
+10 points |
| Jasper AI | jasper_extension |
+10 points |
| WriteSonic | writesonic_extension |
+10 points |
| Merlin AI | merlin_extension |
+10 points |
| Sider AI | sider_extension |
+10 points |
| MaxAI | maxai_extension |
+10 points |
Detection Methods
Section titled “Detection Methods”WebDecoy uses multiple techniques to detect AI browser plugins:
1. DOM Element Detection
Section titled “1. DOM Element Detection”AI extensions inject UI elements with identifiable patterns:
// Claude extension patterns'[class*="claude"]''[data-claude]''[data-anthropic]''[id*="claude-"]''claude-extension'
// ChatGPT extension patterns'[class*="chatgpt"]''[class*="openai"]''[data-chatgpt]''chatgpt-sidebar'
// Copilot patterns'[class*="copilot"]''[data-copilot]''github-copilot'2. Global Variable Detection
Section titled “2. Global Variable Detection”Extensions often expose global objects:
// Claudewindow.__claude__window.__CLAUDE__window.__anthropic__
// ChatGPT/OpenAIwindow.__chatgpt__window.__openai__window.chatGPTExtension
// Copilotwindow.__copilot__window.githubCopilot
// Generic AIwindow.__aiAssistant__window.__AI_EXTENSION__3. Shadow DOM Detection
Section titled “3. Shadow DOM Detection”Modern extensions use Shadow DOM for isolation. WebDecoy inspects:
- Custom element tag names (
<claude-assistant>,<chatgpt-sidebar>) - Shadow root content for AI-related patterns
- Nested shadow DOM structures
4. Custom Element Registry
Section titled “4. Custom Element Registry”Extensions register custom HTML elements:
// Checked custom elements'claude-assistant''claude-sidebar''claude-popup''chatgpt-assistant''chatgpt-sidebar''gpt-popup''copilot-assistant''copilot-suggestion''perplexity-assistant''gemini-assistant''monica-assistant''merlin-assistant''sider-assistant'Vision AI Detection
Section titled “Vision AI Detection”Vision AI bots represent a new category of AI-assisted browsing where AI agents directly control browser interactions. Unlike traditional browser extensions that assist users, Vision AI bots operate the browser autonomously by manipulating the DOM directly.
Vision AI detection is part of the standard detection script’s behavioral phase. There is no separate script tier.
What are Vision AI Bots?
Section titled “What are Vision AI Bots?”Vision AI bots are AI systems that:
- See the page visually using screenshots or DOM snapshots
- Interact programmatically by setting form values directly via JavaScript
- Skip human input patterns by not generating keyboard/mouse events
- Operate autonomously to fill forms, click buttons, and navigate sites
┌─────────────────────────────────────────────────────────────────┐│ VISION AI BOT INTERACTION │├─────────────────────────────────────────────────────────────────┤│ ││ Human User Vision AI Bot ││ ────────── ────────────── ││ ││ Keyboard → keydown event DOM Manipulation ││ → keyup event element.value = "text" ││ → input event ↓ ││ → value changes input event only ││ (no keyboard events!) ││ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Detection: Field has content but ZERO keyboard events │ ││ │ Score Impact: +40 points per field │ ││ └─────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────┘Known Vision AI Bots
Section titled “Known Vision AI Bots”| Bot/Tool | Type | Detection Method |
|---|---|---|
| Claude Computer Use | AI Agent | DOM manipulation, no keyboard events |
| Stagehand | Browser Automation | DOM manipulation, synthetic events |
| Browserbase Agents | Cloud Browser | DOM manipulation, headless signals |
| Playwright AI | Testing Framework | DOM manipulation, automation flags |
| Browser Use | AI Agent Framework | DOM manipulation, programmatic clicks |
How Detection Works
Section titled “How Detection Works”WebDecoy uses two complementary techniques to detect Vision AI bots:
- Ghost Click Detection - Clicks at positions where the mouse was never near
- FormAnalyzer - Form fields with content but no keyboard events
Ghost Click Detection
Section titled “Ghost Click Detection”Real users must move their mouse to a position before clicking there. Vision AI bots using element.click() or browser automation APIs can click anywhere without prior mouse movement.
┌─────────────────────────────────────────────────────────────────┐│ GHOST CLICK DETECTION │├─────────────────────────────────────────────────────────────────┤│ ││ Human User Vision AI Bot ││ ────────── ────────────── ││ ││ 1. Move mouse to button 1. Find element via DOM ││ 2. Hover over button 2. Call element.click() ││ 3. Click button 3. No mouse movement at all! ││ ││ Mouse path recorded: Mouse path recorded: ││ ▸ (100,50) → (150,80) → click ▸ click at (150,80) ││ (no prior movements!) ││ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Detection: Click with NO mouse activity within 100px │ ││ │ Score Impact: +45 points │ ││ └─────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────┘Key features:
- Tracks mouse position history with timestamps
- Checks if mouse was within 100px of click position in the 2 seconds before click
- Immediate report: after 2 clicks with no nearby mouse activity, the script sends a detection right away rather than waiting for the behavioral phase
- Works even if page navigates away immediately after click
FormAnalyzer (DOM Manipulation Detection)
Section titled “FormAnalyzer (DOM Manipulation Detection)”WebDecoy’s FormAnalyzer tracks keyboard events per form field and compares them against actual content:
1. Event Tracking
Section titled “1. Event Tracking”// FormAnalyzer tracks per-field keyboard activity{ "email_field": { keydownCount: 0, // No keydown events keyupCount: 0, // No keyup events inputCount: 1, // One input event (from DOM manipulation) pasteCount: 0, // No paste events contentLength: 25 // But field has 25 characters! }}2. Pattern Detection
Section titled “2. Pattern Detection”Each suspicious field is reported in metadata.behavior.formAnalysis.suspiciousFields with a reason, and WebDecoy’s server adds to the score per field:
reason |
Detection | Score |
|---|---|---|
content_without_keyboard |
Field has content but no keydown and no paste events | +40 |
high_dom_manipulation_ratio |
Value changes without recent keyboard activity outnumber half the keystrokes | +25 |
abnormal_keydown_keyup_ratio |
Keydown/keyup ratio outside 0.5 to 2.0 | +15 |
When totalDomManipulations reaches 3 or more, another +20 is added.
3. Typing Rhythm Analysis
Section titled “3. Typing Rhythm Analysis”Real humans have variable typing rhythms. Bots often have:
- Zero variance in keystroke timing
- Superhuman speed (< 30ms between keystrokes)
- Perfect consistency across all fields
Detection Flags
Section titled “Detection Flags”Click patterns are reported as flags (stored in the detection’s metadata.triggers). Form analysis is not a flag: it travels in metadata.behavior.formAnalysis and is scored as described above.
| Flag | Meaning | Score Impact |
|---|---|---|
ghost_clicks |
Clicks at positions with no prior mouse activity | +45 |
instant_clicks |
Clicks with no delay after mouse stops | +30 |
clicks_no_pre_movement |
Clicks without preceding mouse movement | +25 |
Example Detection Record
Section titled “Example Detection Record”{ "id": "det_xyz789", "source": "bot_scanner", "unified_score": 85, "threat_level": "HIGH",
"metadata": { "triggers": ["ghost_clicks"], "behavior": { "clickAnalysis": { "ghostClicks": true, "ghostClickRatio": 0.67, "instantClicks": false, "noPreMovement": true }, "formAnalysis": { "suspiciousFields": [ { "id": "email", "reason": "content_without_keyboard", "contentLength": 24, "confidence": 0.9 }, { "id": "message", "reason": "content_without_keyboard", "contentLength": 156, "confidence": 0.9 } ], "totalDomManipulations": 2, "fields": { "email": { "contentLength": 24, "keyCount": 0, "noKeyboardEvents": true }, "message": { "contentLength": 156, "keyCount": 0, "noKeyboardEvents": true } } } } }}Distinguishing from Legitimate Use Cases
Section titled “Distinguishing from Legitimate Use Cases”Not all DOM manipulation is malicious. WebDecoy accounts for:
| Scenario | How It Is Handled |
|---|---|
| Copy/paste | A field with a paste event is not reported as content without keyboard |
| Password managers and browser autofill | Can fill a field without keyboard events and so can look like DOM manipulation. Review the rest of the detection before acting on form analysis alone |
| Form pre-population | A field your own page pre-fills has content without keyboard events and can be reported the same way |
What to do with these signals
Section titled “What to do with these signals”Ghost clicks and form DOM manipulation are recorded as flags on the detection and raise its score. There is no separate rule language for flags. To act on them:
- Review them: open a detection to see its flags and form analysis.
- Protect the paths that matter: add your signup, login or checkout routes as protected paths, so a client that cannot earn clearance is challenged or refused there.
- Route them elsewhere: a webhook or SIEM integration receives the detection, flags included, so you can alert or act in your own tooling.
Filtering Vision AI Detections
Section titled “Filtering Vision AI Detections”The Detections table and API filter by source and score, not by individual flag:
| Filter | Value | What It Shows |
|---|---|---|
| Source | bot_scanner |
All client-side detections, where Vision AI flags come from |
| Minimum unified score | 70 |
High-confidence activity |
Open a detection to see which flags it carries.
API Example (the management API takes the Auth0 session token the dashboard uses, not an sk_live_ API key; see API Reference):
# High-confidence client-side detectionscurl -H "Authorization: Bearer $WEBDECOY_SESSION_JWT" \ "https://api.webdecoy.com/api/organizations/$ORG_ID/detections?source=bot_scanner&min_unified_score=70"Browser API observations
Section titled “Browser API observations”Generic API wrapping is retained as an observation. It does not identify an AI extension or add risk by itself; security and analytics integrations can wrap the same browser APIs.
API Wrapping
Section titled “API Wrapping”| Signal | Flag | Score Impact | Meaning |
|---|---|---|---|
| Wrapped Fetch API | wrapped_fetch |
0 points | window.fetch wrapping observed; no AI plugin attribution |
| Wrapped XHR | wrapped_xhr |
0 points | XMLHttpRequest.open wrapping observed; no AI plugin attribution |
| Modified MutationObserver | modified_mutation_observer |
+5 points | Observer constructor has been patched |
The detection script places wrapped_fetch and wrapped_xhr in
aiBrowserPlugins.observations, separately from aiBrowserPlugins.plugins.
When a report is sent, the flags remain in metadata.triggers for diagnostics.
The ingest scorer also assigns them zero risk, including flags from older tags.
Independent extension and automation evidence still contributes to the score.
Detection Logic
Section titled “Detection Logic”// Check if fetch has been wrappedvar fetchStr = window.fetch.toString();if (fetchStr.indexOf('[native code]') === -1) { // Observation only; the wrapper's purpose is unknown. flags.push('wrapped_fetch');}
// Check if XHR has been wrappedvar xhrStr = XMLHttpRequest.prototype.open.toString();if (xhrStr.indexOf('[native code]') === -1) { // XHR has been wrapped flags.push('wrapped_xhr');}Context Menu Modifications
Section titled “Context Menu Modifications”| Signal | Flag | Meaning |
|---|---|---|
| AI Context Menu | ai_context_menu |
Extension added AI options to right-click menu |
Understanding Detection Flags
Section titled “Understanding Detection Flags”When AI activity is detected, the script’s flags are stored on the detection in metadata.triggers:
Flag Categories
Section titled “Flag Categories”┌─────────────────────────────────────────────────────────────────┐│ DETECTION FLAGS BREAKDOWN │├─────────────────────────────────────────────────────────────────┤│ ││ Primary AI Extensions (15 pts each) ││ ──────────────────────────────────── ││ claude_extension, chatgpt_extension, copilot_extension, ││ gemini_extension, perplexity_extension ││ ││ Secondary AI Extensions (10 pts each) ││ ───────────────────────────────────── ││ monica_extension, jasper_extension, writesonic_extension, ││ merlin_extension, sider_extension, maxai_extension ││ ││ Suspicious Signals (5 pts each) ││ ─────────────────────────────── ││ modified_mutation_observer ││ ││ Diagnostic API observations (0 pts) ││ wrapped_fetch, wrapped_xhr ││ ││ Other Signals (8 pts each) ││ ───────────────────────── ││ generic_ai_extension, ai_context_menu ││ │└─────────────────────────────────────────────────────────────────┘Example Detection Record
Section titled “Example Detection Record”{ "id": "det_abc123", "source": "bot_scanner", "ip_address": "192.168.1.100",
"unified_score": 45, "threat_level": "MEDIUM",
"metadata": { "triggers": ["claude_extension", "wrapped_fetch"] },
"score_components": { "ai_scraper_score": 0 }}Filtering AI Detections
Section titled “Filtering AI Detections”In the Detections table, filter specifically for AI-related activity:
Filter Options
Section titled “Filter Options”| Filter | How to Use | Effect |
|---|---|---|
| Source = bot_scanner | Select source filter | Show client-side detections, where AI browser plugin flags come from |
| Minimum unified score | Set minimum score | Show only high-confidence activity |
| Impersonation only | ?agent_impersonation=true on the detections URL |
Show only requests that claimed a known agent and failed the proof |
| One agent | ?ai_scraper_name=GPTBot on the detections URL |
Show every request that claimed that identity, proven or not |
The forged counts in the agent trust report are links that set exactly these two parameters, so clicking a number lands you on the requests behind it rather than on a filter you have to rebuild.
Individual flags such as claude_extension are not a filter: open a detection to see its flags.
Score Impact
Section titled “Score Impact”AI browser plugin detection contributes to the overall bot score:
Scoring Breakdown
Section titled “Scoring Breakdown”| Detection | Points Added | Rationale |
|---|---|---|
| Single primary AI extension | +15 | Strong indicator of AI-assisted browsing |
| Multiple primary AI extensions | +15 each | Compounding evidence |
| Secondary AI extension | +10 | Common AI productivity tools |
| Fetch/XHR wrapping | 0 | Diagnostic observation; does not identify an AI extension |
| Modified MutationObserver | +5 | Separate constructor-patching signal |
| Generic AI signals | +8 | Unspecified AI activity |
Score Examples
Section titled “Score Examples”| Scenario | Flags | Added Score |
|---|---|---|
| Claude extension only | claude_extension |
+15 |
| ChatGPT + wrapped fetch | chatgpt_extension, wrapped_fetch |
+15 |
| Multiple AI tools | claude_extension, monica_extension, copilot_extension |
+40 |
| Wrapped APIs only | wrapped_fetch, wrapped_xhr |
0 |
Use Cases
Section titled “Use Cases”AI browser plugin flags raise a detection’s score; there is no separate rule language for them.
- Content and forms: add the routes you care about (premium content, signup, checkout) as protected paths. Enforcement there is per site and starts in Monitor mode.
- Alerting: send detections to a webhook or SIEM integration and alert on the flags in your own tooling.
WebDecoy does not report on visitors who are not automated, so it is not a tool for measuring AI adoption among your human audience.
API Access
Section titled “API Access”Access AI detection data via the WebDecoy API:
Detection Response Fields
Section titled “Detection Response Fields”Client-side flags are in metadata.triggers. The AI scraper fields are inside score_components, and ai_scraper_category and ai_scraper_name appear only when a known agent matched:
{ "metadata": { "triggers": ["claude_extension", "wrapped_fetch"] }, "score_components": { "ai_scraper_score": 0 }}Filtering API Requests
Section titled “Filtering API Requests”# Client-side detections, where AI browser plugin flags appearcurl -H "Authorization: Bearer $WEBDECOY_SESSION_JWT" \ "https://api.webdecoy.com/api/organizations/$ORG_ID/detections?source=bot_scanner"
# Every request that claimed to be GPTBotcurl -H "Authorization: Bearer $WEBDECOY_SESSION_JWT" \ "https://api.webdecoy.com/api/organizations/$ORG_ID/detections?ai_scraper_name=GPTBot"The API does not filter by flag; read metadata.triggers on each detection returned.
Privacy Considerations
Section titled “Privacy Considerations”AI browser plugin detection is designed to be:
- Non-invasive: Only checks for presence, doesn’t read content
- Privacy-respecting: Doesn’t capture what users type into AI tools
- Transparent: Detection signals are clearly documented
LLM Referral Tracking
Section titled “LLM Referral Tracking”When a visitor arrives at your site by clicking a link in an AI product (a ChatGPT conversation, a Perplexity answer, a Claude response), WebDecoy counts the visit as an AI referral. Human visits are counted, never stored as detections.
How It Works
Section titled “How It Works”The detection script sends an install heartbeat once per session. On the session’s first page it adds where the visit came from, reduced before it leaves the page: the referrer’s origin only (and only when it is another site), plus the landing path with just the utm_source, ref and utm_medium parameters. WebDecoy classifies that against its AI platform table and adds one to a daily counter for the platform and landing path. Nothing else about the visit is kept.
Visitor clicks link in ChatGPT → Lands on your site │ ├── document.referrer = "https://chatgpt.com/..." │ ├── Heartbeat carries { r: "https://chatgpt.com", u: "/landing-path" } │ └── WebDecoy counts one ChatGPT referral for that day and landing pathWhen there is no Referer, a campaign tag that names a known platform (for example ?utm_source=chatgpt.com) is used instead. A Referer from any other site always wins over a tag. Server-side sensors (edge, Vercel log drain, WordPress plugin, Node SDK) can report the same counts; when more than one source reports for a site on a day, WebDecoy keeps one so visits are not counted twice.
Likely referrals (Vercel log drain)
Section titled “Likely referrals (Vercel log drain)”Many AI apps strip the referrer, so a person who clicks a link in an answer often arrives looking like a direct visit. The Vercel log drain sees the other half of that click: when someone asks an assistant about a page, its user fetcher (ChatGPT-User, Perplexity-User, Claude-User, Gemini-User, Meta-ExternalFetcher) fetches the page from your site moments before.
A visit is counted as a likely referral from that assistant when:
- it arrived with no referrer, no
utm_tag and no ad click id (gclid,fbclidand similar), - exactly one assistant’s user fetcher fetched the same page (query string ignored, trailing slash ignored) in the 15 minutes before, or in the same minute,
- and the visit was not itself reported as a bot.
Training and search crawlers never count, because nobody is waiting on them. Claude Code’s fetches never count, because they run for a developer. If two assistants fetched the page in the window, the visit is not counted at all rather than credited to one of them. Each visitor counts once per page per delivery.
Likely referrals are an estimate and are shown as one: on the Referrals tab as “+N likely” beside each platform’s counted visits, with an explanation. They are never added into the referral count, the dashboard total, or the crawl-to-referral ratio. A fetch can be for someone who read the answer and never clicked, and a direct visit a minute later can be someone else. User-fetcher IPs are not verified on this path, so a forged fetcher could raise the estimate. Only counts are stored, never anything about a visitor.
Supported AI Platforms
Section titled “Supported AI Platforms”| Platform | Domains Tracked |
|---|---|
| ChatGPT | chat.openai.com, chatgpt.com |
| Perplexity | perplexity.ai, www.perplexity.ai |
| Gemini | gemini.google.com |
| Claude | claude.ai |
| DeepSeek | deepseek.com, www.deepseek.com, chat.deepseek.com |
| Copilot | copilot.microsoft.com |
| You.com | you.com, www.you.com |
| Phind | phind.com, www.phind.com |
| Kagi | kagi.com, www.kagi.com |
| Meta AI | meta.ai, www.meta.ai |
| Grok | grok.com, www.grok.com |
Viewing LLM Referral Data
Section titled “Viewing LLM Referral Data”AI referrals appear on the AI Traffic page and in the dashboard’s AI referral summary, which show:
- Referrals per AI platform
- Referrals per day
- Top landing pages receiving AI referral traffic
Referral fields on detections
Section titled “Referral fields on detections”A referral is not a detection. But when a request that is stored as a detection (a bot that scored high enough, a decoy hit) carries an AI platform referrer or campaign tag, ingest records it in the detection’s metadata:
| Metadata key | Value |
|---|---|
is_llm_referral |
"true" |
llm_platform |
Platform name, e.g. ChatGPT |
llm_category |
ai_assistant or ai_search |
llm_referral_signal |
referer, or the campaign parameter that matched (utm_source, ref, utm_medium) |
Related Documentation
Section titled “Related Documentation”- AI Scraper Scoring - Detailed AI crawler scoring methodology
- Verified Agents - Proven, unproven and forged agent claims, and the report that splits them
- Detection Script - JavaScript-based bot detection
- Threat Scoring - Overall threat assessment
- Viewing Detections - Working with detection data