The Bot Problem Nobody Talks About
If you're running a web app in 2026, roughly 40% of your traffic isn't human. Scrapers, credential stuffers, fake signups — they eat your bandwidth, pollute your analytics, and sometimes steal your data.
Most developers slap on a CAPTCHA and call it a day. But CAPTCHAs are a UX nightmare, and sophisticated bots solve them anyway. There's a better approach: checking the reputation of incoming requests before they even reach your app.
The Two Signals That Matter Most
After building fraud detection systems for years, I've found that two data points catch 90%+ of malicious traffic:
1. IP Intelligence
Every request comes from an IP address, and that IP tells a story:
- Is it a known proxy/VPN/Tor exit node? Legitimate users sometimes use VPNs, but bots almost always do.
- Is it from a datacenter or residential ISP? Most real users browse from home or mobile — datacenter IPs are a red flag.
- Has this IP been reported for abuse? Threat intelligence feeds track IPs involved in spam, attacks, and fraud.
- What's the geolocation? A "US user" connecting from a hosting provider in Eastern Europe is suspicious.
import requests
# Quick IP reputation check
response = requests.get(
"https://ipasis.com/api/scan/ip/185.220.101.1",
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
data = response.json()
print(f"Risk Score: {data['risk_score']}/100")
print(f"Is VPN: {data['is_vpn']}")
print(f"Is Datacenter: {data['is_datacenter']}")
print(f"Abuse Reports: {data['abuse_count']}")
2. Email Validation
For signups and form submissions, the email address is your second line of defense:
- Does the domain actually exist? Disposable email services (guerrillamail, tempmail) are bot favorites.
- Is the mailbox real? SMTP verification catches typos and fake addresses.
- Is it a known disposable/temporary email? There are 10,000+ disposable domains.
- Is the domain newly registered? Fresh domains often exist solely for fraud.
# Email validation
response = requests.get(
"https://ipasis.com/api/scan/email/suspicious@tempmail.xyz",
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
email_data = response.json()
print(f"Valid: {email_data['is_valid']}")
print(f"Disposable: {email_data['is_disposable']}")
print(f"Domain Age: {email_data['domain_age_days']} days")
Combining Both: A Practical Middleware
Here's a real-world pattern I use — a middleware that scores every signup request:
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
IPASIS_KEY = "your-api-key"
def check_reputation(ip, email):
"""Score a signup attempt using IP + email intelligence."""
risk = 0
flags = []
# Check IP
ip_resp = requests.get(
f"https://ipasis.com/api/scan/ip/{ip}",
headers={"Authorization": f"Bearer {IPASIS_KEY}"}
).json()
if ip_resp.get("is_vpn"):
risk += 20
flags.append("vpn_detected")
if ip_resp.get("is_datacenter"):
risk += 30
flags.append("datacenter_ip")
if ip_resp.get("abuse_count", 0) > 5:
risk += 25
flags.append("known_abuser")
# Check email
email_resp = requests.get(
f"https://ipasis.com/api/scan/email/{email}",
headers={"Authorization": f"Bearer {IPASIS_KEY}"}
).json()
if email_resp.get("is_disposable"):
risk += 40
flags.append("disposable_email")
if not email_resp.get("is_valid"):
risk += 50
flags.append("invalid_email")
return {"risk_score": min(risk, 100), "flags": flags}
@app.route("/signup", methods=["POST"])
def signup():
ip = request.remote_addr
email = request.json.get("email", "")
result = check_reputation(ip, email)
if result["risk_score"] > 60:
return jsonify({"error": "Signup blocked", "reason": "suspicious_activity"}), 403
elif result["risk_score"] > 30:
# Flag for manual review but allow
return jsonify({"status": "pending_review"}), 200
else:
# Clean signup, proceed normally
return jsonify({"status": "approved"}), 200
Why This Beats CAPTCHAs
| Approach | User Friction | Bot Detection Rate | Latency |
|---|---|---|---|
| reCAPTCHA v2 | High (click images) | ~85% | 2-5s |
| reCAPTCHA v3 | Low (invisible) | ~70% | 1-3s |
| IP + Email Intelligence | Zero | ~92% | <200ms |
The key advantage: zero user friction. Your legitimate users never see a challenge. The API call happens server-side in milliseconds, and bad actors get blocked silently.
Getting Started
If you want to try this approach, IPASIS offers a free tier with 1,000 requests/day — enough to protect a small-to-medium app. You can also test any IP or email interactively on the free scanner.
The API docs cover authentication, rate limits, and response formats. The API is REST-based with JSON responses — no SDK required.
Key Takeaways
- Don't rely solely on CAPTCHAs — they hurt UX and sophisticated bots bypass them.
- IP intelligence catches infrastructure-level fraud (VPNs, datacenter IPs, known abusers).
- Email validation catches identity-level fraud (disposable emails, fake domains).
- Combine both for a risk score that lets you block, flag, or approve in real-time.
- Server-side checks = zero user friction — your real users never know it's happening.
Bot detection doesn't have to mean annoying your users. Sometimes the smartest security is invisible.
What bot detection approach are you using? Drop a comment — I'm curious what's working for others in 2026.
Top comments (0)