Skip to content

Self-Hosted API

ipwhoami includes a self-hosted geolocation API in the api/ directory. It uses offline databases for sub-millisecond lookups with no rate limits, no API keys, and no third-party calls.

Third-party providers impose rate limits on free tiers:

ProviderFree Limit
ipinfo.io50k/month
ipapi.co1k/day
ip-api.com45/min

The self-hosted API has no such limits — it runs entirely on your own infrastructure using a local database.

Terminal window
cd api
npm install
npm run download-db # Downloads free DB-IP Lite databases (~70MB)
npm start # Starts on http://localhost:3001

Look up geolocation for a specific IP address.

Terminal window
curl http://localhost:3001/lookup/8.8.8.8
{
"ip": "8.8.8.8",
"city": "Mountain View",
"region": "California",
"country": "US",
"country_name": "United States",
"org": "AS15169 Google LLC",
"location": "37.422, -122.085",
"provider": "ipwhoami"
}

Auto-detect the caller’s IP from request headers and return geolocation. Checks headers in order: CF-Connecting-IP, X-Forwarded-For, X-Real-IP, Fly-Client-IP, then socket address.

Returns server status and database freshness.

{
"status": "ok",
"db_version": "2026-04-01",
"db_age_hours": 12,
"totalTracked": 42,
"totalBanned": 0
}

Returns API info and available endpoints.

The API includes built-in protection with zero external dependencies:

MeasureDefault
Rate limit100 requests/minute per IP
Auto-ban threshold300 requests/minute (3x limit)
Ban duration10 minutes
CleanupStale entries purged every 30 seconds

Every response from /lookup includes:

HeaderDescription
X-RateLimit-LimitMaximum requests per window
X-RateLimit-RemainingRequests remaining in current window
Retry-AfterSeconds to wait (only on 429)
X-Database-DateDate of the geolocation database
  • Sliding window: Tracks request timestamps per IP within a 1-minute window
  • Soft limit: Returns 429 Too Many Requests with Retry-After header
  • Auto-ban: If a client exceeds 3x the rate limit, they are banned for 10 minutes
  • In-memory: No external dependencies (Redis, etc.) — runs entirely in-process

The API uses DB-IP Lite — a free geolocation database (CC BY 4.0 license, no signup required).

FilePurposeSize
dbip-city-lite.mmdbCity-level geolocation~30MB
dbip-asn-lite.mmdbASN / ISP info~10MB

Databases are updated monthly by DB-IP. To update:

Terminal window
npm run download-db

The server auto-detects any *city*.mmdb and *asn*.mmdb file in api/data/, so it also works with MaxMind GeoLite2 databases if you prefer.

The server starts with just the city database. If the ASN database is missing, the org field will be null in responses.

ComponentChoice
RuntimeNode.js 18+
FrameworkHono (ultra-lightweight)
MMDB Readermaxmind npm package
Dependencies3 total (hono, @hono/node-server, maxmind)
api/
├── src/
│ ├── index.js # Hono app with all routes
│ ├── db.js # MMDB database loader
│ ├── ip.js # Client IP extraction from headers
│ ├── response.js # Normalize DB result to API shape
│ └── rate-limiter.js # Sliding window + auto-ban
├── test/ # 34 tests
├── scripts/
│ └── download-db.sh # Downloads free MMDB files
├── data/ # MMDB files (gitignored)
└── package.json

This product includes GeoLite data created by DB-IP.