Skip to content
IP IPBot
Get Started

IP Geolocation API - Free Country, City & Coordinates Lookup

Fast IP geolocation for developers: country, city, coordinates, and timezone in milliseconds.

IPBot returns geolocation fields under location, including country, region, city, postal code, latitude/longitude, and timezone. Results are designed to be stable and UI-friendly.

One request

Get geolocation + ASN + risk signals in a single response.

Cacheable

GET /{ip} is cacheable by default. See Rate Limits.

Example
curl -s https://api.ipbot.com/8.8.8.8 | jq ‘.location’

For the full schema, see Response Schema.

IP geolocation is the technology that determines the physical location of an internet-connected device based on its IP address. Every device connected to the internet has an IP address, and these addresses are allocated in regional blocks that can be mapped to geographic locations.

The IP geolocation market is valued at $3.2 billion in 2024 and is projected to reach $7.1 billion by 2033, reflecting the growing demand for location-aware services across fraud prevention, content personalization, and analytics.

When you make a request to an IP geolocation API, the service:

  1. Receives the IP address - Either from the request path or auto-detected from headers
  2. Queries the database - Matches the IP against known allocation blocks
  3. Returns location data - Country, region, city, coordinates, and timezone

The databases are built from multiple sources:

  • Regional Internet Registries (RIRs) - ARIN, RIPE, APNIC, LACNIC, AFRINIC
  • ISP allocation data - How providers assign IPs to regions
  • User corrections - Crowdsourced accuracy improvements
  • Active measurements - Network latency triangulation

The IPBot API returns comprehensive location data:

{
"location": {
"country": "United States",
"country_code": "US",
"region": "California",
"city": "Mountain View",
"postal": "94043",
"latitude": 37.4192,
"longitude": -122.0574,
"timezone": "-08:00"
}
}
FieldDescriptionTypeExample
countryFull country namestring”United States”
country_codeISO 3166-1 alpha-2 codestring”US”
regionState, province, or regionstring”California”
cityCity or town namestring”Mountain View”
postalZIP or postal codestring”94043”
latitudeDecimal latitudenumber37.4192
longitudeDecimal longitudenumber-122.0574
timezoneUTC offsetstring”-08:00”

IP geolocation accuracy varies by granularity level:

LevelAccuracyNotes
Country99%+Highly reliable for most IPs
Region/State90-95%Good for major regions
City50-80%Depends on ISP allocation patterns
Postal Code40-70%Often approximated to city center

Mobile Networks: Mobile carriers often show IPs from a different city than the user’s actual location because traffic routes through regional hubs.

VPNs and Proxies: Users behind VPNs will show the VPN server’s location, not their real location. IPBot detects most VPNs and flags them in the security response.

Corporate Networks: Large enterprises route traffic through central locations, so all employees may appear from headquarters.

Dynamic IPs: Residential IPs are reassigned frequently, which can cause temporary inaccuracies during database updates.

Automatically display content in the user’s language and currency:

const response = await fetch("https://api.ipbot.com/");
const data = await response.json();
// Set currency based on country
const currencyMap = {
US: "USD",
GB: "GBP",
EU: "EUR",
JP: "JPY",
AU: "AUD",
CA: "CAD",
CN: "CNY",
IN: "INR",
};
const currency = currencyMap[data.location.country_code] || "USD";
// Redirect to localized version
const localizedUrls = {
DE: "/de/",
FR: "/fr/",
ES: "/es/",
JP: "/ja/",
};
if (localizedUrls[data.location.country_code]) {
window.location.href = localizedUrls[data.location.country_code];
}

Display times in the user’s local timezone:

const data = await fetch("https://api.ipbot.com/").then((r) => r.json());
// Parse timezone offset
const tzOffset = data.location.timezone; // "-08:00"
const [hours, minutes] = tzOffset.split(":").map(Number);
const offsetMs = (hours * 60 + Math.sign(hours) * minutes) * 60 * 1000;
// Convert UTC to local time
const utcTime = new Date();
const localTime = new Date(utcTime.getTime() + offsetMs);

Show region-specific promotions:

const data = await fetch("https://api.ipbot.com/").then((r) => r.json());
// Show Black Friday deals only in US
if (data.location.country_code === "US") {
showBlackFridayBanner();
}
// Show local store finder
if (["US", "CA", "GB"].includes(data.location.country_code)) {
const nearbyStores = await findStoresNear(
data.location.latitude,
data.location.longitude,
);
displayStoreLocator(nearbyStores);
}

