IP Reputation API - Risk Scoring and Threat Detection
IPBot’s risk scoring is designed to be explainable. Instead of a black box, responses include
evidence.signals[] with labels, severity, and confidence so you can build stable UI
and internal policy rules.
curl -s https://api.ipbot.com/v1/ip/8.8.8.8 | jq ‘{score, classification, signals: .evidence.signals}’Pair this with caching guidance in Rate Limits.
What Is IP Reputation?
Section titled “What Is IP Reputation?”IP reputation is a trust assessment for an IP address based on its historical behavior, network characteristics, and presence on threat intelligence feeds. Unlike simple geolocation that answers “where is this IP?”, reputation scoring answers “should I trust this IP?”
Every IP address accumulates a digital footprint over time. Mail servers that send spam get blacklisted. IPs used for DDoS attacks appear on abuse databases. VPN and proxy services operate from known IP ranges. Datacenters host both legitimate services and malicious infrastructure. IP reputation aggregates these signals into actionable intelligence.
The global IP reputation and fraud detection market reached $3.2 billion in 2024 and is projected to grow at 14.8% CAGR through 2030. This growth is driven by increasing online fraud, regulatory compliance requirements, and the need for real-time risk assessment in digital transactions.
How IPBot Calculates Risk Scores
Section titled “How IPBot Calculates Risk Scores”IPBot generates a risk score from 0-100 for every IP address, where 0 indicates minimal risk and 100 indicates maximum risk. Unlike black-box scoring systems, IPBot provides complete transparency about what factors contributed to the score.
Scoring Factors
Section titled “Scoring Factors”Connection Type Analysis (0-30 points)
- VPN detection: +15 to +25 points depending on the provider
- Proxy detection: +10 to +20 points based on proxy type
- Tor exit node: +25 to +30 points (highest anonymization)
- Residential proxy: +20 points (often used for fraud)
Infrastructure Classification (0-25 points)
- Datacenter/hosting IP: +5 to +15 points
- Cloud provider ranges: +5 to +10 points
- Known bulletproof hosting: +20 to +25 points
Threat Intelligence (0-45 points)
- Presence on spam blacklists: +5 to +15 points per list
- Abuse database entries: +10 to +20 points
- Known malware infrastructure: +15 to +25 points
- Recent attack source: +10 to +20 points
These factor weights are combined probabilistically (a bounded noisy-OR), not linearly summed — so multiple signals never simply pile up at 100, and the score stays on a smooth, calibrated 0-100 curve.
Score Granularity & Data Tiers
Section titled “Score Granularity & Data Tiers”Scores are calibrated, not cosmetic. Two IPs with different evidence get different scores. Two IPs with identical evidence — for example several public proxies on the same network sharing the same threat-list and proxy-detection signals — correctly receive the same score; IPBot does not manufacture per-IP differences the underlying data cannot support.
Fine-grained per-IP differentiation (continuous proxy fraud scores, proxy recency) depends on enhanced/commercial proxy intelligence. On base data, expect conservative risk classification and bands rather than a unique number for every individual IP.
Response Structure
Section titled “Response Structure”{ "score": { "risk_score": 65, "verdict": "challenge", "recommended_action": "captcha_challenge" }, "classification": { "threat_level": "Medium", "is_proxy": true, "is_vpn": true, "is_tor": false, "is_datacenter": true, "is_known_crawler": false, "confidence": "medium" }, "evidence": { "signals": [ { "category": "privacy", "label": "VPN", "severity": "medium", "confidence": "medium" }, { "category": "network", "label": "Datacenter", "severity": "low", "confidence": "high" } ] }}Use Cases for IP Reputation
Section titled “Use Cases for IP Reputation”Fraud Prevention in E-commerce
Section titled “Fraud Prevention in E-commerce”Online fraud costs businesses over $48 billion annually. IP reputation provides a critical first-line defense by identifying suspicious connections before transactions complete.
Implementation Pattern:
async function assessTransactionRisk(ip, orderValue) { const response = await fetch(`https://api.ipbot.com/v1/ip/${ip}`); const data = await response.json();
const { score, classification, evidence } = data; const signalLabels = evidence.signals.map((signal) => signal.label);
// High-value transactions from risky IPs require additional verification if (orderValue > 500 && score.risk_score > 50) { return { action: "REQUIRE_VERIFICATION", reasons: signalLabels, score: score.risk_score, }; }
// Block transactions from extremely high-risk IPs if (score.risk_score > 85) { return { action: "BLOCK", reasons: signalLabels, score: score.risk_score, }; }
// VPN users may need additional friction if (classification.is_vpn && orderValue > 200) { return { action: "SOFT_CHALLENGE", reasons: signalLabels, score: score.risk_score, }; }
return { action: "ALLOW", score: score.risk_score };}Key Fraud Signals:
- Mismatch between billing address country and IP geolocation
- Known proxy or VPN usage during high-value purchases
- IP associated with previous chargebacks
- Multiple accounts from same high-risk IP
Email Validation and Deliverability
Section titled “Email Validation and Deliverability”Email service providers and marketers use IP reputation to validate signups and protect deliverability. Fraudulent signups from disposable email addresses often originate from anonymized connections.
Email Signup Validation:
import requests
def validate_email_signup(ip_address, email): response = requests.get(f'https://api.ipbot.com/v1/ip/{ip_address}') data = response.json()
score = data['score'] classification = data['classification'] signal_labels = [signal['label'] for signal in data['evidence']['signals']]
# Flag signups from anonymized connections if classification['is_tor'] or classification['is_proxy']: return { 'valid': False, 'reason': 'anonymous_connection', 'action': 'require_phone_verification' }
# Datacenter IPs often indicate bots if classification['is_datacenter'] and score['risk_score'] > 40: return { 'valid': False, 'reason': 'suspected_bot', 'action': 'show_captcha' }
# Known abuse signals can block signup if 'Known Abuse' in signal_labels: return { 'valid': False, 'reason': 'known_abuse', 'action': 'block_signup' }
return {'valid': True, 'risk_score': score['risk_score']}Access Control and Authentication
Section titled “Access Control and Authentication”IP reputation enhances authentication security by identifying suspicious login attempts before they succeed.
Adaptive Authentication:
async function getAuthenticationLevel(ip, userId) { const [ipData, userHistory] = await Promise.all([ fetch(`https://api.ipbot.com/v1/ip/${ip}`).then((r) => r.json()), getUserLoginHistory(userId), ]);
const { score, classification, location, evidence } = ipData; const signalLabels = evidence.signals.map((signal) => signal.label);
// New location from high-risk IP = maximum friction const isNewLocation = !userHistory.countries.includes(location.country_code);
if (isNewLocation && score.risk_score > 60) { return "MFA_REQUIRED_WITH_EMAIL_NOTIFICATION"; }
// VPN from new location = elevated friction if (isNewLocation && classification.is_vpn) { return "MFA_REQUIRED"; }
// Known abuse signals = block and notify if (signalLabels.includes("Known Abuse")) { return "BLOCK_WITH_ADMIN_ALERT"; }
// High risk score = challenge if (score.risk_score > 70) { return "CAPTCHA_REQUIRED"; }
return "STANDARD_AUTH";}API Rate Limiting and Bot Protection
Section titled “API Rate Limiting and Bot Protection”IP reputation helps distinguish legitimate API consumers from abusive bots and scrapers.
function calculateRateLimit(ipData) { const { score, classification } = ipData;
// Datacenter IPs get stricter limits if (classification.is_datacenter) { return { requestsPerMinute: 10, burstLimit: 20 }; }
// High-risk IPs get minimal access if (score.risk_score > 70) { return { requestsPerMinute: 5, burstLimit: 10 }; }
// Proxies get reduced limits if (classification.is_proxy || classification.is_vpn) { return { requestsPerMinute: 30, burstLimit: 50 }; }
// Normal residential traffic return { requestsPerMinute: 60, burstLimit: 100 };}Public Evidence Signals
Section titled “Public Evidence Signals”IPBot exposes product-level signals instead of raw feed names or internal rule IDs. Each signal has a stable label, category, severity, and confidence so your application can explain decisions without binding to IPBot’s private data pipeline.
| Signal Label | Description | Typical Impact |
|---|---|---|
VPN | Traffic appears to come through a VPN service | Medium |
Proxy | Traffic appears to come through a proxy service | Medium |
Tor Exit Node | Traffic appears to exit through the Tor network | High |
Datacenter | IP belongs to hosting or cloud infrastructure | Low to medium |
Known Abuse | IP has abuse or threat evidence | High |
Residential Proxy | Residential-looking network with proxy evidence | Medium to high |
Private Relay | Privacy relay traffic, not residential proxy | Low to medium |
Verified Crawler | Search or platform crawler verified by IPBot | Informational |
Integration Examples
Section titled “Integration Examples”# Get reputation data for any IPcurl -s https://api.ipbot.com/v1/ip/185.220.101.42 | jq '{score, classification, signals: .evidence.signals}'
# Check specific security fieldscurl -s https://api.ipbot.com/v1/ip/185.220.101.42 | jq '{ risk_score: .score.risk_score, is_vpn: .classification.is_vpn, signals: [.evidence.signals[].label]}'JavaScript / Node.js
Section titled “JavaScript / Node.js”class IPReputationClient { constructor(baseUrl = "https://api.ipbot.com") { this.baseUrl = baseUrl; this.cache = new Map(); this.cacheTTL = 3600000; // 1 hour }
async getReputation(ip) { // Check cache first const cached = this.cache.get(ip); if (cached && Date.now() - cached.timestamp < this.cacheTTL) { return cached.data; }
const response = await fetch(`${this.baseUrl}/v1/ip/${ip}`); if (!response.ok) { throw new Error(`Failed to get reputation: ${response.status}`); }
const data = await response.json();
// Cache the public reputation slice this.cache.set(ip, { data: { score: data.score, classification: data.classification, signals: data.evidence.signals, }, timestamp: Date.now(), });
return this.cache.get(ip).data; }
async isHighRisk(ip, threshold = 70) { const reputation = await this.getReputation(ip); return reputation.score.risk_score >= threshold; }
async getThreats(ip) { const reputation = await this.getReputation(ip); return { isVPN: reputation.classification.is_vpn, isProxy: reputation.classification.is_proxy, isTor: reputation.classification.is_tor, signals: reputation.signals.map((signal) => signal.label), }; }}
// Usageconst client = new IPReputationClient();
const reputation = await client.getReputation("185.220.101.42");console.log(`Risk Score: ${reputation.score.risk_score}`);console.log(`Threat Level: ${reputation.classification.threat_level}`);console.log(`Signals: ${reputation.signals.map((signal) => signal.label).join(", ")}`);Python
Section titled “Python”import requestsfrom functools import lru_cachefrom datetime import datetime, timedelta
class IPReputationClient: def __init__(self, base_url='https://api.ipbot.com'): self.base_url = base_url self._cache = {} self._cache_ttl = timedelta(hours=1)
def get_reputation(self, ip: str) -> dict: # Check cache if ip in self._cache: cached_data, cached_time = self._cache[ip] if datetime.now() - cached_time < self._cache_ttl: return cached_data
response = requests.get(f'{self.base_url}/v1/ip/{ip}') response.raise_for_status()
data = response.json() reputation = { 'score': data['score'], 'classification': data['classification'], 'signals': data['evidence']['signals'], }
# Update cache self._cache[ip] = (reputation, datetime.now())
return reputation
def is_high_risk(self, ip: str, threshold: int = 70) -> bool: reputation = self.get_reputation(ip) return reputation['score']['risk_score'] >= threshold
def get_threat_summary(self, ip: str) -> dict: reputation = self.get_reputation(ip) return { 'score': reputation['score']['risk_score'], 'level': reputation['classification']['threat_level'], 'is_anonymous': ( reputation['classification'].get('is_vpn') or reputation['classification'].get('is_proxy') or reputation['classification'].get('is_tor') ), 'signals': [signal['label'] for signal in reputation['signals']] }
# Usageclient = IPReputationClient()
# Check if IP is high riskif client.is_high_risk('185.220.101.42'): print('High risk IP detected!')
# Get detailed threat informationthreats = client.get_threat_summary('185.220.101.42')print(f"Risk Score: {threats['score']}")print(f"Anonymous: {threats['is_anonymous']}")print(f"Signals: {', '.join(threats['signals'])}")<?php
class IPReputationClient { private string $baseUrl; private array $cache = []; private int $cacheTTL = 3600;
public function __construct(string $baseUrl = 'https://api.ipbot.com') { $this->baseUrl = $baseUrl; }
public function getReputation(string $ip): array { // Check cache if (isset($this->cache[$ip])) { $cached = $this->cache[$ip]; if (time() - $cached['timestamp'] < $this->cacheTTL) { return $cached['data']; } }
$response = file_get_contents("{$this->baseUrl}/v1/ip/{$ip}"); $data = json_decode($response, true);
// Cache result $reputation = [ 'score' => $data['score'], 'classification' => $data['classification'], 'signals' => $data['evidence']['signals'] ]; $this->cache[$ip] = [ 'data' => $reputation, 'timestamp' => time() ];
return $reputation; }
public function isHighRisk(string $ip, int $threshold = 70): bool { $reputation = $this->getReputation($ip); return $reputation['score']['risk_score'] >= $threshold; }}
// Usage$client = new IPReputationClient();$reputation = $client->getReputation('185.220.101.42');
echo "Risk Score: " . $reputation['risk_score'] . "\n";echo "Action: " . $reputation['score']['recommended_action'] . "\n";Comparison: IPBot vs Competitors
Section titled “Comparison: IPBot vs Competitors”| Feature | IPBot | MaxMind minFraud | IPQS | Sift |
|---|---|---|---|---|
| Free Tier | Yes | No | Limited | No |
| API Key Required | No | Yes | Yes | Yes |
| Risk Score | 0-100 | 0-99 | 0-100 | 0-100 |
| Explainable Reasons | Yes | Limited | Yes | Limited |
| VPN Detection | Included | Separate product | Included | Included |
| Tor Detection | Included | Separate product | Included | Included |
| Abuse Signals | Yes | Yes | Yes | Yes |
| CORS Enabled | Yes | No | Yes | No |
| Response Time | Under 50ms | Under 100ms | Under 100ms | Under 150ms |
| Pricing | Free tier available | From $50/mo | From $99/mo | Custom |
Best Practices
Section titled “Best Practices”1. Use Risk Thresholds Appropriately
Section titled “1. Use Risk Thresholds Appropriately”Different actions require different thresholds:
const THRESHOLDS = { BLOCK: 85, // Very high confidence of malicious REQUIRE_MFA: 60, // Elevated risk, verify identity SHOW_CAPTCHA: 40, // Moderate risk, prove human LOG_ONLY: 20, // Low risk, just monitor};2. Combine with Other Signals
Section titled “2. Combine with Other Signals”IP reputation is one component of a comprehensive fraud detection system:
function calculateOverallRisk(ipData, userBehavior, deviceFingerprint) { const ipRisk = ipData.score.risk_score * 0.3; const behaviorRisk = userBehavior.anomalyScore * 0.4; const deviceRisk = deviceFingerprint.riskScore * 0.3;
return ipRisk + behaviorRisk + deviceRisk;}3. Handle VPNs Thoughtfully
Section titled “3. Handle VPNs Thoughtfully”Not all VPN users are malicious. Consider context:
function assessVPNRisk(ipData, context) { if (!ipData.classification.is_vpn) return "low";
// Privacy-conscious users in sensitive contexts if (context.isPrivacySensitive) return "acceptable";
// High-value transactions from VPNs need verification if (context.transactionValue > 1000) return "high";
// Account creation from VPN is suspicious if (context.isNewAccount) return "elevated";
return "moderate";}4. Cache Appropriately
Section titled “4. Cache Appropriately”IP reputation changes slowly. Cache for at least 1 hour:
// Recommended cache TTLsconst CACHE_TTL = { HIGH_RISK: 1800000, // 30 minutes for high-risk IPs MEDIUM_RISK: 3600000, // 1 hour for medium-risk LOW_RISK: 86400000, // 24 hours for low-risk};Frequently Asked Questions
Section titled “Frequently Asked Questions”What is the difference between IP reputation and IP geolocation?
Section titled “What is the difference between IP reputation and IP geolocation?”IP geolocation determines the physical location of an IP address (country, city, coordinates). IP reputation assesses the trustworthiness of an IP based on its history and characteristics. Both are useful for different purposes - geolocation for localization and compliance, reputation for security and fraud prevention.
How often is reputation data updated?
Section titled “How often is reputation data updated?”IPBot refreshes its intelligence stack on a regular operations cadence and calculates public risk scores at request time from the latest loaded data.
Can IP reputation be spoofed?
Section titled “Can IP reputation be spoofed?”The IP address itself cannot be spoofed in a TCP connection due to the three-way handshake. However, attackers can use previously unknown IPs or rotate through IP addresses. This is why IP reputation should be one component of a multi-layered security approach.
Should I block all VPN traffic?
Section titled “Should I block all VPN traffic?”Not necessarily. Many legitimate users use VPNs for privacy, especially in countries with internet restrictions. Instead of blanket blocking, consider requiring additional verification for high-risk actions from VPN IPs.
How do I handle false positives?
Section titled “How do I handle false positives?”Build an appeals process and monitor your block rates. If legitimate users are frequently flagged, adjust your thresholds or add exceptions for specific use cases. Use risk scoring as one input rather than the sole decision factor.
Get Started
Section titled “Get Started”Start using IP reputation scoring in your application:
# Quick testcurl https://api.ipbot.com/v1/ip/185.220.101.42 | jq '{score, classification, signals: .evidence.signals}'Resources:
- API Reference - Complete endpoint documentation
- Rate Limits - Caching and usage guidelines
- Code Examples - Integration samples in multiple languages
- Proxy Detection - Deep dive into VPN/proxy detection