Get Country from IP API: ISO Code, Name, Currency and EU Status in One Call

Updated

Short answer

Send a GET request to https://api.iplookupapi.com/v1/info with the IP address and fields=ip,location.country to get the country for any IPv4 or IPv6 address. The response includes the ISO 3166 alpha-2 and alpha-3 codes, the country name, an EU membership flag, currencies, calling codes, languages and time zones. Country data is part of every plan, including the free plan with 150 requests per month.

On this page

To get the country from an IP address, call GET /v1/info with the address and limit the response to location.country. You get back the ISO codes, the country name, EU membership, currencies, calling codes, languages and time zones in a single JSON object. This page shows the request, the response, working code for curl, Node.js, Python and PHP, a middleware sketch for country-based defaults, and how to keep your quota low with caching.

The box below shows what the API returns for your own connection.

Your public IP address

216.73.216.128

Location
Columbus, Ohio, United States
Provider
Anthropic, PBC (AS16509)
Time zone
America/New_York (UTC−4)
Coordinates
39.96, -83.00

This is the address websites see, and the location is an estimate that can be off by a city or more. Your device's local IP (often 192.168.x.x) is a different one and only works inside your network.

The one call: get the country for any IP

Send the IP address in the ip parameter and your key in the apikey header. The fields parameter takes comma-separated dot paths, so ip,location.country returns only the address and the country object. That keeps the response small.

Shell
curl -H "apikey: YOUR_API_KEY" \
  "https://api.iplookupapi.com/v1/info?ip=80.110.0.1&fields=ip,location.country"

You can also send the key as an apikey query parameter. The header is the better choice because URLs end up in server and proxy logs.

Response: the country object

The response is wrapped in data. This is a trimmed example for the address above:

JSON
{
  "data": {
    "ip": "80.110.0.1",
    "location": {
      "country": {
        "alpha2": "AT",
        "alpha3": "AUT",
        "name": "Austria",
        "emoji": "🇦🇹",
        "is_in_european_union": true,
        "calling_codes": ["+43"],
        "currencies": [
          {
            "code": "EUR",
            "name": "Euro",
            "name_plural": "Euros",
            "symbol": "€",
            "symbol_native": "€",
            "decimal_digits": 2,
            "rounding": 0,
            "type": "fiat"
          }
        ],
        "languages": [{ "name": "German", "name_native": "Deutsch" }],
        "timezones": ["Europe/Vienna"]
      }
    }
  }
}

The emoji field holds the country’s flag as an emoji character. The full country object has a few more fields. The info endpoint documentation lists every field and its type.

FieldWhat it holdsTypical use
alpha2ISO 3166-1 alpha-2 code, e.g. USDatabase keys, feature flags, analytics
alpha3ISO 3166-1 alpha-3 code, e.g. USAReports, systems that expect three letters
nameCountry name, e.g. AustriaDisplay text
is_in_european_uniontrue or falseConsent banners, VAT logic
currenciesCode, symbol, decimal digitsPrice display
calling_codesArray such as ["+43"]Default phone prefix in forms
languagesName and native nameLanguage defaults
timezonesIANA time zone IDs of the countryScheduling defaults

The codes follow the ISO 3166 country code standard. The language parameter (de, en, es, fr, ja, pt, ru or zh) sets the language for localized names. If you need the visitor’s local time rather than the country’s time zones, the IP time zone API covers the timezone object.

Get your visitor’s country (server-side)

If you leave out ip, the API answers for the address that made the request. That works for a script or backend job that needs its own country. On a website it does not work the way you might expect: your server makes the call, so you get your server’s country.

For a website, read the visitor’s IP on your server and pass it in ip. To see what an IP-based lookup says about your own connection, open Where am I.

Warning

Never put your API key in browser JavaScript, a mobile app bundle or any code a visitor can download. Call the API from your server or a serverless function and send only the result, such as the country code, to the browser.

Code examples: curl, Node.js, Python and PHP

All examples read the key from the IPLOOKUPAPI_KEY environment variable and run on the server. Replace 80.110.0.1 with the visitor’s address.

Node.js (fetch)

JavaScript
// Node.js 18+ (built-in fetch). Run this on your server, never in the browser.
const API_KEY = process.env.IPLOOKUPAPI_KEY;

async function getCountry(ip) {
  const params = new URLSearchParams({ ip, fields: 'ip,location.country' });
  const res = await fetch(`https://api.iplookupapi.com/v1/info?${params}`, {
    headers: { apikey: API_KEY },
  });
  if (!res.ok) {
    throw new Error(`Lookup failed with HTTP ${res.status}`);
  }
  const { data } = await res.json();
  return data.location.country;
}

getCountry('80.110.0.1')
  .then((country) => console.log(country.alpha2, country.name, country.is_in_european_union))
  .catch((err) => console.error(err.message));

Python (requests)

Python
import os

import requests

API_KEY = os.environ["IPLOOKUPAPI_KEY"]


def get_country(ip):
    response = requests.get(
        "https://api.iplookupapi.com/v1/info",
        params={"ip": ip, "fields": "ip,location.country"},
        headers={"apikey": API_KEY},
        timeout=5,
    )
    response.raise_for_status()
    return response.json()["data"]["location"]["country"]


country = get_country("80.110.0.1")
print(country["alpha2"], country["name"], country["is_in_european_union"])

PHP (cURL)

PHP
<?php
function getCountry(string $ip): array
{
    $query = http_build_query(['ip' => $ip, 'fields' => 'ip,location.country']);
    $ch = curl_init('https://api.iplookupapi.com/v1/info?' . $query);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['apikey: ' . getenv('IPLOOKUPAPI_KEY')],
        CURLOPT_TIMEOUT => 5,
    ]);
    $body = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

    if ($body === false || $status !== 200) {
        throw new RuntimeException("Lookup failed with HTTP $status");
    }
    return json_decode($body, true)['data']['location']['country'];
}

// In a web request, pass the visitor's address instead: $_SERVER['REMOTE_ADDR']
$country = getCountry('80.110.0.1');
echo $country['alpha2'] . ' ' . $country['name'] . PHP_EOL;

If you prefer a client library, official SDKs exist for Python (iplookupapi), PHP (everapi/iplookupapi-php), Ruby, C#, Rust and R; see the SDK overview. For JavaScript, fetch as above is all you need.

Middleware for country-based defaults (Express)

This sketch looks up each visitor once, caches the result for 24 hours and picks a display currency. It requests only the three fields it uses.

JavaScript
// npm install express   (Node.js 18+)
const express = require('express');

const app = express();
app.set('trust proxy', 'loopback'); // nginx on the same host; list your own proxies' addresses

const cache = new Map(); // ip -> { country, expires }
const TTL_MS = 24 * 60 * 60 * 1000; // 24 hours

async function lookupCountry(ip) {
  const hit = cache.get(ip);
  if (hit && hit.expires > Date.now()) return hit.country;

  const params = new URLSearchParams({
    ip,
    fields: 'location.country.alpha2,location.country.currencies,location.country.is_in_european_union',
  });
  const res = await fetch(`https://api.iplookupapi.com/v1/info?${params}`, {
    headers: { apikey: process.env.IPLOOKUPAPI_KEY },
    signal: AbortSignal.timeout(2000),
  });
  if (!res.ok) return null; // e.g. 404 when there is no data, 429 for rate limit or quota

  const { data } = await res.json();
  const country = data.location.country;
  cache.set(ip, { country, expires: Date.now() + TTL_MS });
  return country;
}

app.use(async (req, res, next) => {
  const ip = req.ip.replace(/^::ffff:/, ''); // IPv4-mapped IPv6 -> plain IPv4
  try {
    res.locals.country = await lookupCountry(ip);
  } catch {
    res.locals.country = null; // timeout or network error: use your defaults
  }
  next();
});

const SUPPORTED_CURRENCIES = ['USD', 'EUR', 'GBP', 'CAD'];

app.get('/pricing', (req, res) => {
  const code = res.locals.country?.currencies?.[0]?.code;
  const currency = SUPPORTED_CURRENCIES.includes(code) ? code : 'USD';
  res.send(`Prices shown in ${currency}`);
});

app.listen(3000);

Three details matter in production. Set trust proxy to match your setup, or req.ip shows your load balancer instead of the visitor; the Express guide on running behind proxies explains each option. Replace the in-memory Map with Redis or an LRU cache so it cannot grow without limit. And always fall back to a default, because local addresses such as 127.0.0.1 and ::1 have no country. In Laravel, the same pattern fits in a middleware that reads $request->ip() and caches with Cache::remember().

Note

Prefer defaults and suggestions over forced redirects. Google advises against automatically redirecting visitors to another language version, and its crawler mostly comes from US addresses, so an IP-based redirect can hide your localized pages from search. Show a banner such as “View the German site?” instead. See Google’s guidance on multi-regional sites.

