Accurate VPN detection,
with evidence.
Identify IPs as VPN, residential proxy, hosting server, Tor node, CDN or relay — with all the evidence.
One API, every signal.
Get all our data in a single request. SDKs available in every major programming language and framework.
is_vpnis_hostingis_toris_cdnis_relayis_resproxyis_dcproxyis_mobproxyimport osfrom vpndetection import VPNDetectionclient = VPNDetection(os.environ["VPNDETECTION_API_KEY"])result = client.lookup("45.83.91.1")print(result.is_vpn) # Trueprint(result.vpn.provider) # 'mullvad'print(result.hosting.provider) # 'm247'
Full databases, updated daily.
Full databases available directly, doing your lookups on-premise. Shipped as downloadable CSVGZ and MMDB files.
| start_ip | end_ip | provider | confidence | last_seen |
|---|---|---|---|---|
| 216.131.87.112 | 216.131.87.127 | ipvanish | high | 2026-09-08 |
| 208.85.18.71 | 208.85.18.71 | tunnelbear | high | 2026-09-07 |
| 187.13.129.184 | 187.13.129.187 | nordvpn | high | 2026-09-07 |
| 172.235.240.0 | 172.235.240.11 | metrovpn_net | medium | 2026-09-04 |
| 95.170.13.20 | 95.170.13.23 | pingvpn_pingsecure | low | 2026-06-16 |
Flags say what. Evidence says why.
Every flag arrives with the operator behind it, how strongly it is supported, when it was last observed — and for proxy pools, how persistent the address has been.
providerconfidencelast_seenfirst_seenhitshits_days_pctproviders_num45.83.91.1
An address seen on 63% of the last 90 days is a standing pool member. One sighting on one day is noise — and you can tell them apart before you decide.
Accurate coverage, wide tracking.
All major VPN and proxy providers are covered deeply and accurately.
Pay for the depth you need.
No loose ends.
Do I need an API key to start?
Not to try it — an unauthenticated request still answers ip and is_vpn under a small daily allowance. Signing up is free and lifts you to 50,000 lookups a month.
What does a missing field mean?
Absent means unknown, never false — a field we did not answer is simply not in the response, so read it as unknown. A flag that is present always answers, and its detail object comes back empty when nothing matched.
How fresh is the data?
Every dataset publishes its own cadence and last-updated date, and all eight rebuilt today. Tor IP, for example, refreshes daily.
Can I run detection without calling the API?
Yes. With the db.download scope every licensed dataset downloads as csvgz or mmdb. The endpoint answers 302 with a time-limited link to object storage, and poll metadata first if you only want to fetch when the build changed.
Are private and reserved addresses billed?
Not through an SDK: every official client answers private, loopback, link-local, documentation and multicast ranges, including 6to4 and Teredo, without a request. Sent to the API directly, they count against a keyless or Free plan allowance and cost nothing on a paid plan.
How do I tell a rate limit from a spent allowance?
Both arrive as HTTP 429, and Retry-After is the only difference. Present means a transient rate limit, so retrying works and the SDKs retry for you. Absent means an allowance is spent — raise your overage limit or wait for the window to roll over.
Start without signing up.
Paste it into a terminal — no account needed. 1k daily allowance per user, answering ip and is_vpn.
{"ip": "45.83.91.1","is_vpn": true}