← Back to Quick Start

Check If an IP Address is Trustworthy

Look up threat intelligence, abuse history, and risk scores for any public IP address.

What you'll learn

  • How to check an IP's reputation with a single POST request
  • How to interpret risk scores, threat categories, and abuse flags
  • What happens when you query a known Tor exit node vs. a clean IP
  • How to integrate IP checks into login and registration flows

Prerequisites

Step 1: Your first call

Check the reputation of Google's public DNS server (a known-clean IP):

curl -s -X POST /api/v1/check \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"ipAddress": "8.8.8.8"}' | python3 -m json.tool

Expected response:

{
  "ipAddress": "8.8.8.8",
  "riskScore": 0,
  "riskLevel": "LOW",
  "isTor": false,
  "isProxy": false,
  "isVpn": false,
  "isDatacenter": true,
  "isKnownAttacker": false,
  "abuseConfidenceScore": 0,
  "isp": "Google LLC",
  "country": "US",
  "threatCategories": [],
  "lastReportedAt": null,
  "processingTimeMs": 45
}

Step 2: Understanding the response

riskScore 0–100 composite score. 0 is clean, 100 is confirmed malicious.
riskLevel LOW, MEDIUM, HIGH, or CRITICAL.
isTor / isProxy / isVpn Boolean flags for anonymization services.
abuseConfidenceScore 0–100 score from abuse report databases. Higher = more reports.
threatCategories Array of tags: SPAM, BRUTE_FORCE, MALWARE, PHISHING, etc.
isDatacenter Whether the IP belongs to a cloud/hosting provider (not necessarily malicious).

Step 3: Common use cases

Known Tor exit node

curl -s -X POST /api/v1/check \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"ipAddress": "185.220.101.34"}'
{
  "ipAddress": "185.220.101.34",
  "riskScore": 85,
  "riskLevel": "HIGH",
  "isTor": true,
  "isProxy": false,
  "isVpn": false,
  "isDatacenter": true,
  "isKnownAttacker": false,
  "abuseConfidenceScore": 78,
  "isp": "Tor Exit Node",
  "country": "DE",
  "threatCategories": ["TOR_EXIT", "ANONYMIZER"],
  "lastReportedAt": "2026-03-25T14:30:00Z",
  "processingTimeMs": 52
}

GET by IP (cached lookup)

Use the GET endpoint for previously checked IPs:

curl -s /api/v1/reputation/8.8.8.8 \
  -H "X-API-Key: YOUR_API_KEY"

Private IP rejection

curl -s -X POST /api/v1/check \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"ipAddress": "192.168.1.1"}'
{
  "error": "VALIDATION_ERROR",
  "message": "ipAddress: must be a public IP address (RFC 1918 / private ranges are not accepted)",
  "status": 400
}

Step 4: Handling errors

Invalid IP format

curl -s -X POST /api/v1/check \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"ipAddress": "999.999.999.999"}'
{
  "error": "VALIDATION_ERROR",
  "message": "ipAddress: must be a valid IPv4 or IPv6 address",
  "status": 400
}

IP not found in database (GET endpoint)

The GET endpoint returns 404 if the IP has never been checked:

HTTP/1.1 404 Not Found

Use the POST /check endpoint instead to trigger a fresh lookup.

Step 5: Integration tips

Python login guard

import requests

API_BASE = ""
HEADERS = {
    "Content-Type": "application/json",
    "X-API-Key": "YOUR_API_KEY"
}

def check_ip_risk(ip_address):
    resp = requests.post(
        f"{API_BASE}/api/v1/check",
        json={"ipAddress": ip_address},
        headers=HEADERS, verify=False
    )
    resp.raise_for_status()
    data = resp.json()
    return data

def should_block_login(ip_address):
    result = check_ip_risk(ip_address)
    if result["riskScore"] >= 80:
        return True, "High-risk IP blocked"
    if result["isTor"]:
        return True, "Tor exit node blocked"
    return False, "IP accepted"

blocked, reason = should_block_login("185.220.101.34")
print(f"Blocked: {blocked}, Reason: {reason}")

Integration with web application firewalls

Use the IP reputation API as a pre-filter in your WAF pipeline. Check IPs on first request, cache the result for 1 hour, and apply rules based on riskLevel:

Next steps