AffGuard
...
shield
AffGuard
Sign In
Developer Documentation

API Documentation

Integrate enterprise-grade IP intelligence into your applications with our powerful REST API.

rocket_launch Quick Start
1
Get API Key

Generate your API key from the dashboard

2
Make Request

Send HTTP requests to our endpoints

3
Get Results

Receive JSON response with threat data

key Authentication

All API requests require authentication using your API key. Include it in the request header:

X-API-KEY: YOUR_API_KEY
warning
Security Note: Never expose your API key in client-side code or public repositories. Keep it secure on your server.
language Base URL
https://affguard.ai/api/v1

electrical_services API Endpoints

IP Lookup GET

Analyze an IP address for VPN, proxy, Tor, and datacenter detection.

bolt
< 20ms
Cache HIT response
Known IP, instant return
database
50–120ms
DB lookup response
IP in database, not yet cached
smart_toy
800ms–1.5s
AI Engine (if enabled)
Live heuristic scan on new IP
info
Latency tiers explained

Cache HIT (<20ms) applies to previously-seen IPs served from Redis. DB lookup (50–120ms) runs a range query against the intelligence database. AI Engine adds ~800ms–1.5s only when enabled on your key and the IP is brand new to our system.

Endpoint
GET /api/v1/ip/lookup?ip={ip}
Parameters
Parameter Type Required Description
ip string Yes IPv4 or IPv6 address to analyze
Example Request
curl -X GET "https://affguard.ai/api/v1/ip/lookup?ip=8.8.8.8" \
     -H "X-API-KEY: YOUR_API_KEY"
Example Response
{
    "ip": "8.8.8.8",
    "country": "US",
    "is_vpn": "no",
    "is_proxy": "no",
    "is_tor": "no",
    "is_bot": "no",
    "is_hosting": "yes",
    "is_blacklist": "no",
    "is_residential": "no",
    "risk_score": 40,
    "fraud_score": 30,
    "confidence": 80,
    "threat_categories": ["datacenter_hosting"],
    "subnet_risk": 12.50,
    "is_abusive": "no",
    "abuse_reports": 0,
    "is_market_research_flagged": "no",
    "market_research_reports": 0
}
Response Field Dictionary
Field Format Description
ip string The IP address queried in the request.
country string Two-letter ISO 3166-1 country code (e.g., "US", "GB").
is_vpn yes/no Returns "yes" if identified as a Virtual Private Network.
is_proxy yes/no Returns "yes" if identified as a non-anonymous or commercial proxy.
is_tor yes/no Returns "yes" if identified as an active Tor Exit Node.
is_bot yes/no Returns "yes" if the IP belongs to a known crawler or bot.
is_hosting yes/no Returns "yes" if the IP is from a cloud provider or data center.
is_blacklist yes/no Returns "yes" if the IP is found on global threat/spam blacklists.
risk_score int (0–100) Technical risk score based on the connection nature.
fraud_score int (0–100) Behavioral risk score based on historical abuse.
confidence int (0–100) | null Data confidence score. Higher values indicate more trusted provider sources. Returns null when no provider data is available.
threat_categories array Classified threat labels for this IP, ordered by severity. Possible values: tor_exit_node, vpn, proxy, datacenter_hosting, bot, blacklisted, cpa_fraud, survey_fraud, geo_asn_mismatch, dns_inconsistency, contaminated_subnet, residential. Returns an empty array when no threats are detected.
subnet_risk float (0–100) | null Percentage of flagged IPs within the same /24 subnet. Higher values indicate a contaminated network neighbourhood. Returns null for IPv6 addresses.
is_residential yes/no Returns "yes" if identified as a residential proxy or ISP connection. Residential IPs receive a lower risk score.
is_abusive yes/no Returns "yes" if flagged for advertising/CPA fraud behavior.
abuse_reports int Number of unique CPA fraud reports associated with this IP.
is_market_research_flagged yes/no Returns "yes" if flagged for survey/panel market research fraud (fake traffic, incentivized clicks).
market_research_reports int Number of unique market research fraud reports associated with this IP.
timeline Behavioral Session Analysis Optional Add-on
GET / POST

Pass optional user/session/device parameters on the same IP Lookup call to detect multi-IP rotation, multi-accounting, device farms, and coordinated fraud that pure IP intelligence cannot catch on its own. All parameters are optional — when omitted, the response is identical to a standard IP lookup (fully backwards compatible).

