Rust SDK · Feature

Detect VPN, Proxy & Tor in Rust

Catch traffic that hides behind anonymizers. Every lookup_ip already returns the suspicious_factors fields for proxy, VPN, Tor, datacenter, spam, and crawler — and the dedicated tor_check method adds live Tor exit-node confirmation. No extra call, no extra cost per screen.

Trusted by thousands of businesses
Fast JSON API responses
Real-time validation
Simple integration, SDKs & examples
What it does

Anonymizer detection, built into every lookup

Fraudsters, scrapers, and abusers routinely mask their real IP behind a VPN, an open proxy, the Tor network, or a cloud/datacenter host. ip-api.io maintains these lists in real time and returns a boolean for each on every IP lookup, so you can require step-up verification or block outright — without bolting on a separate service.

Prerequisites

1

Read suspicious_factors on any lookup

No dedicated call needed — the fields ride along with a normal lookup_ip.

let client = Client::new(std::env::var("IP_API_IO_KEY")?);

let info = client.lookup_ip("185.220.101.1").await?;
let f = &info.suspicious_factors;

println!("{}", f.is_vpn);        // VPN service
println!("{}", f.is_proxy);      // open / anonymizing proxy
println!("{}", f.is_tor_node);   // Tor node
println!("{}", f.is_datacenter); // hosting / datacenter IP (often a bot)
println!("{}", f.is_spam);       // known spam source
println!("{}", f.is_crawler);    // known crawler / bot
println!("{}", f.is_threat);     // listed on a threat feed

if f.is_vpn || f.is_proxy || f.is_tor_node {
    // require step-up verification (CAPTCHA, 2FA)
}
2

Confirm a Tor exit node with tor_check

A dedicated check against the live Tor node list, with a count of matching nodes.

let tor = client.tor_check("185.220.101.1").await?;

println!("{}", tor.is_tor);         // true
println!("{}", tor.tor_node_count); // number of matching Tor nodes
Want one number instead of flags? Risk scoring folds all of these signals into a single 0–100 score with risk_score_ip.
Reference

Response reference

suspicious_factors (all bool)

FieldMeaning
is_proxyOpen or anonymizing proxy
is_vpnCommercial VPN endpoint
is_tor_nodePart of the Tor network
is_datacenterHosting / datacenter range
is_spamKnown spam source
is_crawlerKnown crawler / bot
is_threatListed on a threat feed

TorDetection (from tor_check)

FieldTypeDescription
ipStringThe checked IP
is_torboolWhether the IP is a Tor node
tor_node_countu32Matching nodes for the IP
FAQ

Frequently asked questions

How do I detect a VPN or proxy in Rust?

Call client.lookup_ip(ip).await? and read the suspicious_factors struct. It has boolean fields is_vpn, is_proxy, is_tor_node, is_datacenter, is_spam, is_crawler and is_threat on every lookup, so no extra request is needed.

How do I check if an IP is a Tor exit node?

Use client.tor_check(ip).await?. It returns is_tor and tor_node_count, checked against the live Tor node list. The is_tor_node field on a normal lookup also covers this without a second call.

Do I need a separate call to get VPN and proxy flags?

No. The suspicious_factors fields come back on every geolocation lookup at no extra cost, so a single client.lookup_ip(ip) gives you both location and threat signals. Use tor_check only when you want the explicit Tor node count.

Should I block all VPN and proxy traffic?

Not necessarily — many legitimate users use VPNs. A common pattern is to require step-up verification when is_vpn, is_proxy or is_tor_node is true, and reserve hard blocks for is_threat. For a single decision, use the risk score.

Start building with the ip-api.io Rust SDK

Run cargo add ip-api-io, drop in your free API key, and ship in minutes — one async client for geolocation, fraud detection, and email validation.

Need support?

Explore how IP-API.io can enhance your security, provide robust bot protection, and improve IP geolocation accuracy for your applications.

Contact Support

Found a bug in the SDK?

The ip-api-io crate is open source. Open an issue or pull request on GitHub and we'll take a look.

Open on GitHub