API documentation
A small REST API that returns geolocation, network, and timezone data as JSON. No API key is required to start — 45 requests per minute per address, no sign-up.
Quickstart
Look up any address — no key, no account:
curl https://api.ipaddresstoday.com/api/v1/8.8.8.8Look up the caller's own address with /api/v1/ip, or get just the IP as plain text from the frozen ipify-compatible alias:
curl https://api.ipaddresstoday.com/api/ip?format=textReady for more? Create a free API key for 10,000 lookups a month, then send it as a header:
curl -H "X-API-Key: ipt_live_your_key_here" \
https://api.ipaddresstoday.com/api/v1/8.8.8.8Try it now
This calls the live API from your browser, keyless. Leave the field empty to look up your own address.
Endpoints
GET /api/v1/ip— full lookup of the caller's IP.GET /api/v1/{ip}— full lookup of any IPv4 or IPv6 address.POST /api/v1/batch— up to 100 addresses at once (paid plans).GET /api/ip— the IP only, as JSON, text, or JSONP. This shape is frozen and will never change.GET /api/v1/health— service status, including database and cache connectivity.GET /openapi.json— the full OpenAPI 3.1 specification.
Batch lookup
Send up to 100 addresses in one request. Available on Starter and above, with a key carrying the batch.lookup scope. Each address consumes one unit of your monthly quota, so a 100-address batch costs 100 — the saving is in round trips, not quota.
curl -X POST https://api.ipaddresstoday.com/api/v1/batch \
-H "X-API-Key: ipt_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"ips": ["8.8.8.8", "1.1.1.1", "9.9.9.9"]}'Results come back in request order, one entry per input. A bad address fails only its own entry:
{
"count": 2,
"results": [
{ "ip": "8.8.8.8", "result": { "ip": "8.8.8.8", "type": "IPv4", ... } },
{ "ip": "10.0.0.1", "error": "non-routable-ip",
"message": "Private, loopback, or otherwise non-routable address." }
]
}Query parameters
fields— comma-separated dotted paths to keep, e.g.?fields=ip,location.country.name. Everything else is omitted, which keeps responses small on high-volume calls.lang— localise place names: en, de, es, fr, ja, pt-BR, ru, zh-CN.format— json (default), text, or jsonp with acallbackparameter.
Response fields
- ip
- The address that was looked up, normalised.
- type
- "IPv4" or "IPv6".
- location.continent
- Continent name, localised by the lang parameter.
- location.country.name
- Country name.
- location.country.code
- ISO 3166-1 alpha-2, e.g. AU.
- location.country.code3
- ISO 3166-1 alpha-3, e.g. AUS.
- location.country.capital
- Capital city.
- location.country.phoneCode
- International dialling prefix, e.g. +61.
- location.country.currency
- ISO 4217 code and symbol.
- location.country.flag
- Flag emoji.
- location.region
- Subdivision name and ISO code, e.g. New South Wales / NSW.
- location.city
- City name where known.
- location.postalCode
- Postal or ZIP code where known.
- location.latitude / longitude
- Approximate coordinates.
- location.accuracyRadius
- Radius in km the coordinates are accurate to.
- location.timezone
- IANA id, abbreviation, UTC offset, and current local time.
- connection.asn / as
- Autonomous system number, e.g. 15169 and AS15169.
- connection.network
- The announced CIDR block containing the address.
- connection.isp / org
- Network operator name.
- connection.type
- "Hosting" when the address belongs to a datacenter.
- privacy
- Booleans for vpn, proxy, tor, and hosting.
- ipInfo
- Booleans for isPublic, isPrivate, isReserved.
- hostname
- Reverse DNS name where one resolves.
- meta
- GeoLite2 database build date and server-side lookup time.
Fields are omitted rather than null when we have no data for them, so check for presence before reading.
Authentication
Keyless requests work immediately. To raise your quota, create a key in the dashboard and send it one of three ways — header, bearer token, or query parameter:
X-API-Key: ipt_live_…
Authorization: Bearer ipt_live_…
https://api.ipaddresstoday.com/api/v1/8.8.8.8?key=ipt_live_…Prefer the header. The query parameter exists for environments that cannot set headers, but keys in URLs tend to end up in server logs and browser history.
Keys carry scopes (lookup.read, batch.lookup, usage.read, account.read), can be restricted to specific IPs or origins, can be given an expiry, and can be rotated or revoked at any time. A key is shown once at creation and cannot be recovered afterwards — store it somewhere safe.
Rate limits and quotas
Keyless lookups of a specific address (/api/v1/{ip}) are limited to 45 requests per minute per address, with wider per-network ceilings so shared connections are not punished for one noisy neighbour. Keyed traffic is limited by your plan's monthly quota: 10,000 on Free, 150,000 on Starter, 1M on Pro, 10M on Business.
The two “your own IP” endpoints — /api/v1/ip and /api/ip — are not metered. They return the caller their own address, so there is nothing to farm, and the what-is-my-IP page depends on them.
Every response carries the state of the active bucket:
X-RateLimit-Limit: 45
X-RateLimit-Remaining: 44
X-RateLimit-Reset: 1785204000Exceeding a limit returns 429 with a Retry-After header — never a surprise bill. Back off until the reset rather than retrying immediately; persistent hammering is treated as abuse.
Errors
Every error uses RFC 7807 problem+json, and the type field is a stable URL that links to the exact entry in the error reference.
{
"type": "https://www.ipaddresstoday.com/docs/errors#invalid-ip",
"title": "Invalid IP address",
"status": 400,
"detail": "'999.1.1.1' is not a valid IPv4 or IPv6 address."
}Versioning and stability
The API is versioned in the path. /api/v1 is the current version, and we will not make breaking changes to it — adding a field is not breaking, removing or renaming one is.
If a /api/v2 ever becomes necessary, v1 will keep working for at least 12 months after v2 ships, and we will email every account with an active key before anything is switched off. The /api/ip alias is frozen permanently and is exempt from all of this.
OpenAPI specification
The full machine-readable specification lives at https://api.ipaddresstoday.com/openapi.json. Import it into Postman or Insomnia, or generate a typed client:
npx openapi-typescript https://api.ipaddresstoday.com/openapi.json -o ipt.d.tsSomething unclear or missing? Tell us — documentation gaps are bugs.