What developers use IP country data for

  • Localized content and language defaults. Preselect a language or region from languages and alpha2, and let the user change it.
  • Currency and price display. Show prices in the currency from currencies, with the right symbol and number of decimal digits.
  • EU checks. Use is_in_european_union to decide which consent banner to show or which VAT logic to run. The field is a technical signal; which rules apply to your business is a question for your own counsel.
  • Geo restrictions and compliance signals. Limit features or content by country, for example where licenses only cover certain markets.
  • Analytics. Group sign-ups, orders or errors by country code without storing full IP addresses.
  • Fraud signals. Compare the IP country with the billing country or phone prefix (calling_codes). A mismatch is a reason to look closer, not proof of fraud.

How accurate is IP to country lookup?

Country is the most reliable level of IP geolocation. Address blocks are assigned to networks, and most networks serve a single country, so country results are far more dependable than city or postal code. How accurate IP geolocation is compares the levels with published study results.

The main source of wrong countries is the visitor’s setup, not the data. VPNs, proxies, Tor and some corporate networks route traffic through another country, and the API sees the exit point. If that matters for your use case, the security object flags VPN, proxy, Tor and data center addresses on the Professional plan and up. If you find an address with a wrong country, you can report the wrong location.

Cache results to save requests

IP-to-country mappings change slowly, but they do change: providers reassign addresses and move blocks between regions. Cache each IP’s result for a few hours up to a few days, keyed by the IP address. That cuts your request count sharply for returning visitors and keeps response times low.

Tip

Check your remaining quota with GET /v1/status, which does not count against it. The X-Cost response header shows how many requests a call counted. A 429 status means you have hit the rate limit or your monthly quota, so treat it as “use the default” rather than retrying in a loop.

Look up many IPs at once

For log files, CRM imports or nightly jobs, send up to 1,000 addresses in one POST request with the batch IP lookup API. The fields parameter works there too, so you can request only location.country.alpha2 for each address. Each valid address counts as one request, and invalid ones are listed in a top-level errors object next to data without being billed. Batch is included in every plan, including Free.

Plans: country data is included in every plan

PlanPrice per monthRequests per monthCountry data
Free$0150 (10 per minute)Yes
Basic$9.9965,000Yes
Professional$34.99650,000Yes, plus VPN/proxy/Tor flags
Enterprise$74.992,500,000Yes, plus VPN/proxy/Tor flags

Yearly billing gives you two months free. Compare all features on the pricing page, or get a free API key and run the curl command above.

Frequently asked questions

Is there a free API to get the country from an IP address?

Yes. The iplookupapi free plan includes country data for 150 requests per month at up to 10 requests per minute, and you can register for a free key without entering a paid plan. Paid plans start at $9.99 per month for 65,000 requests. See pricing for all plans.

How accurate is IP to country lookup?

Country is the most reliable level of IP geolocation, much more reliable than city or postal code, because address blocks are assigned and routed per network and most networks serve one country. It can still be wrong when a visitor uses a VPN, a proxy, Tor or a corporate network that exits in another country. In those cases the API returns the country where the traffic exits, not where the person is.

Does the IP to country API support IPv6?

Yes. The /v1/info endpoint accepts both IPv4 and IPv6 addresses in the ip parameter, and the type field in the response tells you which one you sent (v4 or v6). The country object has the same fields for both address types.

Which country code format does the API return?

The location.country object returns the ISO 3166-1 alpha-2 code (for example US or AT) in alpha2 and the ISO 3166-1 alpha-3 code (for example USA or AUT) in alpha3. It also returns the country name in name, so you rarely need your own code-to-name table.

How do I check if an IP address is in the European Union?

Read the boolean field location.country.is_in_european_union in the /v1/info response. It is true for addresses located in an EU member state and false otherwise. Use it as a technical signal, for example to choose which consent banner to show, and check with your own counsel which rules apply to your business.

Can I call the IP to country API from JavaScript in the browser?

Do not call it directly from browser code, because anyone could read your API key from the page. Call the API from your server or a serverless function with the visitor’s IP address, then pass only the result, such as the country code, to the browser.

Look up IP addresses in your code

iplookupapi returns the location, provider, time zone and security flags of any IP address as JSON. The free plan includes 150 requests a month.

curl "https://api.iplookupapi.com/v1/info?ip=8.8.8.8" \
  -H "apikey: YOUR_API_KEY"