warning
Real-world fraud pattern this catches:
A cluster of sessions where device details are identical across multiple sessions, but the IP address changes every 15 minutes. Each session fires paid conversions across all available offers before the IP rotates. Pure IP intelligence returns clean residential scores for each individual IP — only behavioural correlation catches the cluster.
Additional Optional Parameters
Parameter Type Required Description
user_id string No Your internal user identifier (any opaque string, max 128 chars). Hashed server-side — never stored in plaintext.
session_id string No Your internal session identifier (any opaque string, max 128 chars). Hashed server-side.
device_fingerprint string No — Recommended Any opaque string that uniquely identifies a device on your platform (max 256 chars). You choose the logic — it can be any hash you compute that stays consistent for a given device across sessions (e.g., from FingerprintJS, ThumbmarkJS, or your own client-side logic). The more unique-per-device it is, the better the detection. Hashed server-side.
ua string No The end-user's browser User-Agent string. Used as a fallback when device_fingerprint is not provided. Low specificity on its own — see warning below.
info
Why device_fingerprint is strongly recommended over ua alone:
A User-Agent string is not unique. Two people using the same iPhone model, iOS version, and browser will produce identical UA strings — and millions of devices do. Flagging on raw UA alone would generate massive false positives. When only ua is provided, thresholds are raised significantly (15+ users vs 5) and signals only fire when corroborated by another behavioural signal. Each signal returns a confidence level so you know how much weight to put on it.
Example Request (with behavioral params)
curl -G "https://affguard.ai/api/v1/ip/lookup" \
     -H "X-API-KEY: YOUR_API_KEY" \
     --data-urlencode "ip=203.0.113.45" \
     --data-urlencode "user_id=user_12345" \
     --data-urlencode "session_id=sess_abc" \
     --data-urlencode "device_fingerprint=YOUR_DEVICE_HASH" \
     --data-urlencode "ua=Mozilla/5.0 (iPhone; CPU iPhone OS 17_0)"
Example Response (with behavior block)
{
    "ip": "203.0.113.45",
    "country": "US",
    "is_vpn": "no",
    "is_residential": "yes",
    "risk_score": 18,
    "fraud_score": 62,
    ...
    "behavior": {
        "session_risk": 86,
        "fingerprint_quality": "strong",
        "ip_rotation": {
            "detected": true,
            "rotation_count": 4,
            "unique_ips": 4,
            "rotation_interval_seconds": 902,
            "rotation_interval_label": "~15 min",
            "rotation_consistency": "high",
            "first_rotation_at": "2026-05-11T13:00:14Z",
            "last_rotation_at": "2026-05-11T13:45:20Z"
        },
        "shared_ip": {
            "detected": false,
            "unique_users_60min": 1,
            "unique_sessions_60min": 1,
            "window_seconds": 3600
        },
        "unique_users_on_device": 1,
        "unique_devices_on_user": 1,
        "first_seen_session": "2026-05-11T13:00:14Z",
        "signals": [
            { "type": "ip_rotation_detected", "confidence": "high" }
        ]
    }
}
Behavioral Response Fields
Field Format Description
behavior.session_risk int (0–100) Composite behavioural risk score. Also added (weighted) into the top-level fraud_score automatically.
behavior.fingerprint_quality string "strong" — customer provided device_fingerprint. "weak" — only ua available; higher thresholds apply. "none" — no device data sent.
behavior.ip_rotation.detected boolean True when consistent IP rotation is detected (3+ IPs, 1 min – 2 hr cadence, with false-positive guards for DHCP/mobile).
behavior.ip_rotation.rotation_interval_label string Human-readable median rotation cadence: "~1 min", "~5 min", "~15 min", "~30 min", "~1 hour", "~2 hours".
behavior.ip_rotation.rotation_consistency string "high" — suspiciously regular cadence (likely automated). "medium" — semi-regular. "low" — irregular (likely organic).
behavior.shared_ip.detected boolean True when the same IP served 5+ distinct users or 8+ distinct sessions within the last 60 minutes — indicates a shared proxy or click farm exit.
behavior.signals[] array Fired behavioural signals. Each entry has type and confidence ("high", "medium", "low"). Empty array when no signals fire.
Signal Reference
Signal Triggers When Recommended Action
ip_rotation_detected 3+ distinct IPs for the same session/user with consistent cadence (1 min–2 hr), passes DHCP/mobile false-positive guards Flag or block when confidence is "high"; review when "medium"
shared_ip_burst Same IP used by 5+ distinct users or 8+ distinct sessions in 60 min Block conversion or require additional verification
device_shared_across_users Same device fingerprint linked to 5+ distinct users in 24h (strong fp) or 15+ users (weak fp + corroboration) Block when confidence is "high"; rely only on corroborated weak-fp signals
velocity_attack Same user_id triggers 10+ API lookups in 60 seconds Rate-limit or block the user_id immediately
stale_fingerprint_on_new_ip Strong device fingerprint seen on 5+ different IPs in 24h High-confidence proxy reuse — flag or block
cross_customer_flagged_device Device fingerprint was flagged by another AffGuard customer in the last 7 days (strong fingerprint only) Treat as high-risk; block conversion
geo_jump Same session_id appears in a different country within 2 minutes Impossible travel — block or invalidate session
Code Examples
<?php
$apiKey            = 'YOUR_API_KEY';
$userId            = $loggedInUserId;          // your internal user identifier
$sessionId         = session_id();             // your session token
$deviceFingerprint = $myDeviceHash;            // any string unique to this device
$userAgent         = $_SERVER['HTTP_USER_AGENT'];

