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

REST API Examples

Geolocate an IP address

curl "https://geo.toolkitapi.io/v1/geo/ip-lookup?ip=8.8.8.8" \
  -H "X-API-Key: YOUR_KEY"
const params = new URLSearchParams({ ip: "8.8.8.8" });
const resp = await fetch(`https://geo.toolkitapi.io/v1/geo/ip-lookup?${params}`, {
  headers: { "X-API-Key": "YOUR_KEY" },
});
const data = await resp.json();
console.log(`${data.city}, ${data.country} (${data.latitude}, ${data.longitude})`);
Response
{
  "ip": "8.8.8.8",
  "city": "Mountain View",
  "region": "California",
  "country": "United States",
  "country_code": "US",
  "latitude": 37.386,
  "longitude": -122.0838,
  "asn": 15169,
  "asn_name": "GOOGLE",
  "org": "Google LLC",
  "query_time_ms": 34.2
}

Detect VPNs, proxies, and threats

curl "https://geo.toolkitapi.io/v1/geo/ip-threat?ip=198.51.100.42" \
  -H "X-API-Key: YOUR_KEY"
const params = new URLSearchParams({ ip: "198.51.100.42" });
const resp = await fetch(`https://geo.toolkitapi.io/v1/geo/ip-threat?${params}`, {
  headers: { "X-API-Key": "YOUR_KEY" },
});
const data = await resp.json();
console.log(`Threat: ${data.is_threat}, VPN: ${data.is_vpn}, Proxy: ${data.is_proxy}`);

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.