Detect VPN and proxy
Not every visitor is who their IP suggests, and telling a residential connection apart from a rented datacenter address or a Tor exit node changes how you should treat that request. This endpoint classifies the IP behind a request so you can apply different rules to different kinds of traffic without guessing.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The gap between an IP and the person using it
A commercial VPN, a proxy service or a Tor exit node all sit between a real user and the server they're talking to, which means the IP a request arrives from often has nothing to do with where that person actually is, what device they're using, or which network they normally connect from. That gap is normal and often entirely legitimate — but for signup, checkout or content decisions, simply knowing it exists changes what you should reasonably do next.
What the classification covers
The response indicates whether the IP belongs to a known datacenter or hosting range, a commercial VPN provider, a public proxy, or a Tor exit node, based on how that particular IP block is registered and operated. It's a classification of the infrastructure the request traveled through, not a judgment about the person behind it — plenty of legitimate traffic comes from VPNs for entirely ordinary, everyday reasons like privacy or corporate network policy.
Why datacenter ranges get flagged at all
Residential and mobile ISPs allocate addresses to homes and phones; hosting providers and cloud platforms allocate addresses to servers instead. Traffic claiming to be an individual shopper but originating from a hosting range is a mismatch worth knowing about, since real browsers rarely run from server infrastructure — automated tools, scrapers and relays often do exactly that.
A layer, not a verdict
This kind of signal has grown alongside the anonymization tools themselves: as VPNs and proxies became mainstream for everyday privacy, services that classify IP infrastructure became a standard input for fraud and abuse systems, sitting alongside other signals like device fingerprints and account history rather than replacing them outright.
How it plugs into a decision pipeline
Send the IP, get a task_id, and receive the classification via your signed webhook or a signed link valid for 24 hours, whichever suits your setup. Most integrations combine it with account history or behavioral signals rather than blocking on it alone, since VPN use by itself is rarely enough on its own to justify a hard rejection of an otherwise normal request.
What you can do with it
Signup abuse prevention
Add friction or extra verification to account creation attempts coming from datacenter or proxy ranges known for automated abuse.
Promo and coupon integrity
Reduce coupon farming by flagging repeated signups routed through VPN or proxy infrastructure.
Content licensing enforcement
Detect when a visitor is masking their real region through a VPN, informing how strictly to enforce location-based rules.
Checkout risk layering
Combine VPN and proxy detection with other signals to prioritize which orders get manual review.
FAQ
How does this vpn detection api actually work?
It checks the IP behind a request against known datacenter, hosting, VPN, proxy and Tor exit node ranges based on how those address blocks are registered and operated, then returns a classification.
Does it detect every VPN?
It covers known and actively tracked datacenter, VPN, proxy and Tor ranges; new or obscure services can appear as regular residential traffic until their ranges are identified.
Is VPN traffic always bad?
No. Plenty of legitimate users rely on VPNs for privacy or security, so this signal is meant to inform a decision, not replace one — most teams combine it with other risk signals instead of blocking outright.
Is it free to use?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
Can I check IPs in bulk?
Each call classifies one IP; for higher volume, send one request per IP and let the async queue process them in parallel.
How fast do I get results?
A task_id returns immediately, and the classification arrives via your signed webhook or a signed link valid for 24 hours.
Is my data retained after the check?
No, results are deleted once the retention window closes and are never used for training.
What if a check fails?
It retries automatically up to three times before returning a clear error, and failed requests are never billed.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/verify/ip-vpn \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"items":["valor-1","valor-2"]}'const res = await fetch("https://api.kit.forhosting.com/verify/ip-vpn", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"items": [
"valor-1",
"valor-2"
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/verify/ip-vpn",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"items": [
"valor-1",
"valor-2"
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/verify/ip-vpn", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"items":["valor-1","valor-2"]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"items":["valor-1","valor-2"]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/verify/ip-vpn", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"items": [
"valor-1",
"valor-2"
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "verify.ip_vpn",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |