geo-ip

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://geo-ip.kylewheeless.com/json

Response

{
  "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://geo-ip.kylewheeless.com/json

# JavaScript
const data = await fetch("https://geo-ip.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://geo-ip.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://geo-ip.kylewheeless.com/yaml

Response

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://geo-ip.kylewheeless.com/yaml

# Shell - extract a single field with yq
curl -s https://geo-ip.kylewheeless.com/yaml | yq .city

GET/ip

Returns just your public IP address as text/plain. No JSON, no parsing.

Request

GET https://geo-ip.kylewheeless.com/ip

Response

203.0.113.42

Examples

# curl
curl https://geo-ip.kylewheeless.com/ip

# Shell - store your IP in a variable
MY_IP=$(curl -s https://geo-ip.kylewheeless.com/ip)

# JavaScript
const ip = await fetch("https://geo-ip.kylewheeless.com/ip").then(r => r.text());

GET/headers

Returns all request headers as application/json. Useful for debugging proxies, CDN setups, or seeing exactly what Cloudflare forwards.

Request

GET https://geo-ip.kylewheeless.com/headers

Response

{
  "accept": "*/*",
  "accept-encoding": "gzip, br",
  "cf-connecting-ip": "203.0.113.42",
  "cf-ipcountry": "US",
  "cf-ray": "8a1b2c3d4e5f6a7b-SFO",
  "cf-visitor": "{"scheme":"https"}",
  "host": "geo-ip.kylewheeless.com",
  "user-agent": "curl/8.4.0",
  ...
}

Examples

# curl
curl https://geo-ip.kylewheeless.com/headers

# JavaScript
const headers = await fetch("https://geo-ip.kylewheeless.com/headers").then(r => r.json());
console.log(headers["cf-ray"], headers["user-agent"]);

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.

FieldTypeDescription
ipstringClient IP address (from CF-Connecting-IP header)
countrystringISO 3166-1 alpha-2 country code
citystringCity name
regionstringRegion / state name
regionCodestringRegion code (e.g. CA, NY)
postalCodestringPostal / ZIP code
metroCodestringMetro / DMA code (US only)
latitudestringApproximate latitude
longitudestringApproximate longitude
timezonestringIANA timezone (e.g. America/New_York)
continentstringContinent code - NA, EU, AS, AF, OC, SA, AN
isEUCountrystring"1" if the country is in the EU, "0" otherwise
asnnumberAutonomous System Number
asOrganizationstringAS organization / ISP name
colostringCloudflare data-center IATA code (e.g. SFO, LHR)
httpProtocolstringHTTP protocol version - HTTP/1.1, HTTP/2, or HTTP/3
requestPrioritystringHTTP request priority hint
tlsVersionstringTLS version negotiated (e.g. TLSv1.3)
tlsCipherstringTLS cipher suite
clientTrustScorenumberCloudflare bot / trust score (0–99; higher = more trusted)
edgeRequestKeepAliveStatusnumberKeep-alive status at the edge