wtfip.io API documentation
API v1 — stable
wtfip.io returns the caller's own public IP address plus its approximate geolocation (country, city) from the IP2Location LITE DB11 database. It is free, needs no API key or authentication, and has no bulk / arbitrary-IP lookup — every response reflects the IP of whoever made the request.
Endpoints
Base URL: https://wtfip.io. All endpoints take
no parameters — the result is derived from the caller's IP.
GET /json
Your public IP + geolocation as application/json.
GET /xml
The same payload as application/xml (root element
<wtfip.io>).
GET /
Content-negotiated: an HTML page for browsers, a plain-text body for
CLI user-agents (curl, wget, httpie, …), and Markdown when the request sends
Accept: text/markdown.
Response fields
| Field | Type | Always present | Description |
|---|---|---|---|
ip | string | yes | Caller's public IP (IPv4 or IPv6). |
country_name | string | yes | Full country name, e.g. "United States of America". |
city_name | string | yes | City the IP resolves to, e.g. "Ashburn". |
country_code | string | yes | ISO 3166-1 alpha-3, lowercase, e.g. usa. |
country_code_short | string | yes | ISO 3166-1 alpha-2, e.g. US. |
ip_list | array | JSON only | Array of the above objects when more than one IP is detected. |
Example request & response
$ curl -s https://wtfip.io/json
{
"ip": "203.0.113.7",
"country_name": "United States of America",
"city_name": "Ashburn",
"country_code": "usa",
"country_code_short": "US",
"ip_list": [
{ "ip": "203.0.113.7", "country_name": "United States of America",
"city_name": "Ashburn", "country_code": "usa", "country_code_short": "US" }
]
}
Code examples
# curl
curl -s https://wtfip.io/json
curl -s https://wtfip.io/xml
curl -s -H 'Accept: text/markdown' https://wtfip.io/
# Python
import requests
print(requests.get("https://wtfip.io/json").json())
# JavaScript
const data = await (await fetch("https://wtfip.io/json")).json();
console.log(data.ip);
# Go
resp, _ := http.Get("https://wtfip.io/json")
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
Responses & errors
| Status | Meaning |
|---|---|
200 OK | Success. |
429 Too Many Requests | Edge rate-limiter throttled you — back off and retry. |
500 Internal Server Error | Geolocation database could not resolve the request (rare, transient) — retry. |
There are no 4xx authentication/authorization errors because there
is no authentication. The MCP get_my_ip tool returns a tool-level error
result (isError) when the caller's IP cannot be determined.
Authentication & rate limits
Authentication: none. wtfip.io is a free, public, no-key API; no header, token, or signup is required.
Rate limits: there is no per-client quota. A single global
edge rate-limiter (Traefik) protects the service; ordinary use is unrestricted, but
abusive bursts may receive HTTP 429 — back off and retry. Cache the result:
your own IP does not change on every request.
Machine-readable surfaces
- OpenAPI 3.1 description —
/openapi.json - API catalog (RFC 9727 linkset)
- MCP server —
/mcp(streamable-HTTP; toolget_my_ip), server card - llms.txt · llms-full.txt
Import /openapi.json into Postman, Insomnia, or Bruno to get a
ready-to-run request collection. No language SDK is published — the stdlib snippets above
cover client usage.
Glossary
- Public IP
- The internet-routable address your traffic egresses from, as seen by wtfip.io.
- Geolocation
- Approximate country/city for an IP, from IP2Location LITE DB11. Not precise; not for security decisions.
country_code- ISO 3166-1 alpha-3, lowercase (e.g.
usa). country_code_short- ISO 3166-1 alpha-2 (e.g.
US). - CF-Connecting-IP
- The Cloudflare header wtfip.io reads to determine the caller's real IP behind the CDN.
Stability & versioning
API v1 — stable. No endpoints are deprecated or in beta. Any future breaking change will ship under a new version path and this page will carry a deprecation notice.