IP Geolocation API - Free Country, City & Coordinates Lookup
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.
Get geolocation + ASN + risk signals in a single response.
GET /{ip} is cacheable by default. See Rate Limits.
curl -s https://api.ipbot.com/8.8.8.8 | jq ‘.location’For the full schema, see Response Schema.
What is IP Geolocation?
Section titled “What is IP Geolocation?”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.
How IP Geolocation Works
Section titled “How IP Geolocation Works”When you make a request to an IP geolocation API, the service:
- Receives the IP address - Either from the request path or auto-detected from headers
- Queries the database - Matches the IP against known allocation blocks
- 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
Location Response Fields
Section titled “Location Response Fields”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" }}| Field | Description | Type | Example |
|---|---|---|---|
country | Full country name | string | ”United States” |
country_code | ISO 3166-1 alpha-2 code | string | ”US” |
region | State, province, or region | string | ”California” |
city | City or town name | string | ”Mountain View” |
postal | ZIP or postal code | string | ”94043” |
latitude | Decimal latitude | number | 37.4192 |
longitude | Decimal longitude | number | -122.0574 |
timezone | UTC offset | string | ”-08:00” |
Accuracy Expectations
Section titled “Accuracy Expectations”IP geolocation accuracy varies by granularity level:
| Level | Accuracy | Notes |
|---|---|---|
| Country | 99%+ | Highly reliable for most IPs |
| Region/State | 90-95% | Good for major regions |
| City | 50-80% | Depends on ISP allocation patterns |
| Postal Code | 40-70% | Often approximated to city center |
Factors Affecting Accuracy
Section titled “Factors Affecting Accuracy”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.
Common Use Cases
Section titled “Common Use Cases”Content Localization
Section titled “Content Localization”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 countryconst 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 versionconst localizedUrls = { DE: "/de/", FR: "/fr/", ES: "/es/", JP: "/ja/",};if (localizedUrls[data.location.country_code]) { window.location.href = localizedUrls[data.location.country_code];}Timezone-Aware Features
Section titled “Timezone-Aware Features”Display times in the user’s local timezone:
const data = await fetch("https://api.ipbot.com/").then((r) => r.json());
// Parse timezone offsetconst 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 timeconst utcTime = new Date();const localTime = new Date(utcTime.getTime() + offsetMs);Geo-Targeting Ads and Content
Section titled “Geo-Targeting Ads and Content”Show region-specific promotions:
const data = await fetch("https://api.ipbot.com/").then((r) => r.json());
// Show Black Friday deals only in USif (data.location.country_code === "US") { showBlackFridayBanner();}
// Show local store finderif (["US", "CA", "GB"].includes(data.location.country_code)) { const nearbyStores = await findStoresNear( data.location.latitude, data.location.longitude, ); displayStoreLocator(nearbyStores);}Analytics and Reporting
Section titled “Analytics and Reporting”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, });}Compliance and Access Control
Section titled “Compliance and Access Control”Implement geo-restrictions for legal compliance:
const data = await fetch("https://api.ipbot.com/").then((r) => r.json());
// GDPR compliance - show EU privacy noticeconst 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 licensingconst blockedCountries = ["KP", "IR", "SY"];if (blockedCountries.includes(data.location.country_code)) { return render451Page("Service not available in your region");}Integration Examples
Section titled “Integration Examples”JavaScript/TypeScript
Section titled “JavaScript/TypeScript”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;}
// Usageconst location = await getIPLocation();console.log(`User is in ${location.city}, ${location.country}`);Python
Section titled “Python”import requestsfrom dataclasses import dataclass
@dataclassclass 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"] )
# Usagelocation = get_ip_location("8.8.8.8")print(f"IP is located in {location.city}, {location.country}")# Get location for specific IPcurl -s https://api.ipbot.com/8.8.8.8 | jq '.location'
# Get your current locationcurl -s https://api.ipbot.com/ | jq '.location'
# Get just country codecurl -s https://api.ipbot.com/ | jq -r '.location.country_code'
# Get coordinates for mappingcurl -s https://api.ipbot.com/1.1.1.1 | jq '{lat: .location.latitude, lng: .location.longitude}'Comparison with Other APIs
Section titled “Comparison with Other APIs”| Feature | IPBot | MaxMind | ipinfo.io | ip-api.com |
|---|---|---|---|---|
| Free Tier | Generous | Limited | 50k/mo | 45/min |
| API Key Required | No | Yes | Yes | No |
| CORS Enabled | Yes | N/A | Yes | Yes |
| Risk Scoring | Included | Separate | Paid | No |
| Postal Code | Yes | Yes | Yes | Yes |
| Coordinates | Yes | Yes | Yes | Yes |
Best Practices
Section titled “Best Practices”Caching
Section titled “Caching”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;}Error Handling
Section titled “Error Handling”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; }}Privacy Considerations
Section titled “Privacy Considerations”- 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
Related Documentation
Section titled “Related Documentation”- API Reference - Full endpoint documentation
- Response Schema - Complete field reference
- ASN Lookup - Network ownership information
- Risk Scoring - Security and threat data
- Code Examples - More integration patterns