IP Geolocation API & Scraper
The IP Geolocation API resolves an IP address as clean JSON.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
The primary lookup endpoint returns country, region, city, coordinates, timezone and network info for an IP, and you can batch many lookups. It is built for personalization, fraud detection and analytics that need to place an IP without a local database. One ReefAPI key, one shared credit pool, the standard envelope.
Which fields are populated, and which are always null right now
Nothing here is guessed, and that means some fields come back empty on every address rather than filled with a plausible value. The table below is three measured lookups side by side: 8.8.8.8, Cloudflare's 2606:4700:4700::1111, and a Turkish consumer ISP address.
| Field | Measured values | What it is |
|---|---|---|
| country_code | US · CA · TR | ISO 3166-1 alpha-2. The country object beside it carries iso3, capital, currency, calling_code, population, tld, languages and an is_eu flag. |
| region_code | US-CA · CA-QC · TR-07 | ISO 3166-2 — note it includes the country prefix, so do not compare it against a bare state code |
| city | Mountain View · Montreal · Antalya | city-level, from the IP block registration |
| latitude / longitude | 37.422 / -122.085 | a city centroid, not a street address |
| postal | null on all three | not carried by the dataset — do not expect a ZIP |
| accuracy_radius_km | null on all three | not carried either |
| timezone / utc_offset | America/Los_Angeles / -07:00 | IANA zone plus the offset in force when you called |
| asn / as_org / isp | 15169 / Google LLC · 13335 / Cloudflare, Inc. | the autonomous system that announces the address |
| network | 8.8.8.0/24 · 2606:4700:4400::/38 | the CIDR block the address matched in — useful for caching a whole range |
| security.is_hosting | true · true · false | populated: true for the two cloud addresses, false for the consumer ISP |
| security.is_proxy / is_vpn / is_tor | null on all three | NOT false. We do not have this signal, and null says so. |
Lookups run against a local dataset — a measured call returned in 0.1 ms with meta.mode 'offline'. Batching therefore saves round trips, not upstream cost. Attribution travels in every response: DB-IP for the geolocation, GeoNames (CC BY 4.0) for the country facts.
Real request and response JSON
Captured from the indexed primary action, lookup, on .
{
"method": "POST",
"url": "https://api.reefapi.com/ip-geolocation/v1/lookup",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"ip": "8.8.8.8"
}
}{
"ok": true,
"meta": {
"api": "ip-geolocation",
"endpoint": "lookup",
"mode": "offline",
"latency_ms": 13.768,
"record_count": 1,
"bytes": 0,
"cache_hit": false,
"completeness_pct": 100,
"attribution": "IP Geolocation by DB-IP (https://db-ip.com); country data © GeoNames (CC BY 4.0)"
},
"data": {
"ip": "8.8.8.8",
"version": 4,
"status": "ok",
"is_private": false,
"found": true,
"country_code": "US",
"country_name": "United States",
"country": {
"area_km2": 9629091,
"calling_code": "1",
"capital": "Washington",
"continent": "NA",
"currency": "USD",
"currency_name": "Dollar",
"is_eu": false,
"iso2": "US",
"iso3": "USA",
"languages": [
"en-US",
"es-US",
"haw"
],
"name": "[redacted-name]",
"population": 327167434,
"tld": ".us"
},
"is_eu": false,
"continent_code": "NA",
"continent_name": "North America",
"region": "California",
"region_code": "US-CA",
"city": "Mountain View",
"postal": null,
"latitude": 37.422,
"longitude": -122.085,
"accuracy_radius_km": null,
"timezone": "America/Los_Angeles",
"utc_offset": "-07:00",
"asn": 15169,
"as_org": "Google LLC",
"isp": "Google LLC",
"network": "8.8.8.0/24",
"security": {
"is_hosting": true,
"is_proxy": null,
"is_vpn": null,
"is_tor": null
}
}
}What the IP Geolocation API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| lookup | geolocate ONE IPv4/IPv6 → country/region/city/lat-lon/timezone/ASN/ISP/org + hosting flag | Ops teams call lookup to get geolocate ONE IPv4/IPv6 → country/region/city/lat-lon/timezone/ASN/ISP/org + hosting flag. | ip, lang |
| batch | geolocate up to 100 IPs in one call | Developer tools call batch to get geolocate up to 100 IPs in one call. | ips, lang |
Call lookup from your stack
curl -X POST https://api.reefapi.com/ip-geolocation/v1/lookup \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"ip":"8.8.8.8"}'import requests
r = requests.post(
"https://api.reefapi.com/ip-geolocation/v1/lookup",
headers={"x-api-key": REEF_KEY},
json={
"ip": "8.8.8.8"
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/ip-geolocation/v1/lookup", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"ip": "8.8.8.8"
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.ip-geolocation.lookup with {"ip":"8.8.8.8"}.Who uses this API and why
- Apps call lookup to personalize content by a visitor's country.
- Fraud tools flag mismatches between an IP's geolocation and a claimed location.
- Analytics use batch to enrich server logs with geography.
Questions developers ask before integrating
is_proxy is null — does that mean the address is not a proxy?
No. null means unknown, and it is what all three of is_proxy, is_vpn and is_tor returned on every measured address. Only is_hosting is populated, and it answers a narrower question: is this address in a hosting or cloud range. Measured, that was true for both the Google and the Cloudflare address and false for a consumer ISP address. If you write `if (!security.is_proxy)` you are treating unknown as clean, which is exactly backwards for a fraud check.
Why did an address I know is global resolve to one specific city?
Anycast. A measured lookup on Cloudflare's 2606:4700:4700::1111 returned Canada, Quebec, Montreal with timezone America/Toronto — a real registration record for an address that answers from hundreds of sites worldwide. Any IP belonging to a CDN, a public resolver or a large cloud provider has a registered location and no meaningful physical one. The is_hosting flag is the warning: when it is true, treat city and coordinates as metadata about the operator, not about a user.
Does the lang parameter translate everything?
Only the country and continent names, and not for every language. Measured on 8.8.8.8: lang=de returned 'Vereinigte Staaten von Amerika' and 'Nordamerika', lang=fr returned 'États-Unis' and 'Amérique Du Nord', while region stayed 'California' and city stayed 'Mountain View' in every case. lang=tr came back entirely in English. lang=es returned 'Estados Unidos de América (los)' — the trailing article is an artifact of the source list, so trim it before display. Region and city names are never localized.
What happens with a private or reserved address?
You get an honest empty rather than an error: a measured lookup on 192.168.1.1 returned ok true with status 'private_or_reserved', is_private true, found false and meta.record_count 0. That is deliberate — a server logging its own LAN traffic should not see failures. A genuinely malformed address is different: 999.1.1.1 returned ok false with error code INVALID_PARAM, retryable false, and the offending value echoed back. Branch on found, and treat INVALID_PARAM as a bug in your own input handling.
Does IPv6 work, and how do I tell which I got?
Yes, both families resolve through the same lookup and the response reports version as the integer 4 or 6. The network field comes back in the matching notation — 8.8.8.0/24 for the IPv4 case and 2606:4700:4400::/38 for the IPv6 one. That prefix is worth keeping: every address inside it resolves identically, so caching on network instead of on ip collapses a lot of repeat traffic.
How accurate is the city, really?
City-level at best, and that is a property of IP geolocation itself rather than of this dataset. Coordinates are a centroid for the registered block, postal comes back null, and accuracy_radius_km is null too, so there is no radius to reason with. Use it for language defaults, currency defaults, coarse analytics and compliance geofencing at country level. Do not use it to prefill a shipping address, and do not use it to place a user on a map.
Can I look up many addresses at once?
Yes — batch takes an ips array and returns one record per address in the same shape, with lang applying to the whole batch. Since each individual lookup is a sub-millisecond local read, the win is purely in round trips: one request for a log file's worth of addresses instead of thousands. Records come back in the order you sent them, including the private and reserved ones, which stay in place with found false rather than being dropped.
What is the IP Geolocation API?
IP Geolocation API is a ReefAPI endpoint group for locate any ip — country, city and network. It returns live JSON through POST requests under /ip-geolocation/v1.
Is the IP Geolocation API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. IP Geolocation calls use the same shared credit balance as every other ReefAPI engine.
Do I need an IP Geolocation login or account?
No login to IP Geolocation is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the IP Geolocation data?
The page example is captured from a live lookup call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the IP Geolocation API use?
IP Geolocation actions currently cost 1-2 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call IP Geolocation from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call ip-geolocation actions with the same key, credit pool and JSON envelope used by normal REST requests.
Is the IP Geolocation API an IP Geolocation scraper?
It is the managed alternative to a DIY IP Geolocation scraper. Instead of building and maintaining your own scraper — proxies, headless browsers, captcha and constant breakage — you call one ReefAPI endpoint and get the same locate any ip — country, city and network back as clean JSON.