Real-Time VPN and Proxy Detection


Overview

Detect VPNs, proxies and residential proxies live in the browser, at the moment a user acts. See what the service does and try it on the Real-Time VPN and Proxy Detection product page.


Setup

The script carries no API key. Requests are authorized by origin, so register your domain before your first call.

  1. Sign up for your IPGeolocation account.
  2. Add your origin as a Request Origin, for example https://app.example.com .
  3. Save.

Quick start

<script src="https://static.ipgeolocation.io/web-assets/static/security/session-analysis.js"></script>

<script>
    const includeIPSecurity = false;

    Analysis
        .startMonitoring(includeIPSecurity)
        .get()
        .then(result => console.log(result))
        .catch(error => console.error(error instanceof Error ? error.message : String(error)));
</script>

Response for a clean connection:

Response Preview
1{
2  "public_ip": "119.156.x.x",
3  "public_ip_country_code": "PK",
4  "live_vpn_proxy_detection": {
5    "is_anonymous": false,
6    "confidence_score": 100,
7    "proxy_score": 0,
8    "vpn_score": 0
9  },
10  "visitor_actual_location": {
11    "actual_ip": "119.156.x.x",
12    "actual_country_code": "PK",
13    "confidence_score": 100
14  }
15}

In plain words: this connection is not anonymized, the service is certain about it, and the visitor is where the request says they are.


Response fields


1. The IP address the request comes from

Two top-level fields, describing the IP address the user appears to be on:

FieldTypeMeaning
public_ip stringThe IP address your server sees on the request. Behind a VPN or proxy this is the exit node's IP address, not the user's.
public_ip_country_code stringTwo-letter ISO country code for that IP address. Behind a VPN or proxy, this is the exit node's country, not the user's.

2. The live verdict: live_vpn_proxy_detection

Four fields, meant to be read together:

FieldTypeMeaning
is_anonymous booleanThe headline answer. true means the connection is anonymized through a VPN or a proxy. It does not say which; the two scores below do.
confidence_score up to 100How much to trust that yes or no. 100 with is_anonymous: false means confidently clean; a low value is weak evidence either way.
proxy_score 0 to 100Looks like a proxy, including residential and rotating proxies.
vpn_score 0 to 100Looks like a VPN.

3. Where the visitor really is: visitor_actual_location

Where the user actually is, recovered by the live tests:

FieldTypeMeaning
actual_ip stringThe visitor's real IP address behind the VPN or proxy. Falls back to public_ip when nothing is hidden, or when the real IP cannot be detected.
actual_country_code stringTwo-letter ISO country code of the visitor's actual location.
confidence_score up to 100Certainty about that actual country. Gate on it before acting on a country mismatch.

4. What is already known about the IP: ip_security

Present only when includeIPSecurity is true . Every field is documented in the IP Security API response reference.

Response Preview
1{
2  "public_ip": "94.237.x.x",
3  "public_ip_country_code": "DE",
4  "live_vpn_proxy_detection": {
5    "is_anonymous": true,
6    "confidence_score": 90,
7    "proxy_score": 90,
8    "vpn_score": 10
9  },
10  "visitor_actual_location": {
11    "actual_ip": "119.156.x.x",
12    "actual_country_code": "PK",
13    "confidence_score": 80
14  },
15  "ip_security": {
16    "threat_score": 50,
17    "is_tor": false,
18    "is_proxy": true,
19    "proxy_provider_names": [],
20    "proxy_confidence_score": 99,
21    "proxy_last_seen": "",
22    "is_residential_proxy": false,
23    "is_vpn": true,
24    "vpn_provider_names": ["Browsec VPN"],
25    "vpn_confidence_score": 99,
26    "vpn_last_seen": "2026-08-07",
27    "is_relay": false,
28    "relay_provider_name": "",
29    "is_anonymous": false,
30    "is_known_attacker": false,
31    "is_bot": false,
32    "is_spam": false,
33    "is_cloud_provider": true,
34    "cloud_provider_name": "UpCloud Ltd"
35  }
36}

Reading it in code:

const liveDetection  = result.live_vpn_proxy_detection;
const actualLocation = result.visitor_actual_location;
const ipSecurity     = result.ip_security;

