Every blocking strategy has two failure modes: bots get through, or real users get blocked. The second one costs you customers silently — they hit a CAPTCHA wall or a 403 and never come back. This guide is about blocking bots without that cost.
The layered defense model
Think in layers, cheapest first:
- Cheap filters (milliseconds): known-bad user agents, obvious garbage requests, honeypot form fields.
- Reputation (server-side): is this IP from a datacenter, a TOR exit node, or a residential ISP? Has this IP misbehaved on your properties before?
- Behavior (server + browser): request velocity across 1/10/60-minute windows; did JavaScript actually run; is the browser environment consistent?
- Challenge (only when unsure): a Cloudflare Turnstile challenge converts suspicious-but-human traffic into verified sessions.
- Decision API: combine all of the above into one
allow/challenge/blockanswer per request.
The mistake almost everyone makes: jumping from layer 1 straight to "block everything suspicious". That's where false positives — blocked customers — come from.
The false-positive trap (and how to escape it)
Real users get blocked when your rules are too blunt:
- Blocking all datacenter IPs also blocks corporate VPNs, university networks, and users behind privacy tools.
- Hard rate limits punish offices behind one NAT address.
- CAPTCHA on everything punishes every visitor for one bad actor.
The escape: make blocking conditional and explainable. Score first; challenge when unsure; block only when confident; log why every decision happened so you can tune it.
A concrete setup that respects real users
PHP sites (WordPress, Laravel, custom): include the XAntiBot PHP package at the top of your entry point. It runs the layered checks server-side, before HTML is sent:
// First line of the entry point — full package: xantibot.com/docs
require __DIR__ . '/xantibot-protect.php';
The package handles allow/challenge/block against the detection API, keeps the API key server-side, and fails safe (if the API is unreachable, a configurable failure mode applies — you choose deny or allow during outages).
Node/Express APIs: call the detection API in a middleware before your routes (full tutorial: Protect a Node.js Express API from Bots).
Forms and signups: add a honeypot field, then challenge-first protection for repeat offenders — not a permanent CAPTCHA for everyone.
Protecting signup specifically
Fake registrations are the most common complaint we hear. What works, in order:
- Honeypot field (invisible to humans).
- Rate limit by IP and by email domain.
- Challenge only when the request already looks suspicious.
- Email verification — a bot that can't receive mail can't activate.
XAntiBot's own signup flow uses exactly this pattern — it's how we keep our own free tier clean.
Tuning loop (monthly)
- Review decision logs: which blocks were correct? Which reasons appear on false positives?
- Adjust thresholds one notch at a time.
- Watch analytics after every change — a dip in conversions means you went too far.
FAQ
Will bot blocking slow my site? A detection API call adds tens of milliseconds — invisible next to typical page loads. PHP integration runs before your HTML. Can I block bots without any CAPTCHA? Yes — that's the design goal. CAPTCHA/challenges become a rare fallback for genuinely uncertain cases. What about good bots like Googlebot? Verified-crawler checks (reverse-DNS) let real search engines through while fake "Googlebot" user-agents get scored like any bot.
Start here
- Create a free account → get an API key → protect your first page today.
- Deeper: PHP Bot Protection Tutorial · Cloudflare Turnstile Integration Guide · Bot Detection vs Rate Limiting.