{"openapi":"3.1.0","info":{"title":"IP Address API","summary":"Public IP, geolocation, and request inspection API.","description":"Free API that returns information about the calling client: public IP address,\nASN, geolocation, timezone, user-agent, the HTTP headers sent by the client,\nand connection security details (TLS, bot detection).\n\nEvery endpoint supports `GET`, `POST`, and `HEAD`. POST bodies are ignored —\nPOST is provided purely for clients that cannot issue a GET.\n\n## Content negotiation\n\nThe same path returns different formats depending on the request:\n\n- **`text/plain`** — default.\n- **`application/json`** — returned when any of these are true:\n  - `Accept` header contains `application/json` or `*/json`\n  - `Content-Type` header contains `application/json`\n  - `?json=1` or `?format=json` query parameter is present\n- **`text/html`** — only on `/`, when `Accept` contains `text/html` (returns\n  the human-readable documentation page instead of the IP).\n- **`text/markdown`** — only on `/`, when `Accept` contains `text/markdown`\n  (or `?format=md` / `?md=1`). Returns the raw Markdown README.\n\n## Response headers (always present)\n\nEvery response carries:\n\n- `x-ipapp-ip` — the detected public IP (or `Unknown` / empty)\n- `x-ipapp-ip-version` — `4`, `6`, or empty\n\nPer-endpoint `x-ipapp-*` headers are listed in each response section. These\nmake the API usable over `HEAD` requests (no response body needed).\n\n## Rate limiting and geo-restriction\n\nExcessive requests are rejected with HTTP `429`; Cloudflare's edge may\nadditionally return a non-standard `1015` block page. Certain countries are\nblocked at the edge due to historic abuse.\n","version":"2026.01.15","contact":{"name":"Fili","url":"https://fili.com/?ref=ip.app"},"license":{"name":"Use at your own risk — see disclaimer","url":"https://fili.com/d/?ref=ip.app"}},"servers":[{"url":"https://ip.app"}],"tags":[{"name":"ip","description":"Caller IP address"},{"name":"network","description":"Network-level info about the caller (ASN, location, timezone)"},{"name":"request","description":"Information extracted from the request itself (headers, user-agent)"},{"name":"security","description":"Connection security and bot detection"},{"name":"geolocation","description":"Geolocation endpoints (Mozilla Location Service-compatible)"}],"paths":{"/":{"parameters":[{"$ref":"#/components/parameters/Json"},{"$ref":"#/components/parameters/Format"}],"get":{"tags":["ip"],"summary":"Caller IP address","description":"Returns the public IP address of the requesting client.\n\nWhen called with `Accept: text/html`, returns the HTML documentation page\ninstead of the IP.\n","responses":{"200":{"description":"IP returned (or docs page for HTML requests).","headers":{"x-ipapp-ip":{"$ref":"#/components/headers/XIpappIp"},"x-ipapp-ip-version":{"$ref":"#/components/headers/XIpappIpVersion"}},"content":{"text/plain":{"schema":{"type":"string","example":"1.1.1.1"}},"application/json":{"schema":{"$ref":"#/components/schemas/IpResponse"}},"text/html":{"schema":{"type":"string","description":"Documentation page."}},"text/markdown":{"schema":{"type":"string","description":"Raw Markdown README."}}}},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["ip"],"summary":"Caller IP address (POST; body ignored)","description":"Same as `GET /`. Any POST body is ignored.","responses":{"200":{"description":"IP returned.","headers":{"x-ipapp-ip":{"$ref":"#/components/headers/XIpappIp"},"x-ipapp-ip-version":{"$ref":"#/components/headers/XIpappIpVersion"}},"content":{"text/plain":{"schema":{"type":"string"}},"application/json":{"schema":{"$ref":"#/components/schemas/IpResponse"}}}}}},"head":{"tags":["ip"],"summary":"IP in response headers only (no body)","responses":{"200":{"description":"No body; IP in `x-ipapp-ip` header.","headers":{"x-ipapp-ip":{"$ref":"#/components/headers/XIpappIp"},"x-ipapp-ip-version":{"$ref":"#/components/headers/XIpappIpVersion"}}}}}},"/asn":{"parameters":[{"$ref":"#/components/parameters/Json"},{"$ref":"#/components/parameters/Format"}],"get":{"tags":["network"],"summary":"ASN of the caller","description":"Returns the Autonomous System Number associated with the caller's IP,\nplus the AS organization name when available.\n\nText format: `AS15169: GOOGLE` — or empty if unavailable.\n","responses":{"200":{"description":"ASN returned (or empty when unknown).","headers":{"x-ipapp-ip":{"$ref":"#/components/headers/XIpappIp"},"x-ipapp-ip-version":{"$ref":"#/components/headers/XIpappIpVersion"},"x-ipapp-asn":{"description":"ASN with `AS` prefix, e.g. `AS15169`. Empty if unknown.","schema":{"type":"string","example":"AS15169"}}},"content":{"text/plain":{"schema":{"type":"string","example":"AS15169: GOOGLE"}},"application/json":{"schema":{"$ref":"#/components/schemas/AsnResponse"}}}}}},"post":{"$ref":"#/paths/~1asn/get"},"head":{"tags":["network"],"summary":"ASN in response headers only","responses":{"200":{"description":"No body; ASN in `x-ipapp-asn` header.","headers":{"x-ipapp-asn":{"schema":{"type":"string"}}}}}}},"/headers":{"parameters":[{"$ref":"#/components/parameters/Json"},{"$ref":"#/components/parameters/Format"}],"get":{"tags":["request"],"summary":"HTTP headers sent by the caller","description":"Returns the HTTP headers the client sent with its request. Cloudflare-injected\nheaders (`cf-*`), `x-forwarded-*`, common proxy/tracing headers (B3, Datadog,\nEnvoy, Amazon, etc.), and `x-real-ip` are filtered out.\n\nOn `HEAD` responses, each client header is echoed back as a response header\nprefixed with `x-ipapp-header-` (lowercased name).\n","responses":{"200":{"description":"Map of the caller's request headers.","headers":{"x-ipapp-ip":{"$ref":"#/components/headers/XIpappIp"},"x-ipapp-ip-version":{"$ref":"#/components/headers/XIpappIpVersion"}},"content":{"text/plain":{"schema":{"type":"string","example":"user-agent: curl/8.5.0\naccept: */*"}},"application/json":{"schema":{"$ref":"#/components/schemas/HeadersResponse"}}}}}},"post":{"$ref":"#/paths/~1headers/get"},"head":{"tags":["request"],"summary":"Headers echoed via `x-ipapp-header-*` response headers","responses":{"200":{"description":"No body; each client header echoed as `x-ipapp-header-<name>`."}}}},"/loc":{"parameters":[{"$ref":"#/components/parameters/Json"},{"$ref":"#/components/parameters/Format"}],"get":{"tags":["network"],"summary":"Caller IP geolocation","description":"City, region, country, postal code, continent, EU membership, and\napproximate coordinates, derived from Cloudflare's IP geolocation.\n","responses":{"200":{"description":"Location fields (values may be empty when unknown).","headers":{"x-ipapp-ip":{"$ref":"#/components/headers/XIpappIp"},"x-ipapp-ip-version":{"$ref":"#/components/headers/XIpappIpVersion"},"x-ipapp-loc-city":{"schema":{"type":"string"}},"x-ipapp-loc-region":{"schema":{"type":"string"}},"x-ipapp-loc-country":{"schema":{"type":"string","description":"ISO 3166-1 alpha-2 code."}},"x-ipapp-loc-postal_code":{"schema":{"type":"string"}},"x-ipapp-loc-continent":{"schema":{"type":"string"}},"x-ipapp-loc-is_eu_country":{"schema":{"type":"string","enum":["true","false"]}},"x-ipapp-loc-latitude":{"schema":{"type":"string"}},"x-ipapp-loc-longitude":{"schema":{"type":"string"}}},"content":{"text/plain":{"schema":{"type":"string"}},"application/json":{"schema":{"$ref":"#/components/schemas/LocationResponse"}}}}}},"post":{"$ref":"#/paths/~1loc/get"},"head":{"tags":["network"],"summary":"Location in response headers only","responses":{"200":{"description":"No body; location in `x-ipapp-loc-*` headers."}}}},"/sec":{"parameters":[{"$ref":"#/components/parameters/Json"},{"$ref":"#/components/parameters/Format"}],"get":{"tags":["security"],"summary":"Connection security and bot detection","description":"Information about the TLS connection (protocol, cipher, version, TCP RTT)\nand Cloudflare's bot management signals: bot score (1-100, higher = more\nlikely human), whether the UA is a verified bot, and the verified bot\ncategory when applicable.\n","responses":{"200":{"description":"Security and bot-detection data for the current connection.","headers":{"x-ipapp-ip":{"$ref":"#/components/headers/XIpappIp"},"x-ipapp-ip-version":{"$ref":"#/components/headers/XIpappIpVersion"},"x-ipapp-sec-http-protocol":{"schema":{"type":"string","example":"HTTP/2"}},"x-ipapp-sec-tls-version":{"schema":{"type":"string","example":"TLSv1.3"}},"x-ipapp-sec-tls-cipher":{"schema":{"type":"string"}},"x-ipapp-sec-tcp-rtt-ms":{"schema":{"type":"string"}},"x-ipapp-sec-bot-score":{"schema":{"type":"string","example":"99"}},"x-ipapp-sec-is-verified-bot":{"schema":{"type":"string","enum":["true","false"]}},"x-ipapp-sec-bot-category":{"schema":{"type":"string"}}},"content":{"text/plain":{"schema":{"type":"string"}},"application/json":{"schema":{"$ref":"#/components/schemas/SecurityResponse"}}}}}},"post":{"$ref":"#/paths/~1sec/get"},"head":{"tags":["security"],"summary":"Security info in response headers only","responses":{"200":{"description":"No body; security info in `x-ipapp-sec-*` headers."}}}},"/tz":{"parameters":[{"$ref":"#/components/parameters/Json"},{"$ref":"#/components/parameters/Format"}],"get":{"tags":["network"],"summary":"Caller timezone","description":"IANA timezone name, e.g. `Europe/Berlin`.","responses":{"200":{"description":"Timezone (empty when unknown).","headers":{"x-ipapp-ip":{"$ref":"#/components/headers/XIpappIp"},"x-ipapp-ip-version":{"$ref":"#/components/headers/XIpappIpVersion"},"x-ipapp-tz":{"schema":{"type":"string","example":"Europe/Berlin"}}},"content":{"text/plain":{"schema":{"type":"string","example":"Europe/Berlin"}},"application/json":{"schema":{"$ref":"#/components/schemas/TimezoneResponse"}}}}}},"post":{"$ref":"#/paths/~1tz/get"},"head":{"tags":["network"],"summary":"Timezone in response headers only","responses":{"200":{"description":"No body; timezone in `x-ipapp-tz` header."}}}},"/ua":{"parameters":[{"$ref":"#/components/parameters/Json"},{"$ref":"#/components/parameters/Format"}],"get":{"tags":["request"],"summary":"Caller User-Agent","description":"Returns the `User-Agent` header sent by the client.","responses":{"200":{"description":"User-Agent string.","headers":{"x-ipapp-ip":{"$ref":"#/components/headers/XIpappIp"},"x-ipapp-ip-version":{"$ref":"#/components/headers/XIpappIpVersion"},"x-ipapp-ua":{"schema":{"type":"string"}}},"content":{"text/plain":{"schema":{"type":"string"}},"application/json":{"schema":{"$ref":"#/components/schemas/UserAgentResponse"}}}}}},"post":{"$ref":"#/paths/~1ua/get"},"head":{"tags":["request"],"summary":"User-Agent in response headers only","responses":{"200":{"description":"No body; UA in `x-ipapp-ua` header."}}}},"/whereami":{"parameters":[{"$ref":"#/components/parameters/Json"},{"$ref":"#/components/parameters/Format"}],"get":{"tags":["geolocation"],"summary":"Coordinates (Mozilla Location Service-compatible)","description":"Returns geolocation coordinates for the caller. JSON response shape is\ncompatible with the decommissioned Mozilla Location Service / Ichnaea\n`geolocate` response so that Geoclue (Linux) can use it as a drop-in.\n\nAccuracy semantics:\n- `50000` (50 km) — precise IP-geolocation coords available\n- `500000` (500 km) — only country-level; falls back to country centroid\n","responses":{"200":{"description":"Coordinates found.","headers":{"x-ipapp-ip":{"$ref":"#/components/headers/XIpappIp"},"x-ipapp-ip-version":{"$ref":"#/components/headers/XIpappIpVersion"},"x-ipapp-latitude":{"schema":{"type":"string"}},"x-ipapp-longitude":{"schema":{"type":"string"}}},"content":{"text/plain":{"schema":{"type":"string","example":"52.52437, 13.41053"}},"application/json":{"schema":{"$ref":"#/components/schemas/WhereamiResponse"}}}},"404":{"description":"No geolocation data available for this IP.","content":{"text/plain":{"schema":{"type":"string","example":"Not Found"}}}}}},"post":{"$ref":"#/paths/~1whereami/get"},"head":{"tags":["geolocation"],"summary":"Coordinates in response headers only","responses":{"200":{"description":"No body; coords in `x-ipapp-latitude` / `x-ipapp-longitude`."},"404":{"description":"No geolocation data available."}}}},"/docs":{"get":{"tags":["ip"],"summary":"Redirect to HTML docs at `/`","responses":{"301":{"description":"Permanent redirect to `/`.","headers":{"Location":{"schema":{"type":"string","example":"/"}}}}}}},"/robots.txt":{"get":{"tags":["ip"],"summary":"robots.txt","responses":{"200":{"description":"Robots exclusion file.","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/llms.txt":{"get":{"tags":["ip"],"summary":"llms.txt summary for LLMs","description":"An [llms.txt](https://llmstxt.org)-format summary of the API — a concise\nMarkdown file LLMs can use to quickly locate the endpoints and the\nOpenAPI spec.\n","responses":{"200":{"description":"Markdown summary.","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/openapi.yaml":{"get":{"tags":["ip"],"summary":"OpenAPI specification (YAML)","responses":{"200":{"description":"This OpenAPI document in YAML.","content":{"application/yaml":{"schema":{"type":"string"}}}}}}},"/openapi.json":{"get":{"tags":["ip"],"summary":"OpenAPI specification (JSON)","responses":{"200":{"description":"This OpenAPI document in JSON.","content":{"application/json":{"schema":{"type":"object"}}}}}}}},"components":{"parameters":{"Json":{"name":"json","in":"query","required":false,"description":"Set to `1` to force a JSON response.","schema":{"type":"string","enum":["1"]}},"Format":{"name":"format","in":"query","required":false,"description":"Set to `json` to force a JSON response.","schema":{"type":"string","enum":["json"]}}},"headers":{"XIpappIp":{"description":"Detected public IP of the caller (or `Unknown` / empty).","schema":{"type":"string","example":"1.1.1.1"}},"XIpappIpVersion":{"description":"IP version — `4`, `6`, or empty string if no valid IP.","schema":{"type":"string","enum":["4","6",""]}}},"schemas":{"IpResponse":{"type":"object","required":["ip","ip_version"],"properties":{"ip":{"type":"string","description":"Public IPv4 or IPv6 address, or `Unknown`.","example":"1.1.1.1"},"ip_version":{"type":"string","enum":["4","6",""],"example":"4"}}},"AsnResponse":{"type":"object","description":"Empty object `{}` when no ASN is available.","properties":{"asn":{"type":"string","pattern":"^AS[0-9]+$","example":"AS15169"},"organization":{"type":"string","example":"GOOGLE"}}},"HeadersResponse":{"type":"object","description":"Map of header name → value. Keys depend on what the client sent.\nCloudflare-injected headers and common proxy/tracing headers are\nfiltered out.\n","additionalProperties":{"type":"string"},"example":{"user-agent":"curl/8.5.0","accept":"*/*","accept-encoding":"gzip"}},"LocationResponse":{"type":"object","description":"Any field may be empty when not known.","properties":{"latitude":{"type":["string","number"],"example":52.52437},"longitude":{"type":["string","number"],"example":13.41053},"city":{"type":"string","example":"Berlin"},"region":{"type":"string","example":"Berlin"},"region_code":{"type":"string","example":"BE"},"country":{"type":"string","example":"DE","description":"ISO 3166-1 alpha-2"},"postal_code":{"type":"string","example":"10115"},"continent":{"type":"string","example":"EU"},"is_eu_country":{"type":["boolean","string"],"example":true}}},"SecurityResponse":{"type":"object","properties":{"http_protocol":{"type":"string","example":"HTTP/2"},"tls_version":{"type":"string","example":"TLSv1.3"},"tls_cipher":{"type":"string","example":"AEAD-AES256-GCM-SHA384"},"tcp_rtt_ms":{"type":["string","number"],"example":12},"bot_score":{"type":["string","number"],"description":"1 (bot) → 100 (human). `0` when bot management unavailable.","example":99},"is_verified_bot":{"type":"boolean","example":false},"bot_category":{"type":"string","description":"Cloudflare verified-bot category, or `Unknown`.","example":"Search Engine Crawler"}}},"TimezoneResponse":{"type":"object","description":"Empty `{}` when unknown.","properties":{"tz":{"type":"string","example":"Europe/Berlin"}}},"UserAgentResponse":{"type":"object","required":["ua"],"properties":{"ua":{"type":"string","example":"curl/8.5.0"}}},"WhereamiResponse":{"type":"object","required":["location","accuracy"],"description":"Mozilla Location Service / Ichnaea-compatible shape.","properties":{"location":{"type":"object","required":["lat","lng"],"properties":{"lat":{"type":"number","example":52.52437},"lng":{"type":"number","example":13.41053}}},"accuracy":{"type":"integer","description":"Accuracy radius in meters (50000 = IP precision, 500000 = country centroid).","enum":[50000,500000],"example":50000}}},"Error":{"type":"object","properties":{"error":{"type":"string"}}}},"responses":{"RateLimited":{"description":"Rate limit exceeded. Cloudflare may additionally return a non-standard\n`1015` block page at the edge.\n","content":{"text/plain":{"schema":{"type":"string"}}}},"MethodNotAllowed":{"description":"Method not allowed. Use GET, POST, or HEAD.","headers":{"Allow":{"schema":{"type":"string","example":"GET, POST, HEAD"}}},"content":{"text/plain":{"schema":{"type":"string","example":"Method not allowed. Use GET, POST, or HEAD."}}}},"NotFound":{"description":"Path not found.","content":{"text/plain":{"schema":{"type":"string","example":"Not Found"}}}}}}}