liveDetection.confidence_score;                                        // 90
actualLocation.actual_country_code;                                    // "PK"
actualLocation.actual_country_code !== result.public_ip_country_code;  // true: presenting DE, actually in PK
ipSecurity.vpn_provider_names;                                         // ["Browsec VPN"]
ipSecurity.threat_score;                                               // 50

Acting on the verdict

When is_anonymous is true , confidence_score decides how much friction the session deserves. Blocking everything the service flags costs real customers; ignoring the flag defeats the check. Work in bands, and tune the cutoffs against your own confirmed fraud outcomes:

confidence_scoreWhat it meansRecommended action
Below 30Very weak signal. Expect false positives.Allow. Log the result, add nothing to the user's path.
30 to 50Uncertain. Could be an unusual network, a mobile carrier, or a corporate gateway.Allow and monitor. Feed it into your wider risk score; add friction only if another signal agrees.
51 to 80Likely anonymized. Enough for friction, not for a hard denial alone.Challenge. MFA, email or SMS verification, or a CAPTCHA. Hold payouts and first orders for review.
81 and aboveConfidently anonymized.Block or restrict. High proxy_score : block or hold for review. High vpn_score : prefer a hard challenge, since many ordinary people browse through VPNs.

These bands apply only when is_anonymous is true . High confidence with is_anonymous: false is a clean visitor, not a risky one.


Credits

ConfigurationCredits per call
includeIPSecurity: false 3
includeIPSecurity: true 5

FAQs

No. Authorization is by Request Origin: register your domain once and requests from it and its subdomains authenticate automatically. No secret ships to the browser.
No, the script is browser-only. For backend, mobile, or bulk checks, use the IP Security API, which returns only the reputation data through a key-authenticated API call.
Usually 1 to 5 seconds, because live network tests run against the connection rather than a single database lookup. Start monitoring on page load so the wait is over before the user reaches your decision point.
Yes. visitor_actual_location returns the actual_ip and actual_country_code recovered by the live tests, with its own confidence_score. Use that country for fraud and compliance rules, and gate on the confidence before acting on a mismatch.
Yes, and that is the main reason it exists. Static lists miss them because the IPs come from constantly refreshed pools of ordinary consumer ISP addresses with no listing history yet; live analysis catches the anonymization behavior itself.
ip_security.is_vpn and is_proxy come from our IP intelligence database, updated daily: they tell you an IP address is known to be associated with VPN or proxy infrastructure. The live vpn_score and proxy_score come from inspecting the current connection, so they describe this session rather than the address's history.
No. It classifies a session with live connection-level techniques only, and does not consult the IP Security database or traditional IP intelligence to reach its verdict. includeIPSecurity: true simply attaches the database view next to the live one.
A residential IP is a real household address that may also be part of a proxy network. The homeowner's own request and an anonymous request routed through the network can arrive from it seconds apart. A database can say the address is associated with residential proxy infrastructure, but not how it is being used on this connection, so acting on the association alone can affect legitimate users too.
Yes. No offline database has complete coverage: new VPN endpoints, private proxies, and rotating residential pools may not be listed yet. Real-time detection does not depend on prior knowledge of the IP address.
In our testing, classification accuracy is around 98%. In the remaining cases, confidence_score was below 35, so gating on confidence gives you an extra signal on the sessions most likely to be misread.
Both, where you can. The IP Security API gives broader IP-level context and known associations; real-time detection tells you what the connection is doing right now. Together they support better decisions without unnecessarily blocking legitimate users.
No. It measures certainty about the verdict it sits next to, in either direction: 100 with is_anonymous: false means confidently clean. Risk lives in proxy_score, vpn_score, and ip_security.threat_score.
Usually not. Many are ordinary privacy-conscious or corporate users. Work the confidence bands: log the weak signals, challenge the likely ones, and reserve blocks for high confidence backed by a second signal.
3 credits per call, or 5 with includeIPSecurity: true, from your plan's normal credit pool. It is a paid plan feature; contact our support team for a free trial.
Real-Time Proxy andVPN Detection

Looking for features, modules, and use cases? Visit the Live Proxy & VPN Detection page.

Explore Live Proxy & VPN Detection

Subscribe to Our Newsletter

Get the latest in geolocation tech, straight to your inbox.