Understand your user demographics:

async function trackVisit() {
const data = await fetch("https://api.ipbot.com/").then((r) => r.json());
analytics.identify({
country: data.location.country,
region: data.location.region,
city: data.location.city,
timezone: data.location.timezone,
isp: data.network.org,
});
}

Implement geo-restrictions for legal compliance:

const data = await fetch("https://api.ipbot.com/").then((r) => r.json());
// GDPR compliance - show EU privacy notice
const euCountries = [
"AT",
"BE",
"BG",
"HR",
"CY",
"CZ",
"DK",
"EE",
"FI",
"FR",
"DE",
"GR",
"HU",
"IE",
"IT",
"LV",
"LT",
"LU",
"MT",
"NL",
"PL",
"PT",
"RO",
"SK",
"SI",
"ES",
"SE",
];
if (euCountries.includes(data.location.country_code)) {
showCookieConsentBanner();
enableGDPRDataHandling();
}
// Geo-blocking for licensing
const blockedCountries = ["KP", "IR", "SY"];
if (blockedCountries.includes(data.location.country_code)) {
return render451Page("Service not available in your region");
}
interface IPBotLocation {
country: string;
country_code: string;
region: string;
city: string;
postal: string;
latitude: number;
longitude: number;
timezone: string;
}
interface IPBotResponse {
ip: string;
location: IPBotLocation;
// ... other fields
}
async function getIPLocation(ip?: string): Promise<IPBotLocation> {
const url = ip ? `https://api.ipbot.com/${ip}` : "https://api.ipbot.com/";
const response = await fetch(url);
const data: IPBotResponse = await response.json();
return data.location;
}
// Usage
const location = await getIPLocation();
console.log(`User is in ${location.city}, ${location.country}`);
import requests
from dataclasses import dataclass
@dataclass
class Location:
country: str
country_code: str
region: str
city: str
postal: str
latitude: float
longitude: float
timezone: str
def get_ip_location(ip: str = "") -> Location:
url = f"https://api.ipbot.com/{ip}" if ip else "https://api.ipbot.com/"
response = requests.get(url)
data = response.json()
loc = data["location"]
return Location(
country=loc["country"],
country_code=loc["country_code"],
region=loc["region"],
city=loc["city"],
postal=loc["postal"],
latitude=loc["latitude"],
longitude=loc["longitude"],
timezone=loc["timezone"]
)
# Usage
location = get_ip_location("8.8.8.8")
print(f"IP is located in {location.city}, {location.country}")
Terminal window
# Get location for specific IP
curl -s https://api.ipbot.com/8.8.8.8 | jq '.location'
# Get your current location
curl -s https://api.ipbot.com/ | jq '.location'
# Get just country code
curl -s https://api.ipbot.com/ | jq -r '.location.country_code'
# Get coordinates for mapping
curl -s https://api.ipbot.com/1.1.1.1 | jq '{lat: .location.latitude, lng: .location.longitude}'
FeatureIPBotMaxMindipinfo.ioip-api.com
Free TierGenerousLimited50k/mo45/min
API Key RequiredNoYesYesNo
CORS EnabledYesN/AYesYes
Risk ScoringIncludedSeparatePaidNo
Postal CodeYesYesYesYes
CoordinatesYesYesYesYes

Geolocation data rarely changes. Cache responses to reduce API calls:

const cache = new Map();
const CACHE_TTL = 24 * 60 * 60 * 1000; // 24 hours
async function getLocationCached(ip) {
const cached = cache.get(ip);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const data = await fetch(`https://api.ipbot.com/${ip}`).then((r) => r.json());
cache.set(ip, { data, timestamp: Date.now() });
return data;
}

Always handle API errors gracefully:

async function safeGetLocation(ip) {
try {
const response = await fetch(`https://api.ipbot.com/${ip}`);
const data = await response.json();
if (data.error) {
console.error(`API error: ${data.error}`);
return null;
}
return data.location;
} catch (error) {
console.error(`Network error: ${error.message}`);
return null;
}
}
  • IP addresses are personal data under GDPR
  • Always have a privacy policy explaining IP usage
  • Consider not storing raw IPs - only derived data
  • Inform users when using location for personalization