Guide

How to Localize by IP with an IP Geolocation API

Set the right currency, language hint and timezone on the first request — before the user touches a setting — all from one lookup.

You can greet a visitor in their local currency, timezone and regional defaults on the very first request — no setting, no prompt — from a single IP lookup. The response already carries currency, timezone and country; this guide turns them into sensible defaults the user can always override.

Python

The examples here are Python, standard library only — but the same logic maps directly onto our official SDKs for TypeScript, Go, Ruby, Java and 7 more. Field paths and the worked outputs below are all verified against the live API.

1Get a key and call the API securely

Create a free account here — 2,000 lookups/day, no card. Send the key as an Authorization: Bearer header, loaded from an environment variable, so it stays out of URLs and logs:

Python
import os, urllib.request, json

API_KEY=***  # export it; never hardcode

def lookup(ip):
    req = urllib.request.Request(
        f"https://api.ipwho.org/ip/{ip}",
        headers={"Authorization": f"Bearer {API_KEY}", "User-Agent": "MyApp/1.0"},
    )
    with urllib.request.urlopen(req, timeout=10) as resp:
        return json.loads(resp.read())["data"]

2Three fields set your regional defaults:

The response carries everything you need for localization: currency.code / currency.symbol, timezone.time_zone, and geoLocation.countryCode / is_in_eu. Read them once on arrival:

Python
# Pull the localization fields — all in the standard response.
data = lookup("91.0.0.1")
geo = data.get("geoLocation") or {}
cur = data.get("currency") or {}
tz  = data.get("timezone") or {}

defaults = {
    "country":  geo.get("countryCode"),   # "DE"
    "currency": cur.get("code"),          # "EUR"
    "symbol":   cur.get("symbol"),        # "€"
    "timezone": tz.get("time_zone"),      # "Europe/Berlin"
    "in_eu":    geo.get("is_in_eu"),      # True
}
print(defaults)

3Format prices in the local currency — as a default, not a lock:

Use the currency to pre-select the storefront's display currency. This is a default: always keep a manual currency switcher, because a visitor's IP country isn't always where they want to be billed.

Python
# Format a price in the visitor's local currency. These are DISPLAY
# defaults — always let the user switch currency/locale manually.
def local_price(amount, data):
    cur = data.get("currency") or {}
    symbol = cur.get("symbol") or "$"
    code   = cur.get("code") or "USD"
    return f"{symbol}{amount:,.2f} {code}"

print(local_price(49, lookup("91.0.0.1")))   # €49.00 EUR
print(local_price(49, lookup("76.102.11.203")))  # $49.00 USD

4The full script — copy, paste, run:

Everything together. Export your key, pass an IP. Standard library only. Tested against the live API (2026-10-26).

Python
#!/usr/bin/env python3
"""Localize defaults from an IP using the IPWho IP geolocation API."""
import os, sys, urllib.request, json

API_KEY=***

def lookup(ip):
    req = urllib.request.Request(
        f"https://api.ipwho.org/ip/{ip}",
        headers={"Authorization": f"Bearer {API_KEY}", "User-Agent": "IPWho-L10n/1.0"},
    )
    with urllib.request.urlopen(req, timeout=10) as resp:
        return json.loads(resp.read())["data"]

def localize(data):
    geo = data.get("geoLocation") or {}
    cur = data.get("currency") or {}
    tz  = data.get("timezone") or {}
    return {
        "country":  geo.get("countryCode"),
        "currency": cur.get("code") or "USD",
        "symbol":   cur.get("symbol") or "$",
        "timezone": tz.get("time_zone"),
        "in_eu":    bool(geo.get("is_in_eu")),
    }

if __name__ == "__main__":
    ip = sys.argv[1] if len(sys.argv) > 1 else "91.0.0.1"
    print(f"{ip}: {localize(lookup(ip))}")
Output
$ python3 localize.py 91.0.0.1     # Deutsche Telekom, Germany
91.0.0.1: {'country': 'DE', 'currency': 'EUR', 'symbol': '€', 'timezone': 'Europe/Berlin', 'in_eu': True}

$ python3 localize.py 76.102.11.203    # Comcast, USA
76.102.11.203: {'country': 'US', 'currency': 'USD', 'symbol': '$', 'timezone': 'America/Los_Angeles', 'in_eu': False}

$ python3 localize.py 133.0.0.1    # Japan
133.0.0.1: {'country': 'JP', 'currency': 'JPY', 'symbol': '¥', 'timezone': 'Asia/Tokyo', 'in_eu': False}

Start with a free API key

Free tier: 2,000 lookups/day, no card. Paid plans from $2.50/month. Full field reference here, or see the localization use case here.