Making requests

Classify a single IP address as VPN, proxy, Tor exit, hosting / CDN, or residential / mobile proxy.

API endpoint

GET https://vpn-proxy-detection.whoisxmlapi.com/api/v1/ip/185.220.101.1?apiKey=YOUR_API_KEY
It takes up to a minute to activate your account after the registration.

Postman collection

Postman is a desktop and web application that allows you to make requests to an API from a graphical user interface. We recommend using Postman with WhoisXML APIs endpoints when exploring the APIs functionality, as well as when you are troubleshooting issues with your application.

The WhoisXML API Postman collection is available at the following links:

The collection includes a preconfigured environment. You will need to set up the api_key variable to fire each request. Get your personal API KEY on the My products page. If you have questions related to the API, contact us.

Input parameters

apiKey

Required. Get your personal API key on the My products page.

ipAddress

Required. The IPv4 address to classify. Specified as a path segment of the request URL, e.g. /api/v1/ip/185.220.101.1.

Sample output

{
    "ip": "185.220.101.1",
    "network": "185.220.101.0\/24",
    "classification": "tor",
    "provider": null,
    "confidence": 1.0,
    "source": "port_scan",
    "detection_method": "port_scan",
    "first_seen": "2024-01-15T08:30:00Z",
    "last_seen": "2026-06-08T08:59:09Z",
    "observation_count": 127,
    "hits_days_pct": 47.78,
    "providers_num": 0,
    "confidence_decay": 0.6650,
    "freshness_class": "current",
    "is_vpn": false,
    "is_proxy": false,
    "is_tor": true,
    "is_relay": false,
    "is_hosting": false,
    "is_cdn": false,
    "is_residential_proxy": false,
    "is_residential_proxy_high_confidence": false,
    "is_residential_proxy_mobile": false,
    "is_open_proxy": false,
    "is_corporate_vpn": false,
    "risk_score": 100,
    "asn": 60729,
    "asn_org": "TORSERVERS-NET - Stiftung Erneuerbare Freiheit, DE",
    "cdn_operator": null,
    "asn_abuse": {
        "abuse_score": 88,
        "abuse_level": "high",
        "flagged_ratio": 0.62,
        "flagged_ip_count": 1240,
        "total_announced_ips": 2000
    },
    "metadata": {
        "raw_score": 100,
        "signals": { "open_ports": [9001, 9030] },
        "dns_enrichment": null,
        "tls_enrichment": null
    },
    "observed_location": null
}

Code: 200 OK.

Output parameters

ip

The queried IPv4 address, echoed back.

network

String or null. The CIDR range the IP belongs to, when known.

classification

String. The detection type of the IP.

Allowed values: vpn, corporate_vpn, proxy, hosting, cdn, tor, relay, residential_proxy, residential_proxy_likely, residential_proxy_mobile, datacenter_proxy, mobile_proxy, suspected_vpn, suspected_proxy, unknown.

provider

String or null. Attributed provider for the IP (e.g. a VPN brand, residential proxy network, hosting company). Null when no attribution is available.

confidence

Float in [0, 1]. Calibrated confidence in the classification. Higher values indicate stronger evidence.

source

String. The detection method that produced the record (e.g. mslm, port_scan, proxy_enum, netflow_analysis, asn_classification).

detection_method

String. Same as source (legacy field, retained for backward compatibility).

first_seen

String (ISO-8601) or null. When the IP was first observed.

last_seen

String (ISO-8601) or null. When the IP was last observed.

observation_count

Integer. Total times the IP has been observed (hits).

hits_days_pct

Float or null. Persistence: the percentage of days within the rolling 90-day observation window on which the IP was observed as an active proxy / VPN exit (distinct observation days ÷ 90 × 100).

High (>50) indicates a consistently active exit; low (<5) indicates sporadic or one-shot activity. Null when the result comes from a network-range detection with no per-IP observation history.

providers_num

Integer. Number of distinct proxy / VPN networks through which the IP was observed as an exit. A value of 2 or more means the IP is shared or resold across multiple commercial networks — a strong proxy signal. 0 means no per-IP enumeration history (range-level detection only).

confidence_decay

Float in [0, 1.5]. Composite evidence-strength score: recency factor × consistency × multi-provider boost. Values above 1.0 indicate multi-provider, daily-active IPs; 0.0 means never observed at point level. For a normalised 0–1 score use min(confidence_decay, 1.0).

freshness_class

String. Observation staleness bucket derived from last_seen, so you can filter without date math.

Allowed values: current (observed in the last day), recent (last week), stale (last 90 days), frozen (>90 days ago, or never observed).

