Prerequisites
- A stable Rust toolchain with
ip-api-ioadded - A free ip-api.io API key
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)
} 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 risk_score_ip.