Predax Blog

Product updates, best practices, and deep dives into IP intelligence.

How to Detect VPN Users with an IP API
Predax Team

How to Detect VPN Users with an IP API

vpn-detectionapitutorialnode.jspython

Why Detect VPN Users?

VPN detection is one of the most common reasons developers reach for an IP intelligence API. The motivations vary by application, but the core problems are consistent: fraud prevention, geo-restriction enforcement, and account abuse mitigation.

Fraud prevention is the most urgent use case. When a user conceals their real location behind a VPN during checkout, you lose confidence in billing address verification. Fraudsters routinely stack a VPN with a stolen card and a fake billing address — the VPN masks the geographic mismatch that would otherwise be an obvious red flag.

Geo-restriction enforcement matters for licensing compliance. Streaming services, sports rights holders, and software vendors with territory-based pricing need to know when a user is tunnelling from a restricted region. A VPN detection signal lets you apply the correct entitlement or present the appropriate message rather than silently serving the wrong content.

Account abuse is a subtler problem. Credential stuffers and account farmers use VPNs to distribute login attempts across many exit IPs, defeating IP-based rate limiting. Detecting that a login attempt is originating from a VPN datacenter lets you apply tighter rate limits or trigger a step-up authentication challenge.

How IP APIs Detect VPNs

A good IP reputation API cross-references multiple data sources to identify VPN exit nodes:

  • BGP/ASN data — VPN providers register Autonomous System Numbers (ASNs) to announce their IP ranges. The ASN description often reveals the operator (e.g. "Mullvad VPN", "ExpressVPN", "Private Internet Access"). Reputable feeds maintain up-to-date ASN-to-provider mappings.
  • Datacenter CIDR ranges — Most commercial VPNs terminate traffic in cloud or colocation datacenters. IP ranges registered to AWS, Vultr, Hetzner, OVH, and similar providers that are not serving legitimate cloud workloads are strong VPN candidates.
  • Shared-exit behaviour — When tens of thousands of distinct sessions originate from a single /29 subnet over a short window, that subnet is almost certainly a VPN shared-exit pool. Behavioural aggregation across the API's customer base surfaces this.
  • Open-source and commercial threat feeds — Specialised databases such as ipinfo.io's privacy feed, db-ip, and IPHub publish curated VPN/proxy/datacenter lists that are updated hourly or daily.

Predax combines all of these into a single classification.is_vpn boolean and a classification.risk_score (0–100) so you don't have to manage multiple feeds yourself.

VPN detection data sources and IP intelligence workflow
VPN detection data sources and IP intelligence workflow

Making the API Call

curl

curl -s "https://predax.io/api/v1/check/ip" \
  -H "X-API-Key: prdx_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ip": "185.220.101.1"}'

A typical response:

{
  "ip": "185.220.101.1",
  "version": 4,
  "classification": {
    "risk_score": 92,
    "risk_level": "high",
    "is_vpn": true,
    "is_proxy": false,
    "is_tor": true,
    "is_datacenter": false,
    "flags": ["tor", "vpn"]
  },
  "network": {
    "asn": 4242421337,
    "as_name": "Tor exit relay"
  },
  "location": {
    "country_code": "DE",
    "country_name": "Germany"
  }
}

Node.js

async function checkIp(ip) {
  const res = await fetch('https://predax.io/api/v1/check/ip', {
    method: 'POST',
    headers: {
      'X-API-Key': process.env.PREDAX_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ ip }),
  });
  return res.json();
}

// Express middleware example
app.use(async (req, res, next) => {
  const visitorIp = req.ip;
  const result = await checkIp(visitorIp);

  if (result.classification.is_vpn && result.classification.risk_score >= 65) {
    return res.status(403).json({ error: 'VPN access is not permitted.' });
  }
  next();
});

Python

import httpx

PREDAX_KEY = "prdx_YOUR_KEY"

def check_ip(ip: str) -> dict:
    r = httpx.post(
        "https://predax.io/api/v1/check/ip",
        headers={"X-API-Key": PREDAX_KEY},
        json={"ip": ip},
        timeout=2.0,
    )
    r.raise_for_status()
    return r.json()

result = check_ip("185.220.101.1")
classification = result["classification"]
if classification["is_vpn"] and classification["risk_score"] >= 65:
    raise PermissionError("VPN access not allowed")

How to Act on the Result

The right action depends on your risk tolerance and user base:

ScenarioRecommended action
`classification.is_vpn: true` + `risk_score >= 85`Block outright (Tor/datacenter VPN, very high risk)
`classification.is_vpn: true` + `risk_score` 50–84Flag the session, trigger MFA or CAPTCHA
`classification.is_vpn: true` + `risk_score` 20–49Log and monitor; allow but tag the session
`classification.is_vpn: true` + `risk_score < 20`Likely a false positive — allow and ignore

Avoid hard-blocking all VPN users unless your use case demands it (e.g. regional licensing). A risk-score threshold of 65 is a reasonable starting point for most login-protection scenarios.

Caveats and False Positives

No VPN detection system is perfect. Residential VPN services (Windscribe, ProtonVPN on residential IPs) are harder to flag because they route traffic through genuine ISP addresses. Corporate VPNs often use office IP ranges that look like normal residential traffic.

Consider letting users whitelist their own IPs if you operate a B2B product — a developer connecting from their company VPN should not be blocked from their own dashboard. Predax supports per-account IP allowlists for exactly this reason.

Developer reviewing IP allowlist configuration in a security dashboard
Developer reviewing IP allowlist configuration in a security dashboard

Related guides

Ready to ship VPN detection in your stack? See pricing — or drop our WordPress, WooCommerce, or Shopify plugin in for one-click protection.