{"openapi":"3.1.0","info":{"title":"IP Checker API","version":"1.0.0","summary":"IP, network and connection diagnostics for scripts and AI agents.","description":"The IP Checker API describes the network connection making a request, and looks up arbitrary IP addresses.\n\n- No authentication is required for public endpoints.\n- Classifications (network type, proxy, VPN, Tor, hosting) are probabilistic. Each carries a certainty of `known`, `likely`, `inferred` or `unavailable` in the `confidence` / `classification` objects.\n- Values that cannot be determined are `null`, never guessed.\n- Rate limits: 120/min per IP for connection endpoints, 30/min for IP lookups, 5/min for proxy endpoints.\n- All errors share one envelope: `{ success: false, error: { code, message } }`."},"servers":[{"url":"https://ipcheck.trytorchlabs.com","description":"Production"}],"tags":[{"name":"Connection","description":"The connection making the request."},{"name":"Lookup","description":"Arbitrary IP addresses."},{"name":"Plain text","description":"Single values for shell scripts and agents."},{"name":"Proxy","description":"Proxy testing and validation (planned)."}],"paths":{"/ip":{"get":{"operationId":"getCurrentIp","tags":["Plain text"],"summary":"Caller public IP (plain text)","description":"Returns only the caller's public IP followed by a newline. The fastest endpoint.","responses":{"200":{"description":"Caller IP.","headers":{"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per window."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests remaining in the window."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."},"X-Request-Id":{"schema":{"type":"string"},"description":"Correlates the request with server logs."}},"content":{"text/plain":{"schema":{"type":"string"},"example":"203.0.113.42\n"}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/country":{"get":{"operationId":"getCurrentCountry","tags":["Plain text"],"summary":"Caller country code (plain text)","responses":{"200":{"description":"ISO 3166-1 alpha-2 country code, or `unknown`.","headers":{"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per window."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests remaining in the window."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."},"X-Request-Id":{"schema":{"type":"string"},"description":"Correlates the request with server logs."}},"content":{"text/plain":{"schema":{"type":"string"},"example":"US\n"}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/asn":{"get":{"operationId":"getCurrentAsn","tags":["Plain text"],"summary":"Caller ASN (plain text)","responses":{"200":{"description":"Autonomous system number prefixed with AS, or `unknown`.","headers":{"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per window."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests remaining in the window."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."},"X-Request-Id":{"schema":{"type":"string"},"description":"Correlates the request with server logs."}},"content":{"text/plain":{"schema":{"type":"string"},"example":"AS7018\n"}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/isp":{"get":{"operationId":"getCurrentIsp","tags":["Plain text"],"summary":"Caller ISP (plain text)","responses":{"200":{"description":"ISP name, or `unknown`.","headers":{"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per window."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests remaining in the window."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."},"X-Request-Id":{"schema":{"type":"string"},"description":"Correlates the request with server logs."}},"content":{"text/plain":{"schema":{"type":"string"},"example":"AT&T Enterprises, LLC\n"}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/me":{"get":{"operationId":"getCurrentConnection","tags":["Connection"],"summary":"Describe the calling connection","description":"Network, location and risk signals for the IP making the request.\n\n- `format=agent` returns a compact flat object.\n- `fields=a,b,c` returns only the listed fields (explicit allowlist). `fields` and `format=agent` are mutually exclusive.","parameters":[{"name":"format","in":"query","schema":{"type":"string","enum":["default","agent"],"default":"default"}},{"name":"fields","in":"query","description":"Comma-separated. Allowed: ip, ip_version, country, country_name, region, city, postal_code, latitude, longitude, timezone, asn, asn_name, isp, organization, network_type, proxy, vpn, tor, hosting, reverse_dns, user_agent, http_version, client_type, timestamp.","schema":{"type":"string"},"example":"ip,country,asn,isp"}],"responses":{"200":{"description":"Connection description. Shape depends on `format` / `fields`.","headers":{"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per window."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests remaining in the window."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."},"X-Request-Id":{"schema":{"type":"string"},"description":"Correlates the request with server logs."}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Me"},{"$ref":"#/components/schemas/AgentConnection"},{"$ref":"#/components/schemas/FieldSelection"}]},"examples":{"default":{"value":{"success":true,"ip":"203.0.113.42","ip_version":4,"network":{"asn":7018,"asn_name":"AT&T Enterprises, LLC","isp":"AT&T Enterprises, LLC","organization":"AT&T Enterprises, LLC","connection_type":"residential"},"location":{"country":"United States","country_code":"US","region":"California","region_code":null,"city":"Los Angeles","postal_code":null,"latitude":34.05,"longitude":-118.24,"timezone":"America/Los_Angeles"},"security":{"proxy":false,"vpn":false,"tor":false,"hosting":false},"request":{"http_version":null,"user_agent":"curl/8.7.1"},"unavailable":[],"timestamp":"2026-01-01T00:00:00.000Z"}},"agent":{"value":{"ip":"203.0.113.42","geo":"US-California-Los Angeles","asn":"AS7018","isp":"AT&T Enterprises, LLC","network_type":"residential","proxy":false,"vpn":false,"tor":false}},"fields":{"value":{"ip":"203.0.113.42","country":"US","asn":7018,"isp":"AT&T Enterprises, LLC"}}}}}},"400":{"description":"INVALID_FIELD or INVALID_FORMAT.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/ip/{ip}":{"get":{"operationId":"lookupIp","tags":["Lookup"],"summary":"Look up an IP address","description":"IPv4 or IPv6 (IPv4-mapped IPv6 is normalised to IPv4). Special-purpose addresses return empty network data plus `special_range`.","parameters":[{"name":"ip","in":"path","required":true,"schema":{"type":"string"},"example":"8.8.8.8"},{"name":"format","in":"query","schema":{"type":"string","enum":["default","agent"],"default":"default"}}],"responses":{"200":{"description":"Lookup result.","headers":{"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per window."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests remaining in the window."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."},"X-Request-Id":{"schema":{"type":"string"},"description":"Correlates the request with server logs."}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Lookup"},{"$ref":"#/components/schemas/AgentConnection"}]}}}},"400":{"description":"INVALID_IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/diagnostic":{"get":{"operationId":"getDiagnostics","tags":["Connection"],"summary":"Full connection diagnostic","description":"Everything the server can observe: network, geo, risk with certainty, protocol, allowlisted request headers and a probabilistic client classification.","responses":{"200":{"description":"Diagnostic.","headers":{"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per window."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests remaining in the window."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."},"X-Request-Id":{"schema":{"type":"string"},"description":"Correlates the request with server logs."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Diagnostic"}}}},"429":{"description":"RATE_LIMITED.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/proxy/test":{"post":{"operationId":"testProxy","tags":["Proxy"],"summary":"Test proxy connectivity and exit IP","description":"Connects through the proxy to a diagnostic endpoint controlled by this platform and reports the exit connection. Credentials are never logged or returned.\n\n**Status: planned.** The request contract is final and validated today; this deployment currently responds `501 NOT_IMPLEMENTED` after validation.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["proxy"],"additionalProperties":false,"properties":{"proxy":{"$ref":"#/components/schemas/ProxyInput"}}}}}},"responses":{"200":{"description":"Test result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyTestResult"}}}},"400":{"description":"INVALID_PROXY or UNSUPPORTED_PROTOCOL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"PAYLOAD_TOO_LARGE.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"NOT_IMPLEMENTED.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"PROXY_CONNECTION_FAILED.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"PROXY_TIMEOUT.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/proxy/validate":{"post":{"operationId":"validateProxy","tags":["Proxy"],"summary":"Validate a proxy against expectations","description":"Tests the proxy and compares the exit connection with expected country, region, city, ASN, ISP or network type. Designed for autonomous support workflows.\n\n**Status: planned.** The request contract is final and validated today; this deployment currently responds `501 NOT_IMPLEMENTED` after validation.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["proxy","expect"],"additionalProperties":false,"properties":{"proxy":{"$ref":"#/components/schemas/ProxyInput"},"expect":{"type":"object","minProperties":1,"additionalProperties":false,"properties":{"country":{"type":"string","minLength":2,"maxLength":2},"region":{"type":"string"},"city":{"type":"string"},"asn":{"type":"integer"},"isp":{"type":"string"},"network_type":{"type":"string","enum":["residential","mobile","hosting","business","education","government"]}}}}}}}},"responses":{"200":{"description":"Validation result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyValidationResult"}}}},"400":{"description":"INVALID_PROXY or UNSUPPORTED_PROTOCOL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"NOT_IMPLEMENTED.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/proxy/session-test":{"post":{"operationId":"testProxySession","tags":["Proxy"],"summary":"Test sticky-session stability","description":"Sends repeated requests through the proxy and reports how many distinct exit IPs were seen. Max 20 requests, 5000 ms interval, 60000 ms total.\n\n**Status: planned.** The request contract is final and validated today; this deployment currently responds `501 NOT_IMPLEMENTED` after validation.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["proxy"],"additionalProperties":false,"properties":{"proxy":{"$ref":"#/components/schemas/ProxyInput"},"requests":{"type":"integer","minimum":2,"maximum":20,"default":10},"interval_ms":{"type":"integer","minimum":0,"maximum":5000,"default":1000}}}}}},"responses":{"200":{"description":"Session result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxySessionResult"}}}},"400":{"description":"INVALID_PROXY or UNSUPPORTED_PROTOCOL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"NOT_IMPLEMENTED.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Error":{"type":"object","required":["success","error"],"properties":{"success":{"const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["INVALID_IP","INVALID_PROXY","INVALID_FIELD","INVALID_FORMAT","INVALID_REQUEST","UNSUPPORTED_PROTOCOL","PAYLOAD_TOO_LARGE","NOT_FOUND","NOT_IMPLEMENTED","PROXY_CONNECTION_FAILED","PROXY_TIMEOUT","RATE_LIMITED","INTERNAL_ERROR"]},"message":{"type":"string"},"details":{"type":"object"}}}}},"Certainty":{"type":"string","enum":["known","likely","inferred","unavailable"]},"SignalDetail":{"type":"object","properties":{"value":{},"certainty":{"$ref":"#/components/schemas/Certainty"},"confidence":{"type":["number","null"],"minimum":0,"maximum":1}}},"Signal":{"type":"object","properties":{"value":{},"certainty":{"$ref":"#/components/schemas/Certainty"},"confidence":{"type":["number","null"]},"basis":{"type":["string","null"],"description":"Evidence source, e.g. tor-exit-list, asn-hosting-list, asn-name-keywords."}}},"NetworkType":{"type":["string","null"],"enum":["residential","mobile","hosting","business","education","government","unknown",null]},"Network":{"type":"object","properties":{"asn":{"type":["integer","null"]},"asn_name":{"type":["string","null"]},"isp":{"type":["string","null"]},"organization":{"type":["string","null"]},"connection_type":{"$ref":"#/components/schemas/NetworkType"}}},"Location":{"type":"object","properties":{"country":{"type":["string","null"]},"country_code":{"type":["string","null"]},"region":{"type":["string","null"]},"region_code":{"type":["string","null"]},"city":{"type":["string","null"]},"postal_code":{"type":["string","null"]},"latitude":{"type":["number","null"]},"longitude":{"type":["number","null"]},"timezone":{"type":["string","null"]}}},"Security":{"type":"object","description":"Flattened estimates. true only when certainty is known or likely; null when undetermined; false when not detected. See Confidence for detail.","properties":{"proxy":{"type":["boolean","null"]},"vpn":{"type":["boolean","null"]},"tor":{"type":["boolean","null"]},"hosting":{"type":["boolean","null"]}}},"Confidence":{"type":["object","null"],"properties":{"connection_type":{"$ref":"#/components/schemas/SignalDetail"},"proxy":{"$ref":"#/components/schemas/SignalDetail"},"vpn":{"$ref":"#/components/schemas/SignalDetail"},"tor":{"$ref":"#/components/schemas/SignalDetail"},"hosting":{"$ref":"#/components/schemas/SignalDetail"},"timezone":{"type":"object","properties":{"certainty":{"$ref":"#/components/schemas/Certainty"}}}}},"Me":{"type":"object","properties":{"success":{"const":true},"ip":{"type":["string","null"]},"ip_version":{"type":["integer","null"],"enum":[4,6,null]},"network":{"$ref":"#/components/schemas/Network"},"location":{"$ref":"#/components/schemas/Location"},"security":{"$ref":"#/components/schemas/Security"},"confidence":{"$ref":"#/components/schemas/Confidence"},"request":{"type":"object","properties":{"http_version":{"type":["string","null"]},"user_agent":{"type":["string","null"]}}},"unavailable":{"type":"array","items":{"type":"string","enum":["location","network"]}},"timestamp":{"type":"string","format":"date-time"}}},"AgentConnection":{"type":"object","description":"Compact, flat, stable keys.","properties":{"ip":{"type":["string","null"]},"geo":{"type":["string","null"],"description":"COUNTRY-REGION-CITY, omitting unknown parts."},"asn":{"type":["string","null"],"example":"AS7018"},"isp":{"type":["string","null"]},"network_type":{"$ref":"#/components/schemas/NetworkType"},"proxy":{"type":["boolean","null"]},"vpn":{"type":["boolean","null"]},"tor":{"type":["boolean","null"]}}},"FieldSelection":{"type":"object","additionalProperties":true,"description":"Only the requested fields."},"Lookup":{"type":"object","properties":{"success":{"const":true},"ip":{"type":"string"},"version":{"type":"integer","enum":[4,6]},"reverse_dns":{"type":["string","null"]},"network":{"$ref":"#/components/schemas/Network"},"location":{"$ref":"#/components/schemas/Location"},"security":{"$ref":"#/components/schemas/Security"},"confidence":{"$ref":"#/components/schemas/Confidence"},"unavailable":{"type":"array","items":{"type":"string"}},"special_range":{"type":"string","description":"Present when the address is not publicly routable, e.g. private, loopback, documentation."}}},"Diagnostic":{"type":"object","properties":{"success":{"const":true},"connection":{"type":"object","properties":{"ip":{"type":["string","null"]},"version":{"type":["integer","null"]},"reverse_dns":{"type":["string","null"]},"special_range":{"type":["string","null"]}}},"network":{"type":"object","properties":{"asn":{"type":["integer","null"]},"asn_name":{"type":["string","null"]},"isp":{"type":["string","null"]},"organization":{"type":["string","null"]},"domain":{"type":["string","null"]},"network_type":{"$ref":"#/components/schemas/NetworkType"}}},"geo":{"$ref":"#/components/schemas/Location"},"risk":{"type":"object","properties":{"proxy":{"type":["boolean","null"]},"vpn":{"type":["boolean","null"]},"tor":{"type":["boolean","null"]},"hosting":{"type":["boolean","null"]},"relay":{"type":["boolean","null"]},"abuse_score":{"type":["number","null"]}}},"classification":{"type":["object","null"],"properties":{"network_type":{"$ref":"#/components/schemas/Signal"},"residential":{"$ref":"#/components/schemas/Signal"},"mobile":{"$ref":"#/components/schemas/Signal"},"datacenter":{"$ref":"#/components/schemas/Signal"},"proxy":{"$ref":"#/components/schemas/Signal"},"vpn":{"$ref":"#/components/schemas/Signal"},"tor":{"$ref":"#/components/schemas/Signal"},"hosting":{"$ref":"#/components/schemas/Signal"},"relay":{"$ref":"#/components/schemas/Signal"}}},"protocol":{"type":"object","properties":{"http":{"type":["string","null"]},"tls":{"type":["string","null"]},"tls_cipher":{"type":["string","null"]},"ja4":{"type":["string","null"]},"note":{"type":["string","null"]}}},"request":{"type":"object","additionalProperties":true},"client":{"type":"object","properties":{"client_type":{"type":"string","enum":["browser","cli","server","automation","bot","unknown"]},"confidence":{"type":"number"},"hash":{"type":"string"},"signals":{"type":"array","items":{"type":"string"}},"product":{"type":["string","null"]}}},"meta":{"type":"object","properties":{"providers":{"type":"array","items":{"type":"string"}},"unavailable":{"type":"array","items":{"type":"string"}},"attribution":{"type":"array","items":{"type":"string"}}}},"timestamp":{"type":"string","format":"date-time"}}},"ProxyInput":{"type":"object","required":["protocol","host","port"],"additionalProperties":false,"properties":{"protocol":{"type":"string","enum":["http","https","socks5"]},"host":{"type":"string","maxLength":253,"description":"Public hostname or IP. Private, loopback, link-local and metadata destinations are refused."},"port":{"type":"integer","minimum":1,"maximum":65535},"username":{"type":"string","maxLength":256},"password":{"type":"string","maxLength":256,"writeOnly":true,"description":"Never logged or returned."}}},"ProxyExit":{"type":"object","properties":{"ip":{"type":"string"},"country":{"type":["string","null"]},"region":{"type":["string","null"]},"city":{"type":["string","null"]},"asn":{"type":["integer","null"]},"isp":{"type":["string","null"]},"network_type":{"$ref":"#/components/schemas/NetworkType"}}},"ProxyTestResult":{"type":"object","properties":{"success":{"const":true},"reachable":{"type":"boolean"},"latency_ms":{"type":["integer","null"]},"exit":{"$ref":"#/components/schemas/ProxyExit"}}},"ProxyValidationResult":{"type":"object","properties":{"success":{"const":true},"reachable":{"type":"boolean"},"exit":{"$ref":"#/components/schemas/ProxyExit"},"validation":{"type":"object","additionalProperties":{"type":"object","properties":{"expected":{},"actual":{},"match":{"type":"boolean"}}}}}},"ProxySessionResult":{"type":"object","properties":{"success":{"const":true},"requests":{"type":"integer"},"successful":{"type":"integer"},"unique_ips":{"type":"integer"},"ips":{"type":"array","items":{"type":"object","properties":{"ip":{"type":"string"},"requests":{"type":"integer"}}}},"session":{"type":"object","properties":{"sticky":{"type":"boolean"},"stability":{"type":"number","minimum":0,"maximum":1}}}}}}}}