Proxy Detection API - VPN, Tor & Proxy Detection
IPBot exposes security signals under security. These signals include an overall
risk_score plus a human-readable risk_reasons[] list.
Treat these as explainable heuristics to power your own policies.
Every detection includes human-readable reasons you can audit and act on.
VPN, proxy, Tor, datacenter, and threat list matches in one response.
Why Proxy Detection Matters
Section titled “Why Proxy Detection Matters”Fraudsters and bad actors use VPNs, proxies, and Tor to hide their identity and bypass security controls. According to industry research, ecommerce companies lose $48 billion annually to fraud, with VPN and proxy usage being a key indicator of suspicious activity.
Key statistics on proxy usage in fraud:
- 75% of ecommerce businesses are increasing fraud prevention budgets
- Fraudsters manipulate digital fingerprints using VPNs and proxies to bypass restrictions
- Multiple user accounts accessing a site from the same IP is a strong fraud indicator
- Orders from IPs in different countries than billing addresses require additional review
Security Response Fields
Section titled “Security Response Fields”The IPBot API returns comprehensive security data:
{ "security": { "risk_score": 75, "risk_reasons": ["hosting_provider", "vpn_detected", "datacenter_ip"], "usage_type": "Hosting", "is_datacenter": true, "is_proxy": true, "threat_level": "Medium", "threat_lists": ["firehol_level1"] }}| Field | Description | Type | Example |
|---|---|---|---|
risk_score | Overall risk score (0-100) | number | 75 |
risk_reasons | Human-readable risk factors | string[] | [“vpn_detected”] |
usage_type | IP usage classification | string | ”Hosting” |
is_datacenter | Whether IP is from datacenter | boolean | true |
is_proxy | Whether proxy-like behavior detected | boolean | true |
threat_level | Overall threat assessment | string | ”Medium” |
threat_lists | Matched threat intelligence feeds | string[] | [“firehol_level1”] |
Detection Methods
Section titled “Detection Methods”IPBot uses multiple detection methods to identify proxies and VPNs:
ASN-Based Detection
Section titled “ASN-Based Detection”Known VPN and proxy providers operate from specific ASNs:
// Example VPN provider ASNs (these are commonly flagged)const vpnAsns = [ "AS9009", // M247 (common VPN hosting) "AS62041", // Datacamp "AS212238", // Datacamp Limited "AS60068", // CDN77 "AS202422", // G-Core Labs];IPBot maintains lists of known VPN provider ASNs and flags connections from these networks.
Datacenter Detection
Section titled “Datacenter Detection”Legitimate users typically connect from residential ISPs. Connections from datacenters are suspicious:
const data = await fetch("https://api.ipbot.com/").then((r) => r.json());
if (data.security.is_datacenter) { // Flag for review - datacenter IPs are rarely used by regular users addFraudFlag("datacenter_connection", { network: data.network.org, asn: data.network.asn, });}Tor Exit Node Detection
Section titled “Tor Exit Node Detection”IPBot checks against the official Tor exit node list:
if (data.security.risk_reasons.includes("tor_exit")) { // Tor exit nodes are used for anonymous browsing // May be legitimate privacy use or malicious activity handleTorConnection(clientIp);}Threat Intelligence Feeds
Section titled “Threat Intelligence Feeds”IPBot integrates with open threat intelligence sources:
| Feed | Description |
|---|---|
| Firehol | Aggregated IP blocklists for known attackers |
| Tor Project | Official Tor exit node list |
| Spamhaus | Spam and abuse sources |
| Datacenter Lists | Cloud and hosting provider IP ranges |
Use Cases
Section titled “Use Cases”E-commerce Fraud Prevention
Section titled “E-commerce Fraud Prevention”Detect suspicious orders before they result in chargebacks:
async function assessOrderRisk(order) { const data = await fetch(`https://api.ipbot.com/${order.clientIp}`).then( (r) => r.json(), );
const riskFactors = []; let riskScore = 0;
// Proxy/VPN detection if (data.security.is_proxy) { riskFactors.push("VPN or proxy detected"); riskScore += 30; }
// Datacenter IP if (data.security.is_datacenter) { riskFactors.push("Datacenter IP"); riskScore += 25; }
// Tor exit node if (data.security.risk_reasons.includes("tor_exit")) { riskFactors.push("Tor exit node"); riskScore += 40; }
// Location mismatch if (data.location.country_code !== order.billingCountry) { riskFactors.push("IP country differs from billing country"); riskScore += 20; }
// High-risk region const highRiskCountries = ["NG", "GH", "PK", "BD"]; if (highRiskCountries.includes(data.location.country_code)) { riskFactors.push("High-fraud region"); riskScore += 15; }
return { score: Math.min(riskScore, 100), factors: riskFactors, recommendation: riskScore > 50 ? "review" : "approve", };}Account Registration Protection
Section titled “Account Registration Protection”Prevent fake account creation:
import requests
def validate_registration(client_ip: str, email: str) -> dict: data = requests.get(f"https://api.ipbot.com/{client_ip}").json()
blocks = []
# Block datacenter registrations (bots) if data["security"]["is_datacenter"]: blocks.append("Datacenter IPs cannot register accounts")
# Require additional verification for VPN users if data["security"]["is_proxy"]: return { "allowed": True, "requires_verification": True, "reason": "VPN detected - phone verification required" }
# Block Tor completely for registrations if "tor_exit" in data["security"]["risk_reasons"]: blocks.append("Tor connections not allowed for registration")
# Block if on threat lists if data["security"]["threat_lists"]: blocks.append(f"IP on threat list: {data['security']['threat_lists']}")
if blocks: return {"allowed": False, "reasons": blocks}
return {"allowed": True, "requires_verification": False}Content Access Control
Section titled “Content Access Control”Enforce geo-restrictions while detecting bypass attempts:
async function checkContentAccess(clientIp, contentId) { const data = await fetch(`https://api.ipbot.com/${clientIp}`).then((r) => r.json(), ); const content = await getContentRules(contentId);
// Check if content is available in user's country const userCountry = data.location.country_code; if (!content.availableCountries.includes(userCountry)) { return { allowed: false, reason: "Not available in your region" }; }
// Detect VPN/proxy bypass attempts if (data.security.is_proxy) { // User might be trying to bypass geo-restrictions return { allowed: false, reason: "VPN/proxy detected. Disable to access content.", suggestion: "Connect without VPN to verify your location", }; }
return { allowed: true };}Login Security
Section titled “Login Security”Add friction for suspicious login attempts:
async function assessLoginRisk(userId, clientIp, userAgent) { const data = await fetch(`https://api.ipbot.com/${clientIp}`).then((r) => r.json(), ); const userHistory = await getUserLoginHistory(userId);
let riskLevel = "low"; const challenges = [];
// New location if (!userHistory.countries.includes(data.location.country_code)) { riskLevel = "medium"; challenges.push("new_location"); }
// VPN when user doesn't normally use VPN if (data.security.is_proxy && !userHistory.usesVpn) { riskLevel = "medium"; challenges.push("unexpected_vpn"); }
// Datacenter IP for non-API user if (data.security.is_datacenter && !userHistory.isApiUser) { riskLevel = "high"; challenges.push("datacenter_login"); }
// Tor for normal user if (data.security.risk_reasons.includes("tor_exit")) { riskLevel = "high"; challenges.push("tor_login"); }
// Determine authentication requirements if (riskLevel === "high") { return { action: "block", reason: "Suspicious connection" }; } else if (riskLevel === "medium") { return { action: "mfa", challenges }; }
return { action: "allow" };}Integration Examples
Section titled “Integration Examples”JavaScript/TypeScript
Section titled “JavaScript/TypeScript”interface SecurityInfo { riskScore: number; isProxy: boolean; isDatacenter: boolean; isTor: boolean; threatLevel: string; riskReasons: string[];}
async function getSecurityInfo(ip?: string): Promise<SecurityInfo> { const url = ip ? `https://api.ipbot.com/${ip}` : "https://api.ipbot.com/"; const response = await fetch(url); const data = await response.json();
return { riskScore: data.security.risk_score, isProxy: data.security.is_proxy, isDatacenter: data.security.is_datacenter, isTor: data.security.risk_reasons.includes("tor_exit"), threatLevel: data.security.threat_level, riskReasons: data.security.risk_reasons, };}
// Usageconst security = await getSecurityInfo();if (security.isProxy || security.riskScore > 50) { requireAdditionalVerification();}Python
Section titled “Python”import requestsfrom dataclasses import dataclassfrom typing import List
@dataclassclass SecurityInfo: risk_score: int is_proxy: bool is_datacenter: bool is_tor: bool threat_level: str risk_reasons: List[str] threat_lists: List[str]
def get_security_info(ip: str = "") -> SecurityInfo: url = f"https://api.ipbot.com/{ip}" if ip else "https://api.ipbot.com/" response = requests.get(url) data = response.json()
sec = data["security"] return SecurityInfo( risk_score=sec["risk_score"], is_proxy=sec["is_proxy"], is_datacenter=sec["is_datacenter"], is_tor="tor_exit" in sec.get("risk_reasons", []), threat_level=sec["threat_level"], risk_reasons=sec.get("risk_reasons", []), threat_lists=sec.get("threat_lists", []) )
# Usagesecurity = get_security_info()if security.is_tor: block_access("Tor connections not allowed")elif security.is_proxy and security.risk_score > 50: require_captcha()cURL Examples
Section titled “cURL Examples”# Get security info for any IPcurl -s https://api.ipbot.com/8.8.8.8 | jq '.security'
# Check if proxy detectedcurl -s https://api.ipbot.com/ | jq -r '.security.is_proxy'
# Get risk scorecurl -s https://api.ipbot.com/ | jq -r '.security.risk_score'
# Get all risk reasonscurl -s https://api.ipbot.com/8.8.8.8 | jq -r '.security.risk_reasons[]'
# Check threat listscurl -s https://api.ipbot.com/8.8.8.8 | jq -r '.security.threat_lists[]'
# Combined location and security checkcurl -s https://api.ipbot.com/ | jq '{country: .location.country_code, risk: .security.risk_score, proxy: .security.is_proxy}'Best Practices
Section titled “Best Practices”Layered Security
Section titled “Layered Security”Don’t rely solely on proxy detection. Combine with other signals:
async function calculateTotalRisk(clientIp, userAgent, email) { const ipData = await fetch(`https://api.ipbot.com/${clientIp}`).then((r) => r.json(), );
let totalRisk = 0;
// IP-based signals totalRisk += ipData.security.risk_score * 0.4;
// Proxy penalty if (ipData.security.is_proxy) totalRisk += 15;
// Email analysis if (isDisposableEmail(email)) totalRisk += 20; if (isRecentlyCreatedDomain(email)) totalRisk += 10;
// Device fingerprinting const deviceRisk = await getDeviceRiskScore(userAgent); totalRisk += deviceRisk * 0.2;
// Behavioral analysis const behaviorRisk = await getBehaviorScore(clientIp); totalRisk += behaviorRisk * 0.2;
return Math.min(totalRisk, 100);}Handle False Positives
Section titled “Handle False Positives”Some legitimate users use VPNs for privacy. Allow them to proceed with verification:
if (security.isProxy && security.riskScore < 50) { // Low-risk VPN user - allow with friction return { action: "verify", message: "VPN detected. Please verify your identity.", methods: ["email", "sms"], };}Cache Appropriately
Section titled “Cache Appropriately”Proxy status can change, but not frequently:
// Cache proxy detection for 1 hourconst CACHE_TTL = 60 * 60 * 1000;
async function getCachedSecurityInfo(ip) { const cached = cache.get(`security:${ip}`); if (cached && Date.now() - cached.timestamp < CACHE_TTL) { return cached.data; }
const data = await fetch(`https://api.ipbot.com/${ip}`).then((r) => r.json()); cache.set(`security:${ip}`, { data: data.security, timestamp: Date.now() }); return data.security;}Related Documentation
Section titled “Related Documentation”- API Reference - Full endpoint documentation
- Response Schema - Complete field reference
- IP Reputation - Risk scoring details
- ASN Lookup - Network ownership information
- Solutions - Implementation patterns