Skip to content

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.

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 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.

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 Google 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

Traditional search engines that may also feed AI features:

Crawler Company Score User-Agent Pattern Note
Googlebot Google 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
Crawler Company Score User-Agent Pattern
SemrushBot Semrush 50 SemrushBot
AhrefsBot Ahrefs 50 AhrefsBot
MJ12bot Majestic 50 MJ12bot
DotBot Moz 50 DotBot

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

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.


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.

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

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

WebDecoy uses multiple techniques to detect AI browser plugins:

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'

Extensions often expose global objects:

// Claude
window.__claude__
window.__CLAUDE__
window.__anthropic__
// ChatGPT/OpenAI
window.__chatgpt__
window.__openai__
window.chatGPTExtension
// Copilot
window.__copilot__
window.githubCopilot
// Generic AI
window.__aiAssistant__
window.__AI_EXTENSION__

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

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 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.

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 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
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

WebDecoy uses two complementary techniques to detect Vision AI bots:

  1. Ghost Click Detection - Clicks at positions where the mouse was never near
  2. FormAnalyzer - Form fields with content but no keyboard events

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

WebDecoy’s FormAnalyzer tracks keyboard events per form field and compares them against actual content:

// 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!
}
}

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.

Real humans have variable typing rhythms. Bots often have:

  • Zero variance in keystroke timing
  • Superhuman speed (< 30ms between keystrokes)
  • Perfect consistency across all fields

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
{
"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
}
}
}
}
}
}

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

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.

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):

Terminal window
# High-confidence client-side detections
curl -H "Authorization: Bearer $WEBDECOY_SESSION_JWT" \
"https://api.webdecoy.com/api/organizations/$ORG_ID/detections?source=bot_scanner&min_unified_score=70"

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.

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.

// Check if fetch has been wrapped
var 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 wrapped
var xhrStr = XMLHttpRequest.prototype.open.toString();
if (xhrStr.indexOf('[native code]') === -1) {
// XHR has been wrapped
flags.push('wrapped_xhr');
}
Signal Flag Meaning
AI Context Menu ai_context_menu Extension added AI options to right-click menu

When AI activity is detected, the script’s flags are stored on the detection in metadata.triggers:

┌─────────────────────────────────────────────────────────────────┐
│ 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 │
│ │
└─────────────────────────────────────────────────────────────────┘
{
"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
}
}

In the Detections table, filter specifically for AI-related activity:

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.


AI browser plugin detection contributes to the overall bot score:

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
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

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.


Access AI detection data via the WebDecoy API:

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
}
}
Terminal window
# Client-side detections, where AI browser plugin flags appear
curl -H "Authorization: Bearer $WEBDECOY_SESSION_JWT" \
"https://api.webdecoy.com/api/organizations/$ORG_ID/detections?source=bot_scanner"
# Every request that claimed to be GPTBot
curl -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.


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

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.

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 path

When 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.

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, fbclid and 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.

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

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

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)