$query = http_build_query([
    'ip'                 => $_SERVER['REMOTE_ADDR'],
    'user_id'            => $userId,
    'session_id'         => $sessionId,
    'device_fingerprint' => $deviceFingerprint,
    'ua'                 => $userAgent,
]);
$response = file_get_contents("https://affguard.ai/api/v1/ip/lookup?{$query}", false, stream_context_create([
    'http' => ['header' => "X-API-KEY: {$apiKey}"]
]));
$data = json_decode($response, true);

$behavior = $data['behavior'] ?? null;
if ($behavior) {
    foreach ($behavior['signals'] as $signal) {
        if ($signal['type'] === 'ip_rotation_detected' && $signal['confidence'] === 'high') {
            http_response_code(403);
            exit('Suspicious activity detected. Conversion blocked.');
        }
    }
    if ($behavior['session_risk'] >= 70) {
        http_response_code(403);
        exit('High session risk. Conversion blocked.');
    }
}
lock
Privacy: All identifiers (user_id, session_id, device_fingerprint, ua) are HMAC-hashed on receipt and never stored in plaintext. AffGuard cannot reverse the hash to identify your users. Hashed signals are retained for 30 days for behavioural analysis and then permanently deleted.
mark_email_read Email Validation
GET Free — No Quota

Validate an email address for deliverability, disposable detection, DNS/MX verification, and SMTP probing. This endpoint is free — it uses your existing API key but does not count against your plan quota.

speed
Rate Limits (per API key): 60 req/min · 1,000 req/hour · 10,000 req/day. Rate limit headers are included in every response: X-Email-RateLimit-Remaining-Minute, X-Email-RateLimit-Remaining-Hour, X-Email-RateLimit-Remaining-Daily.
Endpoint
GET /api/v1/email/{email}
ParameterTypeLocationDescription
email string URL path The email address to validate. URL-encode if needed (e.g., user%40example.com).
Example Request
curl -X GET "https://affguard.ai/api/v1/email/user%40gmail.com" \
     -H "X-API-KEY: YOUR_API_KEY"
Example Response
{
  "email": "[email protected]",
  "status": "valid",
  "is_disposable": false,
  "confidence_score": 95,
  "smtp": "unverifiable",
  "is_catch_all": null,
  "has_typo_suggestion": false,
  "did_you_mean": null,
  "is_role_address": false,
  "mx_host": "gmail-smtp-in.l.google.com",
  "domain_age_days": null,
  "has_web_presence": true,
  "heuristic_score": 0
}
Response Fields
FieldTypeDescription
emailstringThe email address that was validated
statusstringvalid | invalid | unknown
is_disposableboolTrue if confirmed disposable/temporary email provider
confidence_scoreint (0–100)Overall deliverability confidence. Higher is better.
smtp string valid — mailbox confirmed via SMTP
invalid — mailbox rejected by server
catch_all — server accepts all addresses
greylisted — temporarily deferred
unverifiable — provider blocks SMTP probing (Gmail, Outlook, Yahoo, iCloud, etc.)
unavailable — no MX records found
rate_limited — probing throttled for this domain
not_applicable — email already confirmed disposable
error — connection or protocol failure
is_catch_allboolTrue if the domain accepts mail for any address
has_typo_suggestionboolTrue if the domain looks like a common provider typo
did_you_meanstring|nullSuggested corrected domain (e.g., gmail.com), or null
is_role_addressboolTrue if the local part is a role address (e.g., info@, support@)
mx_hoststring|nullPrimary MX hostname for the domain
domain_age_daysint|nullDomain age in days from RDAP registration data. Returns null for major known providers (Gmail, Outlook, Yahoo, etc.) where age is irrelevant.
has_web_presenceboolTrue if the domain resolves to a website
heuristic_scoreint (0–100)Internal heuristic risk score. Higher values indicate more disposable-like signals.
Rate Limit Headers
HeaderDescription
X-Email-RateLimit-MinuteMax requests per minute (60)
X-Email-RateLimit-Remaining-MinuteRequests remaining in current minute
X-Email-RateLimit-HourMax requests per hour (1,000)
X-Email-RateLimit-Remaining-HourRequests remaining in current hour
X-Email-RateLimit-DayMax requests per day (10,000)
X-Email-RateLimit-Remaining-DailyRequests remaining today
coronavirus GPT & Offerwall Integration