is_vpn

Boolean. True if the classification is in {vpn, vpn_concentrator, corporate_vpn, commercial_vpn, vpn_hosting} (confirmed VPN endpoints). Does not include tor, relay, suspected_vpn, or vpn_suspecttor/relay have dedicated booleans; suspected_vpn/vpn_suspect are corroboration-only signals that do not set is_vpn. This asymmetry with is_proxy is deliberate: suspected_proxy does set is_proxy, but suspected_vpn/vpn_suspect never set is_vpn.

is_proxy

Boolean. True if the classification is in {proxy, datacenter_proxy, mobile_proxy, suspected_proxy}. Does not include residential proxies (see is_residential_proxy). To match any proxy of any kind, combine is_proxy OR is_residential_proxy.

is_tor

Boolean. True if the IP is a Tor exit node (classification tor).

is_relay

Boolean. True if the classification is relay — a privacy-preserving relay service (e.g. Apple Private Relay). Distinct from is_vpn: relays route consumer traffic through provider-operated egress with no user-selectable endpoint.

is_hosting

Boolean. True if the IP belongs to a datacenter / hosting provider.

is_cdn

Boolean. True if the IP belongs to a content-delivery network.

is_residential_proxy

Boolean. True if the classification is in {residential_proxy, residential_proxy_likely, residential_proxy_mobile}. Mutually exclusive with is_proxy; use the more specific booleans below to filter further.

is_residential_proxy_high_confidence

Boolean. True if classification == residential_proxy (the ≥85% precision tier). Subset of is_residential_proxy.

is_residential_proxy_mobile

Boolean. True if classification == residential_proxy_mobile — mobile carrier IPs detected as proxy. Subset of is_residential_proxy.

is_open_proxy

Boolean. True when the IP appears on a public open-proxy list. Distinct from is_proxy: every open proxy is also a proxy, but most proxies are not on public lists.

is_corporate_vpn

Boolean. True if the IP is an appliance-class VPN (Fortinet, Pulse Secure, Cisco AnyConnect, …). Sub-flag of is_vpn.

risk_score

Integer in [0, 100]. Computed as confidence × 100, with a +10 boost for high-risk classification types.

asn

Integer or null. Autonomous System number announcing the IP.

asn_org

String or null. Registered organisation name for the ASN.

cdn_operator

String or null. Normalised CDN operator brand (lowercase), e.g. akamai, fastly, cloudflare, aws_cloudfront. Non-null only when classification == cdn.

asn_abuse

Object or null. ASN-level abuse scoring. Available on all tiers; premium tiers (growth+) get the full breakdown:

abuse_score — integer 0–100, abuse level for this ASN (all tiers).

abuse_level — string: low, moderate, high, critical (all tiers).

flagged_ratio — float 0.0–1.0, ratio of flagged IPs in the ASN (growth+).

flagged_ip_count — integer, count of flagged IPs (growth+).

total_announced_ips — integer, total IPs announced by this ASN (growth+).

metadata

Object. Additional detection signals and enrichment data (all keys optional):

raw_score — number, the internal numeric confidence (0–100).

signals — object, detection signals (port patterns, protocols, etc.).

dns_enrichment — object, DNS PTR records and RDNS history.

tls_enrichment — object, TLS certificate analysis.

observed_location

Object or null. Geographic data, premium tiers (growth+) only; null when no observed-location data is available. Keys:

exit_country — string or null, ISO 3166-1 alpha-2 country code of the exit IP.

user_countries — array of strings or null, countries where users of this IP were observed.

user_country_count — integer or null, count of distinct user countries.

observed_lat / observed_lon — number or null, coordinates of the observed exit point.

observed_countries — array of strings, countries where this concentrator was observed.

observation_readings — string or null, metadata about the observations.

Free access

After Sign Up you automatically get a free subscription plan limited to 10 queries.

Rate limits

API requests are rate-limited per API key over a 60-second sliding window. The limit depends on your subscription plan:

Free

2 requests/min

Starter

30 requests/min

Pro

100 requests/min

Scale

250 requests/min

Business

500 requests/min

Enterprise

Custom — contact us.


Monthly query credits are separate and shown on the pricing page.

If you exceed your limit, the API returns HTTP 429 with the standard error envelope and the Retry-After / X-RateLimit-Reset headers — wait Retry-After seconds before retrying.

{"error": {"code": "rate_limited", ...}}

This API is also available with a dedicated load balancer and premium endpoint to enable faster querying as part of our Premium API Services and Enterprise API Packages.