Free IP Lookup API
Your public IP, location, ISP and VPN or proxy status in one request.
No sign-up and no API key.
curl checkip.me
Quick start
$ curl checkip.me
203.0.113.42$ curl checkip.me/json
{"ip": "203.0.113.42", "country": ...}$ curl checkip.me/8.8.8.8
{"ip": "8.8.8.8", "isp": "Google LLC", ...}$ curl checkip.me/8.8.8.8/country
United StatesWorks on Linux, macOS and Windows 10/11, which ship with curl.exe.
Add -4 or -6 to force IPv4 or IPv6.
Endpoints
Two hostnames, same data. Pick the one that fits your use case.
checkip.me Simple APIPlain text and flat JSON with fixed field names. Use it in the terminal, in scripts and in most apps.
api.checkip.me Full APIEvery field the data source provides, as nested JSON. Use it when you need detection history, attack history or VPN operator details.
| Endpoint | Returns |
|---|---|
| Simple API | |
checkip.me | Your IP address as plain text |
checkip.me/ip | Your IP address as plain text, in browsers too |
checkip.me/json | Details for your IP (JSON) |
checkip.me/{ip} | Details for any IP (JSON) |
checkip.me/{field} | One field for your IP, plain text |
checkip.me/{ip}/{field} | One field for any IP, plain text |
| Full API | |
api.checkip.me/whoami | All data for your IP (JSON) |
api.checkip.me/{ip} | All data for any IP (JSON) |
All endpoints use GET over HTTPS. In the terminal, plain HTTP works too.
CORS is enabled on both hostnames, so you can call them from browser JavaScript.
OpenAPI: Simple API (checkip.me/openapi.json)
· Full API (api.checkip.me/openapi.json)
Response
GET checkip.me/8.8.8.8{
"ip": "8.8.8.8",
"hostname": "dns.google",
"asn": "AS15169",
"isp": "Google LLC",
"organisation": "Level 3",
"type": "Business",
"range": "8.8.8.0/24",
"continent": "North America",
"country": "United States",
"country_code": "US",
"region": "California",
"region_code": "CA",
"city": "Mountain View",
"postal_code": "94043",
"latitude": 37.422,
"longitude": -122.085,
"timezone": "America/Los_Angeles",
"currency": "USD",
"proxy": false,
"vpn": false,
"tor": false,
"hosting": false,
"compromised": false,
"scraper": false,
"anonymous": true,
"risk": 100,
"operator": null,
"docs": "https://checkip.me/api"
}ip | The IP address you looked up |
asn, isp, organisation | Network and owner |
type | Residential, Business, Wireless, Hosting… |
country … city | Approximate location |
latitude, longitude | Approximate coordinates |
timezone, currency | IANA timezone, ISO 4217 code |
proxy, vpn, tor | true when detected |
hosting | Data center or cloud IP |
compromised, scraper, anonymous | Other risk signals |
risk | Risk score from 0 to 100. Higher means riskier. |
operator | VPN or proxy provider, when known |
docs | Link to this documentation |
Unknown values are null. Any field can be fetched on its own as plain text,
for example checkip.me/8.8.8.8/isp or checkip.me/vpn.
Full API · GET api.checkip.me/8.8.8.8
{
"status": "ok",
"8.8.8.8": {
"network": {
"asn": "AS15169",
"range": "8.8.8.0/24",
"hostname": "dns.google",
"provider": "Google LLC",
"organisation": "Level 3",
"type": "Business"
},
"location": {
"continent_name": "North America",
"continent_code": "NA",
"country_name": "United States",
"country_code": "US",
"region_name": "California",
"region_code": "CA",
"city_name": "Mountain View",
"postal_code": "94043",
"latitude": 37.422,
"longitude": -122.085,
"timezone": "America/Los_Angeles",
"currency": { "name": "Dollar", "code": "USD", "symbol": "$" }
},
"device_estimate": { "address": 10, "subnet": 60 },
"detections": {
"proxy": false,
"vpn": false,
"compromised": false,
"scraper": false,
"tor": false,
"hosting": false,
"anonymous": true,
"risk": 100,
"confidence": 100,
"first_seen": "2026-09-21T08:17:28Z",
"last_seen": "2026-09-21T08:17:28Z",
"times_seen": null
},
"detection_history": { "delisted": true, "delist_datetime": "2026-09-18T06:18:03Z" },
"attack_history": { "vulnerability_probing": 20 },
"operator": null,
"last_updated": "2026-09-20T11:30:55Z"
},
"query_time": 5,
"docs": "https://checkip.me/api"
}The data for the IP is stored under a key named after the IP address, so read it with
data[ip]. It adds detection confidence, first and last seen dates, device estimates,
detection and attack history, and VPN operator details such as services, protocols and policies.
Code examples
# Your IP
IP=$(curl -s checkip.me)
echo "My IP is $IP"
# One field for your IP
COUNTRY=$(curl -s checkip.me/country)
# One field for any IP
curl -s checkip.me/8.8.8.8/isp
# Check whether an IP is a VPN
if [ "$(curl -s checkip.me/8.8.8.8/vpn)" = "true" ]; then
echo "VPN detected"
fi
# All fields as JSON
curl -s checkip.me/8.8.8.8curl checkip.me
curl checkip.me/country
curl checkip.me/8.8.8.8# Use curl.exe, because "curl" is an alias of Invoke-WebRequest in PowerShell
curl.exe checkip.me
# Or read the JSON directly
$info = Invoke-RestMethod https://checkip.me/8.8.8.8
$info.country# Check which IP a proxy gives you, and whether it is detected as a proxy
# HTTP / HTTPS proxy
curl -x http://user:pass@host:port checkip.me
curl -x http://user:pass@host:port checkip.me/json
# SOCKS4 (no password support in the protocol)
curl -x socks4://host:port checkip.me
# SOCKS5 (socks5h: DNS is resolved by the proxy)
curl -x socks5h://user:pass@host:port checkip.me# pip install "requests[socks]"
import requests
proxy = "socks5h://user:pass@host:port" # or http://..., socks4://...
proxies = {"http": proxy, "https": proxy}
info = requests.get("https://checkip.me/json", proxies=proxies, timeout=10).json()
print(info["ip"], info["country"], info["proxy"])import requests
# Your IP
ip = requests.get("https://checkip.me").text.strip()
# One field
country = requests.get("https://checkip.me/8.8.8.8/country").text.strip()
# All fields
info = requests.get("https://checkip.me/8.8.8.8").json()
print(info["country"], info["isp"], info["vpn"])
# Full API: nested data, stored under the IP address
ip = "8.8.8.8"
data = requests.get(f"https://api.checkip.me/{ip}").json()
print(data[ip]["detections"]["risk"], data[ip]["operator"])// Works in the browser (CORS enabled) and Node.js 18+
const res = await fetch("https://checkip.me/json");
const info = await res.json();
console.log(info.ip, info.country, info.vpn);
// Full API: nested data, stored under the IP address
const ip = "8.8.8.8";
const data = await (await fetch(`https://api.checkip.me/${ip}`)).json();
console.log(data[ip].detections.risk, data[ip].operator);<?php
// Your IP
$ip = trim(file_get_contents('https://checkip.me/ip'));
// One field
$country = trim(file_get_contents('https://checkip.me/8.8.8.8/country'));
// All fields
$info = json_decode(file_get_contents('https://checkip.me/8.8.8.8'), true);
echo $info['country'] . ' - ' . $info['isp'];Errors
Both APIs use the same status codes. A failed lookup returns an HTTP error status and a JSON body with an error field:
{
"ip": "192.168.1.1",
"error": "This is a private or reserved IP address. No public data is available for it."
}| Status | Meaning |
|---|---|
200 | Success |
400 | Missing ip parameter (api.checkip.me/check?ip= form only) |
404 | Unknown path or invalid IP address |
422 | Private or reserved IP (e.g. 10.x, 192.168.x) |
429 | Too many lookups. See usage limits below. |
502 | The data source did not respond. Try again later. |
Usage limits
- Looking up your own IP has no limit.
- Lookups of other IPs are limited to 120 per hour for each visitor,
on both
checkip.meandapi.checkip.me. IPs that were looked up recently are served from cache and don't count. - Need more? Contact us with your use case.
- Over the limit, you get HTTP
429with aRetry-Afterheader. - Results are cached, so data can be up to 30 days old.