When a user attempts to open an offer from your Ad Network or Offerwall partners, check their IP first. If the risk_score is above 40, we recommend blocking the redirect to protect your advertiser reputation.

// Example Logic
if ($data['risk_score'] > 40) {
    die("VPN/Proxy detected. Please disable it to continue to offers.");
}
category Threat Categories

The threat_categories field returns a structured array of detected threat types, ordered by severity. Use these labels to build routing rules, auto-block policies, or dashboard visualizations.

Category Trigger Description
tor_exit_node is_tor = yes Active Tor exit node, anonymized traffic
vpn is_vpn = yes Commercial or personal VPN service
proxy is_proxy = yes HTTP/SOCKS proxy detected
datacenter_hosting is_hosting = yes Cloud provider or data center IP
bot is_bot = yes Known crawler or automated bot
blacklisted is_blacklist = yes Found on global threat or spam blacklists
cpa_fraud is_abusive = yes Flagged for CPA or advertising fraud
survey_fraud is_market_research_flagged = yes Flagged for survey or panel fraud
geo_asn_mismatch Network anomaly detected IP geolocation does not match ASN registration country
dns_inconsistency Network anomaly detected PTR hostname does not resolve back to the original IP
contaminated_subnet subnet_risk ≥ 20% High concentration of flagged IPs in the /24 network block
residential is_residential = yes, no threats Clean residential ISP connection (informational only)
info
Tip: An IP can have multiple categories at once (e.g., ["vpn", "blacklisted", "cpa_fraud"]). An empty array [] means no threat signals were detected.
shield Understanding Scores

Our IP Intelligence system provides multiple scoring dimensions to help you make informed security decisions.

Risk Score

Technical threat level based on VPN, Proxy, Tor, and hosting indicators. 0-100

Fraud Score

Behavioral risk combining historical abuse, provider data, and recency. 0-100

Confidence

How much we trust the data, based on provider quality. 0-100 or null

Subnet Risk

Percentage of flagged IPs in the same /24 network block. 0-100

Score Interpretation Guide
Range Level Recommended Action
0–25 Low Safe for most transactions. High confidence in residential origin.
26–55 Medium Moderate risk. Recommended: Extra verification (e.g., OTP or Email confirmation).
56–85 High Significant risk. High probability of VPN/Proxy abuse. Recommended: Manual review.
86–100 Critical Extreme fraud risk. Blacklisted or multi-flagged IP. Recommended: Immediate rejection.
info Response Codes
Code Status Description
200 OK Request successful
422 Unprocessable Invalid IP address, private/reserved range, or malformed email
401 Unauthorized Invalid or missing API key
402 Payment Required Insufficient balance
429 Too Many Requests Rate limit exceeded
500 Server Error Internal server error
speed Rate Limits

Rate limits vary by plan tier:

Free
10/min
Starter
60/min
Pro
300/min
Enterprise
1000/min
code Code Examples
<?php
$apiKey = 'YOUR_API_KEY';
$ip     = '8.8.8.8';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://affguard.ai/api/v1/ip/lookup?ip=" . urlencode($ip));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["X-API-KEY: $apiKey"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
$data     = json_decode($response, true);

echo "Risk Score: " . $data['risk_score'];
?>
import requests

api_key = 'YOUR_API_KEY'
ip      = '8.8.8.8'

headers  = {'X-API-KEY': api_key}
response = requests.get('https://affguard.ai/api/v1/ip/lookup', params={'ip': ip}, headers=headers)

data = response.json()
print(f"Risk Score: {data['risk_score']}")
const apiKey = 'YOUR_API_KEY';
const ip     = '8.8.8.8';

fetch(`https://affguard.ai/api/v1/ip/lookup?ip=${encodeURIComponent(ip)}`, {
    headers: { 'X-API-KEY': apiKey }
})
.then(r => r.json())
.then(data => console.log('Risk Score:', data.risk_score));
curl -X GET "https://affguard.ai/api/v1/ip/lookup?ip=8.8.8.8" \
     -H "X-API-KEY: YOUR_API_KEY"
headset_mic

Need Help?

Our support team is here to assist you with integration and technical questions.

mail Contact Support