Documentation
All endpoints return the same flat data - pick whichever format suits your use case.
GET/json
Returns geo-IP and Cloudflare request metadata as application/json.
Request
GET https://whereami.kylewheeless.com/jsonResponse
{
"ip": "203.0.113.42",
"country": "US",
"city": "San Francisco",
"region": "California",
"regionCode": "CA",
"postalCode": "94105",
"latitude": "37.7749",
"longitude": "-122.4194",
"timezone": "America/Los_Angeles",
"continent": "NA",
"isEUCountry": "0",
"asn": 13335,
"asOrganization": "Cloudflare, Inc.",
"colo": "SFO",
"httpProtocol": "HTTP/2",
"tlsVersion": "TLSv1.3",
"tlsCipher": "AEAD-AES128-GCM-SHA256",
"clientTrustScore": 99
}Examples
# curl
curl https://whereami.kylewheeless.com/json
# JavaScript
const data = await fetch("https://whereami.kylewheeless.com/json").then(r => r.json());
console.log(data.city, data.region);
# Python
import urllib.request, json
data = json.load(urllib.request.urlopen("https://whereami.kylewheeless.com/json"))
print(data["city"], data["country"])GET/yaml
Same data serialized as YAML, with Content-Type: text/yaml. Useful for shell scripts or config pipelines.
Request
GET https://whereami.kylewheeless.com/yamlResponse
ip: 203.0.113.42
country: US
city: San Francisco
region: California
regionCode: CA
postalCode: '94105'
latitude: '37.7749'
longitude: '-122.4194'
timezone: America/Los_Angeles
continent: NA
isEUCountry: '0'
asn: 13335
asOrganization: Cloudflare, Inc.
colo: SFO
httpProtocol: HTTP/2
tlsVersion: TLSv1.3
tlsCipher: AEAD-AES128-GCM-SHA256
clientTrustScore: 99Examples
# curl
curl https://whereami.kylewheeless.com/yaml
# Shell - extract a single field with yq
curl -s https://whereami.kylewheeless.com/yaml | yq .cityGET/xml
Same data as XML, with Content-Type: application/xml.
Request
GET https://whereami.kylewheeless.com/xmlResponse
<?xml version="1.0" encoding="UTF-8"?>
<result>
<ip>203.0.113.42</ip>
<country>US</country>
<city>San Francisco</city>
<region>California</region>
<regionCode>CA</regionCode>
<postalCode>94105</postalCode>
<timezone>America/Los_Angeles</timezone>
<asn>13335</asn>
<asOrganization>Cloudflare, Inc.</asOrganization>
...
</result>Examples
# curl
curl https://whereami.kylewheeless.com/xml
# Shell - extract a field with xmllint
curl -s https://whereami.kylewheeless.com/xml | xmllint --xpath "//city/text()" -GET/ip
Returns just your public IP address as text/plain. No JSON, no parsing.
Request
GET https://whereami.kylewheeless.com/ipResponse
203.0.113.42Examples
# curl
curl https://whereami.kylewheeless.com/ip
# Shell - store your IP in a variable
MY_IP=$(curl -s https://whereami.kylewheeless.com/ip)
# JavaScript
const ip = await fetch("https://whereami.kylewheeless.com/ip").then(r => r.text());GET/text
Full geo-IP data as text/plain, one key: value pair per line. Good for shell one-liners and quick terminal use.
Request
GET https://whereami.kylewheeless.com/textResponse
ip: 203.0.113.42
country: US
city: San Francisco
region: California
regionCode: CA
postalCode: 94105
latitude: 37.7749
longitude: -122.4194
timezone: America/Los_Angeles
continent: NA
asn: 13335
asOrganization: Cloudflare, Inc.
colo: SFO
httpProtocol: HTTP/2
tlsVersion: TLSv1.3Examples
# curl
curl https://whereami.kylewheeless.com/text
# Shell - extract a single field with grep
curl -s https://whereami.kylewheeless.com/text | grep ^city | cut -d' ' -f2-GET/headers
Returns all request headers as application/json. Useful for debugging proxies, CDN setups, or seeing exactly what Cloudflare forwards.
Request
GET https://whereami.kylewheeless.com/headersResponse
{
"accept": "*/*",
"accept-encoding": "gzip, br",
"cf-connecting-ip": "203.0.113.42",
"cf-ipcountry": "US",
"cf-ray": "8a1b2c3d4e5f6a7b-SFO",
"cf-visitor": "{"scheme":"https"}",
"host": "whereami.kylewheeless.com",
"user-agent": "curl/8.4.0",
...
}Examples
# curl
curl https://whereami.kylewheeless.com/headers
# JavaScript
const headers = await fetch("https://whereami.kylewheeless.com/headers").then(r => r.json());
console.log(headers["cf-ray"], headers["user-agent"]);GET/weather
Returns current weather at your location using Open-Meteo (free, no key required). Requires the request to pass through the Cloudflare network so that latitude and longitude are available. Returns 503 if location data is missing.
Request
GET https://whereami.kylewheeless.com/weatherResponse
{
"latitude": 37.7749,
"longitude": -122.4194,
"timezone": "America/Los_Angeles",
"time": "2025-05-15T14:00",
"temperature": 62.1,
"feelsLike": 59.8,
"humidity": 74,
"windSpeed": 11.2,
"windDirection": 280,
"weatherCode": 2,
"condition": "Partly cloudy",
"isDay": true,
"units": {
"temperature": "°F",
"feelsLike": "°F",
"humidity": "%",
"windSpeed": "mp/h",
"windDirection": "°"
}
}Examples
# curl
curl https://whereami.kylewheeless.com/weather
# JavaScript
const wx = await fetch("https://whereami.kylewheeless.com/weather").then(r => r.json());
console.log(wx.condition, wx.temperature + wx.units.temperature);
# Shell - just the condition
curl -s https://whereami.kylewheeless.com/weather | jq -r '.condition'Field reference
All fields come from the Cloudflare request.cf object and are only present when the request passes through the Cloudflare network. Fields absent from request.cf for a given request will not appear in the response.
| Field | Type | Description |
|---|---|---|
ip | string | Client IP address |
country | string | ISO 3166-1 alpha-2 country code |
city | string | City name |
region | string | Region / state name |
regionCode | string | Region code (e.g. CA, NY) |
postalCode | string | Postal / ZIP code |
metroCode | string | Metro / DMA code (US only) |
latitude | string | Approximate latitude |
longitude | string | Approximate longitude |
timezone | string | IANA timezone (e.g. America/New_York) |
continent | string | Continent code - NA, EU, AS, AF, OC, SA, AN |
isEUCountry | boolean | true if the country is in the EU |
asn | number | Autonomous System Number |
asOrganization | string | AS organization / ISP name |
colo | string | Cloudflare data-center IATA code (e.g. SFO, LHR) |