Suggest a country from a visitor's IP address

Get a visitor's country with one IP API request and use it for regional content, defaults, or a country picker.

JavaScript (browser)Last tested Get the complete example ↓
On this page

Working example

HTML + JavaScript
Use this example

Get the visitor's country

Call /ip from the browser. ParseAPI looks up that connection and returns a two-letter country code, such as US. The same answer can suggest a regional storefront, choose local content, or provide a starting country in your app.

JavaScript
async function suggestCountry(signal) {
  const url = new URL('https://api.parseapi.com/ip');
  url.search = new URLSearchParams({ key: API_KEY });
  const response = await fetch(url, { signal, cache: 'no-store', redirect: 'error' });
  if (!response.ok) throw new Error('Country lookup failed.');
  const data = await response.json();
  return typeof data?.country === 'string' && /^[A-Z]{2}$/.test(data.country)
    ? data.country : null;
}

Replace YOUR_PUBLIC_API_KEY with a Public key from the example setup. Allow your site's hostname and localhost for local development. Serve the downloaded HTML over HTTP; keep secret keys on your server.

The working example runs on load and displays the country. Refresh repeats the lookup. It uses Intl.DisplayNames to turn the code into a readable name without another API request.

Use it as a default

suggestCountry() returns a country code or null. Use the code wherever your app needs a regional suggestion. If the country is unknown or the request fails, keep your existing default.

A saved preference or an explicit visitor choice should take precedence. A VPN, corporate network, or travel can change the connection's country, so do not use it to infer nationality, residence, language, or a shipping destination. The lookup does not request device-location permission.

For a server-side integration, call /ip/{ip} with the visitor's IP from your framework's trusted request information. A bare /ip call from your server looks up the server's connection. See the IP API reference for the response fields and request options.

Complete example

One HTML file with the markup, styles, and JavaScript. Replace YOUR_PUBLIC_API_KEY with your public key, then run it on a domain you have added to that key.

Download HTML
View and copy the complete source
suggest-country-from-ip.html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Suggest a country from a visitor's IP address</title>
  <style>
    :root { color-scheme: light dark; --bg: #fff; --ink: #152029; --muted: #5e6b75; --line: #d9e2e7; --field: #f6f9fa; --accent: #007c91; }
    @media (prefers-color-scheme: dark) {
      :root:not([data-theme="light"]) { --bg: #0b1015; --ink: #eff7fa; --muted: #94a6b2; --line: #2c3942; --field: #121b23; --accent: #67e8f9; }
    }
    :root[data-theme="dark"] { color-scheme: dark; --bg: #0b1015; --ink: #eff7fa; --muted: #94a6b2; --line: #2c3942; --field: #121b23; --accent: #67e8f9; }
    :root[data-theme="light"] { color-scheme: light; }
    * { box-sizing: border-box; }
    body { margin: 0; padding: 24px; background: var(--bg); color: var(--ink); font: 15px/1.5 system-ui, sans-serif; }
    main { max-width: 540px; margin: 0 auto; }
    h1 { margin: 0; color: var(--muted); font-size: 14px; font-weight: 500; }
    #country { margin: 8px 0; font-size: 28px; font-weight: 600; line-height: 1.25; overflow-wrap: anywhere; }
    #status { margin: 0; color: var(--muted); font-size: 13px; }
    button { margin-top: 20px; padding: 10px 14px; border: 1px solid var(--line); border-radius: 8px; background: var(--field); color: var(--accent); font: inherit; cursor: pointer; }
    button:disabled { opacity: .6; cursor: wait; }
    :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
    @media (max-width: 380px) { body { padding: 18px; } }
  </style>
</head>
<body>
  <main>
    <h1>Suggested country</h1>
    <div aria-live="polite" aria-atomic="true">
      <p id="country">Looking up your country...</p>
      <p id="status">Based on your internet connection.</p>
    </div>
    <button id="refresh" type="button">Refresh</button>
  </main>
  <script>
    const API_KEY = 'YOUR_PUBLIC_API_KEY';
    const country = document.querySelector('#country');
    const status = document.querySelector('#status');
    const refresh = document.querySelector('#refresh');
    const countryNames = new Intl.DisplayNames(['en'], { type: 'region' });
    let activeRequest;

    // example:request
    async function suggestCountry(signal) {
      const url = new URL('https://api.parseapi.com/ip');
      url.search = new URLSearchParams({ key: API_KEY });
      const response = await fetch(url, { signal, cache: 'no-store', redirect: 'error' });
      if (!response.ok) throw new Error('Country lookup failed.');
      const data = await response.json();
      return typeof data?.country === 'string' && /^[A-Z]{2}$/.test(data.country)
        ? data.country : null;
    }
    // /example:request

    async function refreshCountry() {
      activeRequest?.abort();
      const request = new AbortController();
      activeRequest = request;
      const timeout = setTimeout(() => request.abort(), 5000);
      refresh.disabled = true;
      country.textContent = 'Looking up your country...';
      status.textContent = 'Based on your internet connection.';
      try {
        const code = await suggestCountry(request.signal);
        if (activeRequest !== request) return;
        if (request.signal.aborted) throw new Error('Country lookup timed out.');
        country.textContent = code ? countryNames.of(code) : 'Country unknown';
        status.textContent = code
          ? `${code} · Based on your internet connection.`
          : 'Your connection did not return a country.';
      } catch {
        if (activeRequest !== request) return;
        country.textContent = 'Country unavailable';
        status.textContent = 'Could not look up your country. Try again.';
      } finally {
        clearTimeout(timeout);
        if (activeRequest === request) refresh.disabled = false;
      }
    }

    refresh.addEventListener('click', refreshCountry);
    refreshCountry();
  </script>
</body>
</html>

Need a key? Set up this browser example. For every field and parameter, see IP API reference.