{"openapi":"3.1.0","info":{"title":"utilo IP API","version":"1.0.0","description":"Free IP geolocation, WHOIS/RDAP, DNS, VPN/proxy detection, blacklist check, and CIDR calculator API. No API key required.","license":{"name":"MIT","identifier":"MIT"}},"servers":[{"url":"https://api.ip.utilo.kr"}],"paths":{"/ip":{"get":{"operationId":"getMyIp","summary":"Geolocate the caller's own public IP","description":"Returns geolocation for the requester's IP as seen at the Cloudflare edge (no upstream call, no cache).","x-rate-limit":"60/min","responses":{"200":{"description":"Geolocation for the caller's IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GeoIPEnvelope"}}}}}}},"/ip/{ip}":{"get":{"operationId":"getIp","summary":"Geolocate a specific IP address","description":"Looks up geolocation, ISP, and ASN for any IPv4 or IPv6 address via an upstream GeoIP provider (cached 24h). Falls back to edge-derived data (marked `partial: true`) if the upstream is unavailable and the request is proxied through Cloudflare.","x-rate-limit":"60/min","parameters":[{"name":"ip","in":"path","required":true,"description":"An IPv4 or IPv6 address.","schema":{"type":"string"},"example":"8.8.8.8"}],"responses":{"200":{"description":"Geolocation for the requested IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GeoIPEnvelope"}}}},"400":{"description":"The provided IP address is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"ok":false,"error":{"code":"INVALID_IP","message":"The provided IP address is not valid."}}}}},"502":{"description":"GeoIP service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"ok":false,"error":{"code":"UPSTREAM_ERROR","message":"GeoIP service unavailable"}}}}}}}},"/ip/{ip}/vpn":{"get":{"operationId":"getIpVpn","summary":"Detect VPN/proxy/hosting signals for an IP","description":"Reflects the proxy/hosting/mobile flags reported by the GeoIP provider. Does not specifically identify Tor exit nodes or residential/consumer VPN services.","x-rate-limit":"60/min","parameters":[{"name":"ip","in":"path","required":true,"description":"An IPv4 or IPv6 address.","schema":{"type":"string"},"example":"8.8.8.8"}],"responses":{"200":{"description":"VPN/proxy detection result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VpnEnvelope"}}}},"400":{"description":"The provided IP address is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"ok":false,"error":{"code":"INVALID_IP","message":"The provided IP address is not valid."}}}}},"502":{"description":"VPN detection service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"ok":false,"error":{"code":"UPSTREAM_ERROR","message":"VPN detection service unavailable"}}}}}}}},"/whois/{ip}":{"get":{"operationId":"getWhois","summary":"RDAP/WHOIS ownership lookup","description":"Looks up registrant organization, allocated network range, country, and registration events for an IP via RDAP (cached 7 days).","x-rate-limit":"10/min","parameters":[{"name":"ip","in":"path","required":true,"description":"An IPv4 or IPv6 address.","schema":{"type":"string"},"example":"8.8.8.8"}],"responses":{"200":{"description":"WHOIS/RDAP record for the requested IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhoisEnvelope"}}}},"400":{"description":"The provided IP address is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"ok":false,"error":{"code":"INVALID_IP","message":"The provided IP address is not valid."}}}}},"404":{"description":"No Whois data found for this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"ok":false,"error":{"code":"NOT_FOUND","message":"No Whois data found for this IP."}}}}}}}},"/dns/{domain}":{"get":{"operationId":"getDns","summary":"Resolve DNS records for a domain","description":"Resolves A, AAAA, MX, TXT, NS, or CNAME records for a domain via DNS-over-HTTPS (cached 5 min).","x-rate-limit":"30/min","parameters":[{"name":"domain","in":"path","required":true,"description":"Domain name to resolve.","schema":{"type":"string"},"example":"example.com"},{"name":"type","in":"query","required":false,"description":"DNS record type. Defaults to \"A\".","schema":{"type":"string","enum":["A","AAAA","MX","TXT","NS","CNAME"],"default":"A"}}],"responses":{"200":{"description":"Resolved DNS records.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DnsEnvelope"}}}},"400":{"description":"Invalid request — code is one of INVALID_DOMAIN | INVALID_TYPE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"invalidDomain":{"value":{"ok":false,"error":{"code":"INVALID_DOMAIN","message":"The provided domain is not valid."}}},"invalidType":{"value":{"ok":false,"error":{"code":"INVALID_TYPE","message":"Invalid DNS record type. Valid: A, AAAA, MX, TXT, NS, CNAME"}}}}}}},"502":{"description":"DNS lookup failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"ok":false,"error":{"code":"DNS_ERROR","message":"DNS lookup failed"}}}}}}}},"/dns/{ip}/reverse":{"get":{"operationId":"getReverseDns","summary":"Reverse DNS (PTR) lookup","description":"Looks up the PTR hostname for an IPv4 or IPv6 address (cached 5 min).","x-rate-limit":"30/min","parameters":[{"name":"ip","in":"path","required":true,"description":"An IPv4 or IPv6 address.","schema":{"type":"string"},"example":"8.8.8.8"}],"responses":{"200":{"description":"Reverse DNS (PTR) result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DnsEnvelope"}}}},"400":{"description":"The provided IP address is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"ok":false,"error":{"code":"INVALID_IP","message":"The provided IP address is not valid."}}}}},"502":{"description":"Reverse DNS lookup failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"ok":false,"error":{"code":"DNS_ERROR","message":"Reverse DNS lookup failed"}}}}}}}},"/blacklist/{ip}":{"get":{"operationId":"getBlacklist","summary":"Check an IPv4 address against abuse blacklists","description":"Checks DNSBL blacklists (Spamhaus ZEN, Barracuda, SpamCop) plus AbuseIPDB when configured (cached 1h). IPv4 only.","x-rate-limit":"10/min","parameters":[{"name":"ip","in":"path","required":true,"description":"An IPv4 address. IPv6 is not supported.","schema":{"type":"string"},"example":"185.220.101.1"}],"responses":{"200":{"description":"Blacklist check result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlacklistEnvelope"}}}},"400":{"description":"Invalid request — code is one of INVALID_IP | IPV6_UNSUPPORTED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"invalidIp":{"value":{"ok":false,"error":{"code":"INVALID_IP","message":"The provided IP address is not valid."}}},"ipv6Unsupported":{"value":{"ok":false,"error":{"code":"IPV6_UNSUPPORTED","message":"Blacklist check currently supports IPv4 only."}}}}}}},"502":{"description":"Blacklist check failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"ok":false,"error":{"code":"UPSTREAM_ERROR","message":"Blacklist check failed"}}}}}}}},"/cidr":{"get":{"operationId":"calculateCidr","summary":"Calculate subnet details from CIDR notation","description":"Calculates network/broadcast address, subnet mask, and host range from IPv4 CIDR notation. IPv4 only.","x-rate-limit":"60/min","parameters":[{"name":"range","in":"query","required":true,"description":"CIDR block, e.g. 192.168.1.0/24.","schema":{"type":"string"},"example":"192.168.1.0/24"}],"responses":{"200":{"description":"Calculated subnet details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CidrEnvelope"}}}},"400":{"description":"Invalid request — code is one of MISSING_RANGE | INVALID_CIDR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"missingRange":{"value":{"ok":false,"error":{"code":"MISSING_RANGE","message":"Query parameter \"range\" is required (e.g., ?range=192.168.1.0/24)"}}},"invalidCidr":{"value":{"ok":false,"error":{"code":"INVALID_CIDR","message":"The provided CIDR notation is not valid."}}}}}}}}}}},"components":{"schemas":{"ErrorEnvelope":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"GeoIP":{"type":"object","description":"Fields present depend on lookup path; ip-api.com-sourced lookups add proxy/hosting/mobile/isp.","properties":{"ip":{"type":"string"},"country":{"type":"string"},"city":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"asn":{"type":"number"},"asOrganization":{"type":"string"},"isp":{"type":"string"},"region":{"type":"string"},"timezone":{"type":"string"},"proxy":{"type":"boolean"},"hosting":{"type":"boolean"},"mobile":{"type":"boolean"},"partial":{"type":"boolean","description":"True when this is a degraded edge-only fallback (upstream GeoIP was unavailable)."}},"additionalProperties":true},"GeoIPEnvelope":{"type":"object","required":["ok","data","cached"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/GeoIP"},"cached":{"type":"boolean"},"cache_ttl":{"type":"number","description":"Seconds. Present when the value was freshly computed and cacheable."}}},"VpnResult":{"type":"object","properties":{"ip":{"type":"string"},"isVpn":{"type":"boolean"},"isProxy":{"type":"boolean"},"isHosting":{"type":"boolean"},"isMobile":{"type":"boolean"},"confidence":{"type":"string","enum":["high","medium","low"]}}},"VpnEnvelope":{"type":"object","required":["ok","data","cached"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/VpnResult"},"cached":{"type":"boolean"},"cache_ttl":{"type":"number"}}},"WhoisResult":{"type":"object","properties":{"ip":{"type":"string"},"name":{"type":"string"},"handle":{"type":"string"},"startAddress":{"type":"string"},"endAddress":{"type":"string"},"country":{"type":"string"},"registrant":{"type":"string"},"registrar":{"type":"string"},"events":{"type":"array","items":{"type":"object","properties":{"action":{"type":"string"},"date":{"type":"string"}}}}},"additionalProperties":true},"WhoisEnvelope":{"type":"object","required":["ok","data","cached"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/WhoisResult"},"cached":{"type":"boolean"},"cache_ttl":{"type":"number"}}},"DnsRecord":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string"},"ttl":{"type":"number"},"data":{"type":"string"}}},"DnsResult":{"type":"object","properties":{"query":{"type":"string"},"type":{"type":"string"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"}}}},"DnsEnvelope":{"type":"object","required":["ok","data","cached"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/DnsResult"},"cached":{"type":"boolean"},"cache_ttl":{"type":"number"}}},"BlacklistSource":{"type":"object","properties":{"name":{"type":"string"},"listed":{"type":"boolean"},"detail":{"type":"string"}}},"BlacklistResult":{"type":"object","properties":{"ip":{"type":"string"},"listed":{"type":"boolean"},"sources":{"type":"array","items":{"$ref":"#/components/schemas/BlacklistSource"}},"limitedSources":{"type":"boolean","description":"True when AbuseIPDB was unavailable, rate-limited, or not configured (only DNSBL sources were checked)."}}},"BlacklistEnvelope":{"type":"object","required":["ok","data","cached"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/BlacklistResult"},"cached":{"type":"boolean"},"cache_ttl":{"type":"number"}}},"CidrResult":{"type":"object","properties":{"cidr":{"type":"string"},"networkAddress":{"type":"string"},"broadcastAddress":{"type":"string"},"subnetMask":{"type":"string"},"wildcardMask":{"type":"string"},"prefix":{"type":"number"},"totalHosts":{"type":"number"},"usableHosts":{"type":"number"},"firstHost":{"type":"string"},"lastHost":{"type":"string"}}},"CidrEnvelope":{"type":"object","required":["ok","data","cached"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/CidrResult"},"cached":{"type":"boolean"}}}}}}