Plant, log, trace.
Honeypots are the one detection method with a 0% false-positive rate. A trigger is proof, not signal.
Place a trap
Inject invisible bait — links, fields, watermarks. Hidden via CSS or zero-width unicode. Real users can't see them.
Watch for triggers
Every trap hit is logged with full request context. Score immediately set to 1.0. No ambiguity, no judgment call.
Trace the source
Dynamic traps tie each token back to a session. Proxy rotators get caught — same trap, different IP = automation.
Three ways to plant bait.
Layer them. Static traps catch HTTP scrapers. Dynamic traps catch proxy rotation. Watermarks trace stolen content. Together they cover every scrape modality.
Static traps
Invisible links + form fields injected into your HTML. CSS-hidden (position: absolute; left:-9999px). No JavaScript required — catches HTTP-only scrapers that ignore CSS rendering.
Dynamic traps
detect.js generates per-session trap URLs with HMAC-signed tokens. Each visitor gets a unique trap set — bots can't filter by pattern. Catches proxy rotation when same token loads from different IPs.
Content watermarks
Zero-width unicode markers (U+200B, U+200C, U+200D, U+FEFF) embedded in page text. Invisible on render, survives copy-paste. Trace scraped content back to the exact session that grabbed it.
Honeypots are the cleanest verdict you'll ever get.
Zero false positives
Real browsers never render hidden links. Real users never submit hidden form fields. A trigger means a bot — guaranteed.
Catches HTTP-only scrapers
python-requests, curl, Go-http-client parse raw HTML — they walk every <a href> blindly. Static traps catch them on the first request.
Proxy rotation tells
Dynamic tokens tied to session ID. If token X loads from IP A then IP B within 10 seconds, you've caught a residential proxy rotation in action.
Content traceability
Watermarks survive scraping. If your content shows up in an AI dataset, the embedded marker proves which scrape session captured it.
Designed to be invisible.
No JavaScript required
Static traps work on any page. Even users with JS disabled get full functionality — they just never see the trap.
Per-session rotation
Dynamic trap URLs change every session. No way for a bot to maintain a denylist — every visit has new traps.
Validated automatically
Run a one-click verification check from the dashboard. We fetch your site and confirm the trap snippet is present.
Configurable density
2, 3, 5, or 8 traps per page. More traps = higher detection rate. Sites with sparse content can dial up; busy pages can dial down.