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.