Guides

Geolocate a visitor by IP without a third-party script

Most IP geolocation on the web runs through a JavaScript tag that calls out to a third party from the visitor's browser. That is one more script to load, one more request the browser has to wait on, and one more thing that can silently fail if a visitor blocks it.

A server-side lookup instead

The /v1/ip endpoint takes an IP address and returns location data directly. If you call it from your own backend, using the IP address your web server already sees on the incoming connection, there is no script running in the visitor's browser at all.

GET /v1/ip?ip=203.0.113.42
{
  "status": "ok",
  "ip": "203.0.113.42",
  "version": 4,
  "found": true,
  "country": "France",
  "country_code": "FR",
  "region": "Ile-de-France",
  "city": "Paris",
  "postcode": "75001",
  "lat": 48.8566,
  "lon": 2.3522,
  "timezone": "Europe/Paris",
  "asn": 12345,
  "org": "Example Networks"
}

Omitting the IP parameter

If you call this endpoint without an ip parameter, it looks up the caller's own address, which is convenient when your backend is making the request on behalf of the visitor currently connected to it. Passing the ip parameter explicitly is what you want when you already have the address logged and are looking it up later.

What you get back

Country, region, and city cover most personalization use cases. The timezone field means you often do not need a second lookup just to know what local time it is for that visitor. The asn and org fields identify the network the address belongs to, which is useful for anything beyond simple personalization, such as spotting hosting providers or corporate networks.

An edge case worth handling

Not every address resolves to a location. The found field is false for a range that is reserved, unallocated, or simply not in the dataset, and the location fields will be absent or empty in that case. Check found before you read country or city, rather than assuming a successful HTTP response always means a usable location, since a request against a private or reserved address will still return a 200 with found set to false.

A mistake worth avoiding

Calling this endpoint on every single page view, rather than once per session, is the most common way a site burns through its allowance for no real benefit. A visitor's IP address, and therefore their approximate location, does not usually change between one page and the next during the same visit. Look it up once when the session starts, store the result against the session, and read from that stored copy on every later page instead of calling the endpoint again.

Request cost and caching

Each IP lookup is one request. Since a visitor's location rarely changes within a single session, look it up once and store the result for the session rather than calling it on every page view. That keeps a typical site well within the 2,500 free requests a day included with every key or available from a single address with no key at all.

The same endpoint and the same response shape work for IPv6 addresses without any change to your request, and the version field in the response tells you which family you got back. See the IPv6 lookup docs if your traffic includes a meaningful share of IPv6 visitors.

Running this server-side keeps a third-party script out of your page entirely, which matters for both speed and reliability. See the IPv4 lookup docs for the full field list.