VPN & Proxy Detection API

Classify IP addresses as VPN, proxy, datacenter, residential, or Tor exit nodes.

Endpoints

MethodPathDescription
GET/api/v1/vpn/ip/{ip}Check a single IP
POST/api/v1/vpn/ip/batchCheck up to 100 IPs
GET/api/v1/vpn/stats/asn-abuseASN abuse leaderboard
GET/api/v1/vpn/export/asn-abuse.csvASN abuse CSV export

Try It

Example Request

bash
curl -H "X-API-Key: wxa_yourkey" https://wxaintel.wxapros.com/api/v1/vpn/ip/1.2.3.4

Example Response

json
{
  "ip": "1.2.3.4",
  "classification": "vpn",
  "provider": "NordVPN",
  "confidence": 0.92,
  "source": "proxy_enum",
  "firstSeen": null,
  "lastSeen": null,
  "observationCount": 47,
  "observed_location": {
    "exit_country": "US",
    "user_countries": ["JP", "CN", "KR", "TW", "HK"],
    "user_country_count": 85,
    "observed_lat": null,
    "observed_lon": null,
    "observed_countries": null,
    "observation_readings": null
  },
  "asn_abuse": {
    "abuse_score": 74,
    "abuse_level": "high",
    "flagged_ratio": 0.38,
    "flagged_ip_count": 12840,
    "total_announced_ips": 33792
  }
}

observed_location Field

Available on Growth tier and above. Shows where VPN users are actually located, not just where the exit node is registered.

FieldTypeDescription
exit_countrystringCountry where the VPN exit node is located (registered/routing location)
user_countriesstring[]Countries where users connecting through this VPN are located (NetFlow)
user_country_countintNumber of unique source countries
observed_latfloatGPS-observed latitude (Panavision telemetry, when available)
observed_lonfloatGPS-observed longitude (Panavision telemetry, when available)
observed_countriesstring[]Countries observed via GPS telemetry
observation_readingsintNumber of GPS sensor readings

asn_abuse Field

Included in every IP lookup response. Shows abuse metrics for the IP's ASN. The field is null when no abuse data is available for the ASN.

FieldTypeDescription
abuse_scoreintWeighted abuse score (0-100)
abuse_levelstring"clean" | "low" | "moderate" | "high" | "critical"
flagged_ratiofloatFraction of the ASN's IPs that are flagged
flagged_ip_countintNumber of flagged IPs in this ASN
total_announced_ipsintTotal IPs announced by this ASN

Abuse Score Levels

ScoreLevelMeaning
0-19cleanNormal ASN, minimal abuse indicators
20-39lowSome flagged IPs but within normal range for ASN type
40-59moderateAbove-average abuse concentration
60-79highSignificant abuse infrastructure
80-100criticalPredominantly abuse infrastructure

ASN Abuse Leaderboard

Returns top abuser ASNs ranked by abuse score.

bash
curl -H "X-API-Key: wxa_yourkey" \
  "https://wxaintel.wxapros.com/api/v1/vpn/stats/asn-abuse?min_score=40&limit=500"
ParameterDefaultDescription
min_score40Minimum abuse score to include (0-100)
limit500Maximum number of ASNs to return (1-5000)

ASN Abuse CSV Export

Download all scored ASNs as a CSV file.

bash
curl -H "X-API-Key: wxa_yourkey" \
  "https://wxaintel.wxapros.com/api/v1/vpn/export/asn-abuse.csv?min_score=0"
ParameterDefaultDescription
min_score0Minimum abuse score to include (0-100)

Classification Values

ValueMeaning
vpnCommercial VPN service
proxyHTTP/SOCKS proxy
datacenterCloud/hosting provider
residentialResidential ISP (clean)
residential_proxyResidential proxy network
torTor exit node
relayApple Private Relay / iCloud Relay
unknownNot in database

Batch Request

bash
curl -X POST -H "X-API-Key: wxa_yourkey" \
  -H "Content-Type: application/json" \
  -d '{"ips": ["1.2.3.4", "5.6.7.8"]}' \
  https://wxaintel.wxapros.com/api/v1/vpn/ip/batch

Response Codes

StatusDescription
200Success
401Missing or invalid API key
403Key doesn't have required scope
429Rate limit exceeded
502Backend service unavailable

Code Examples

python
import requests

response = requests.get(
    "https://wxaintel.wxapros.com/api/v1/vpn/ip/1.2.3.4",
    headers={"X-API-Key": "wxa_yourkey"}
)
data = response.json()
print(f"{data['ip']}: {data['classification']} ({data['confidence']:.0%})")
javascript
const response = await fetch(
  "https://wxaintel.wxapros.com/api/v1/vpn/ip/1.2.3.4",
  { headers: { "X-API-Key": "wxa_yourkey" } }
);
const data = await response.json();
console.log(`${data.ip}: ${data.classification} (${Math.round(data.confidence * 100)}%)`);