What It Does
Open IP Geo is a self-hosted PHP project that turns any server into an IP geolocation API. It uses MaxMind's GeoLite2 database (free, updated weekly) to resolve IP addresses to physical locations entirely offline — no external API calls, no per-query fees, no rate limits.
Give it an IP, get back:
Quick Start
Step 1. Download and upload to your server. Point your domain to the /public directory.
Step 2. Make /data writable: chmod 755 data/
Step 3. Sign up for a free MaxMind GeoLite2 account at maxmind.com and generate a license key.
Step 4. Visit /admin, enter your Account ID and License Key, click Download Database.
Step 5. Done. curl yoursite.com/api/8.8.8.8
API Endpoints
| Endpoint | Returns |
|---|---|
GET /api/lookup?ip=8.8.8.8 | Full geolocation JSON |
GET /api/8.8.8.8 | Shorthand — same result |
GET /api/me | Lookup your own IP |
GET /api/lookup?ip=8.8.8.8&fields=country,city | Filtered fields only |
POST /api/batch | Batch — up to 100 IPs per request |
GET /api/status | Health check + database info |
GET /admin | Admin dashboard |
Auto-Update
The database auto-refreshes weekly. By default it checks every Wednesday (when MaxMind publishes updates) and downloads fresh databases in the background — zero downtime, atomic file replacement.
For more reliable scheduling, use cron:
0 3 * * 3 /usr/bin/php /var/www/open-ip-geo/update-db.php
You can also trigger updates manually from the admin dashboard at any time.
Usage Examples
# Single lookup
curl "https://geo.yoursite.com/api/8.8.8.8" | jq .
# Your own IP
curl "https://geo.yoursite.com/api/me"
# Filtered fields
curl "https://geo.yoursite.com/api/lookup?ip=8.8.8.8&fields=country,city,location"
# Batch (POST)
curl -X POST "https://geo.yoursite.com/api/batch" \
-H "Content-Type: application/json" \
-d '{"ips": ["8.8.8.8", "1.1.1.1", "208.67.222.222"]}'
// JavaScript
const geo = await fetch('/api/8.8.8.8').then(r => r.json());
console.log(geo.city, geo.country.name, geo.location.timezone);
# Python
import requests
r = requests.get("https://geo.yoursite.com/api/lookup", params={"ip": "8.8.8.8"})
print(r.json()["city"])
Comparison
| Feature | ipstack | IPinfo | Open IP Geo |
|---|---|---|---|
| Free tier | 100 req/mo | Country-only (2025+) | Unlimited |
| City-level | Paid ($13+/mo) | Paid ($49+/mo) | Free |
| ASN / ISP | Paid | Paid | Free |
| Batch API | Paid | Paid | 100/request |
| Response time | ~100ms (network) | ~80ms (network) | <1ms (local) |
| Rate limits | Yes | Yes | Configurable/none |
| Data leaves server | Yes | Yes | No — fully offline |
| Self-hosted | No | No | Yes |
Honest note: ipstack and IPinfo offer additional data (VPN/proxy detection, company enrichment, abuse scoring) that this project does not. Open IP Geo covers the geolocation use case that 90%+ of lookups need.
Requirements
PHP 7.4+ (no special extensions), Apache (mod_rewrite) or Nginx, writable /data directory (~70 MB for databases), free MaxMind GeoLite2 account. No database server. No Composer. No npm. No framework dependencies.
Attribution
This product includes GeoLite2 Data created by MaxMind, available from maxmind.com. GeoLite2 data is licensed under CC BY-SA 4.0. MMDB reader library by MaxMind (MIT license).
License
GPLv2 or later. Free to use, modify, and distribute. Built by Max Intel. See all self-hosted tools.