IP Intelligence¶
2 endpoints for resolving public IP addresses to geographic locations and detecting anonymisation infrastructure.
| Endpoint | Purpose |
|---|---|
GET /v1/geo/ip-lookup |
Resolve IP to city, region, country, coordinates, ASN |
GET /v1/geo/ip-threat |
Detect VPN, proxy, Tor, and datacenter IPs |
Python SDK Examples¶
Geolocate an IP address¶
ip_lookup accepts any public IPv4 or IPv6 address and returns city-level location data plus ASN information.
from toolkitapi import Geo
with Geo(api_key="tk_...") as geo:
result = geo.ip_lookup("8.8.8.8")
print(result["city"]) # "Mountain View"
print(result["region"]) # "California"
print(result["country"]) # "United States"
print(result["country_code"]) # "US"
print(result["latitude"]) # 37.386
print(result["longitude"]) # -122.0838
print(result["asn"]) # "AS15169"
print(result["org"]) # "Google LLC"
Geolocate a user's IP in a web request¶
from toolkitapi import Geo
def enrich_request(remote_ip: str) -> dict:
"""Return geo data for an incoming request IP."""
with Geo(api_key="tk_...") as geo:
try:
return geo.ip_lookup(remote_ip)
except Exception:
return {}
# Flask / FastAPI example
# location = enrich_request(request.remote_addr)
Check if an IP is a VPN, proxy, or Tor node¶
ip_threat returns anonymisation indicators — useful for fraud detection, access control, or analytics filtering.
from toolkitapi import Geo
suspicious_ips = [
"185.220.101.5", # Known Tor exit node
"104.16.100.1", # Cloudflare CDN
"8.8.8.8", # Google DNS
]
with Geo(api_key="tk_...") as geo:
for ip in suspicious_ips:
threat = geo.ip_threat(ip)
print(f"{ip}:")
print(f" VPN: {threat['is_vpn']}")
print(f" Proxy: {threat['is_proxy']}")
print(f" Tor: {threat['is_tor']}")
print(f" Datacenter: {threat['is_datacenter']}")
print(f" Threat score: {threat.get('threat_score', 'n/a')}")
Combine geolocation and threat data¶
from toolkitapi import Geo
def analyze_ip(ip: str) -> dict:
"""Return full IP intelligence: location + threat indicators."""
with Geo(api_key="tk_...") as geo:
location = geo.ip_lookup(ip)
threat = geo.ip_threat(ip)
return {
"ip": ip,
"city": location.get("city"),
"country": location.get("country_code"),
"org": location.get("org"),
"is_vpn": threat.get("is_vpn"),
"is_tor": threat.get("is_tor"),
"is_datacenter": threat.get("is_datacenter"),
}
result = analyze_ip("1.2.3.4")
if result["is_vpn"] or result["is_tor"]:
print("Anonymised traffic — proceed with caution")
Batch-process a list of IPs¶
from toolkitapi import Geo
access_log_ips = [
"8.8.8.8",
"1.1.1.1",
"185.220.101.5",
"91.108.4.1",
]
results = []
with Geo(api_key="tk_...") as geo:
for ip in access_log_ips:
try:
loc = geo.ip_lookup(ip)
threat = geo.ip_threat(ip)
results.append({
"ip": ip,
"country": loc.get("country_code"),
"city": loc.get("city"),
"flagged": threat.get("is_vpn") or threat.get("is_tor"),
})
except Exception as exc:
results.append({"ip": ip, "error": str(exc)})
for r in results:
flag = " [FLAGGED]" if r.get("flagged") else ""
print(f"{r['ip']} → {r.get('city')}, {r.get('country')}{flag}")
Response Fields¶
ip-lookup response:
| Field | Type | Description |
|---|---|---|
ip |
string | Normalised IP address |
city |
string | City name |
region |
string | State or province |
country |
string | Full country name |
country_code |
string | ISO 3166-1 alpha-2 code |
latitude |
float | Latitude |
longitude |
float | Longitude |
asn |
string | Autonomous System Number (e.g. AS15169) |
org |
string | Organisation name |
ip-threat response:
| Field | Type | Description |
|---|---|---|
ip |
string | Checked IP |
is_vpn |
bool | Known VPN exit node |
is_proxy |
bool | Open or commercial proxy |
is_tor |
bool | Tor exit node |
is_datacenter |
bool | Datacenter / hosting provider ASN |
Tip
Private (192.168.x.x, 10.x.x.x), loopback (127.x.x.x), and reserved address ranges return a 400 error. Only publicly routable IPs can be geolocated. In development, use a real public IP like 8.8.8.8 for testing.