Published on Oct 2, 2022Ghadeer Al-MashhadiRead time: 9m1.5K viewer
How to Get a User's IP Address and Location in JavaScript (Free API)

How to Get a User's IP Address and Location in JavaScript (Free API)

Introduction

If you've ever tried to get an IP address in JavaScript from the browser, you've probably hit the same wall everyone does: there's no navigator.ip or anything like it. The browser simply doesn't hand your code the public IP, so you have to ask a server that can see it. The good news is that this takes one fetch call, and with the right API you can go from IP to country, city, and timezone in a second request.

This guide walks through the practical ways to handle "javascript get ip address" tasks, from free echo endpoints to Greip's key-free GET /ip. Then we'll get location from an IP address in JavaScript using the Greip IP Geolocation API v2, with a server-side proxy so your API key never ships to the browser. Along the way you'll see how to get the client IP address in JavaScript, how to get user location in JavaScript without a permission prompt, and how to pull just the country from an IP.

We'll also compare JavaScript geolocation through the browser's navigator.geolocation with IP-based lookups, since they solve different problems. By the end, you'll know which approach fits your signup form, checkout, or personalization logic.

Get the user's IP address in JavaScript

Because client-side code can't read its own public IP, every browser solution works the same way: call an endpoint that reads the connecting IP from the request and sends it back. The differences come down to response format, reliability, and what else you get with the answer. Here are three options, starting with the most minimal.

Cloudflare trace: a quick plain-text option

Cloudflare exposes a diagnostic endpoint at https://www.cloudflare.com/cdn-cgi/trace that returns plain text with one key=value pair per line. One of those lines is ip=, so you just need to parse it out.

async function getIpFromCloudflare() {
  const res = await fetch("https://www.cloudflare.com/cdn-cgi/trace");
  const text = await res.text();
  const line = text.split("\n").find((l) => l.startsWith("ip="));
  return line ? line.slice(3) : null;
}
getIpFromCloudflare().then((ip) => console.log("Your IP:", ip));

It works, but keep in mind this is a debugging endpoint rather than a documented product API. The format isn't JSON, and there's no contract promising it stays the same, so it's fine for quick scripts and less ideal for production code.

AWS checkip: the simplest possible response

Amazon's https://checkip.amazonaws.com/ returns your IP as a single line of plain text, nothing else. That makes parsing trivial, as long as you trim the trailing newline.

async function getIpFromAws() {
  const res = await fetch("https://checkip.amazonaws.com/");
  const ip = (await res.text()).trim();
  return ip;
}
getIpFromAws().then((ip) => console.log("Your IP:", ip));

The tradeoff is the same as with Cloudflare. You get the raw address and nothing about it, and browser support depends on the endpoint's CORS behavior, so test it in your target environment before relying on it.

Greip key-free GET /ip: structured JSON with no setup

If you want a clean JSON response from an endpoint that's actually documented for this purpose, Greip's Free Get-IP method is built for exactly that. You call https://v2.greipapi.com/ip with no account and no API key. Don't send an Authorization header to this endpoint, it doesn't need one.

async function getIpFromGreip() {
  const res = await fetch("https://v2.greipapi.com/ip");
  const json = await res.json();
  if (!json.success) {
    throw new Error("Could not retrieve IP");
  }
  const { address, version } = json.data.ip;
  return { address, version };
}
getIpFromGreip().then(({ address, version }) => {
  console.log(`Your IP is ${address} (IPv${version})`);
});

The response follows the v2 shape, { success, data: { ip: { address, version, numeric, bogon } } }. The version field tells you whether you're dealing with IPv4 or IPv6, and bogon flags addresses that shouldn't appear on the public internet, which is handy when you're validating what you received.

Get location from an IP address in JavaScript using Greip IP Geolocation API v2

Knowing the IP is step one. Most of the time what you actually want is where it's coming from, which country, city, timezone, or currency, and whether the connection looks risky. That's where the Greip IP geolocation API comes in.

The geolocation endpoints use an API key sent as Authorization: Bearer <api_key> on https://v2.greipapi.com. API v2 only accepts the key in that header, never in the query string. That also means you should not call these endpoints directly from browser code, because anyone could open DevTools and copy your key.

Pick the right endpoint: /geo/ip vs /lookup/ip/{ip}

Greip v2 gives you two ways to get location data. GET /geo/ip resolves the IP address of the request it receives, and GET /lookup/ip/{ip} looks up a specific address that you put in the path. Both return the same rich data object, so the choice depends on who is making the call.

In a server-side proxy, the request to Greip comes from your server, so /geo/ip would return your server's location rather than your visitor's. The right pattern is to read the client IP on your server and pass it to /lookup/ip/{ip}. Full parameter details live in the IP Geolocation docs.

Keep your API key server-side with a small Express proxy

Here's a minimal Node.js and Express setup. It reads the visitor's IP from the incoming request, calls Greip with the key from an environment variable, and returns only the fields your frontend needs. It uses the built-in fetch available in Node 18 and later.

// server.js
import express from "express";
const app = express();
// If you run behind a load balancer or CDN, this lets req.ip
// reflect the client IP from X-Forwarded-For. Configure it to
// match your infrastructure so the header can't be spoofed.
app.set("trust proxy", true);
const GREIP_API_KEY = process.env.GREIP_API_KEY;
app.get("/api/geo", async (req, res) => {
  const clientIp = req.ip;
  try {
    const url = new URL(
      `https://v2.greipapi.com/lookup/ip/${encodeURIComponent(clientIp)}`
    );
    url.searchParams.set("params", "security,timezone,currency");
    const greipRes = await fetch(url, {
      headers: { Authorization: `Bearer ${GREIP_API_KEY}` },
    });
    const json = await greipRes.json();
    if (!json.success) {
      return res.status(502).json({ error: json.description || "Lookup failed" });
    }
    const { ip, geo, timezone, currency, security } = json.data;
    res.json({
      ip: ip.address,
      country: geo.country,
      countryCode: geo.country_code,
      region: geo.region,
      city: geo.city,
      timezone: timezone?.name,
      currency: currency?.code,
      vpnOrProxy: security?.vpn_or_proxy,
    });
  } catch (err) {
    res.status(500).json({ error: "Geo lookup unavailable" });
  }
});
app.listen(3000, () => console.log("Listening on http://localhost:3000"));

The params query string lets you request optional modules, any of security, currency, timezone, location, and device. You can also pass lang for localized names, format for other response formats, and mode=test while you're wiring things up so you can integrate before going live.

Call your own /api/geo endpoint from the browser

With the proxy in place, your frontend code is short and contains no secrets. It just calls your own backend, which is also nice for caching and rate limiting later.

async function getUserLocation() {
  const res = await fetch("/api/geo");
  if (!res.ok) throw new Error("Geo request failed");
  return res.json();
}
getUserLocation().then((loc) => {
  console.log(`${loc.city}, ${loc.region}, ${loc.country}`);
  console.log(`Timezone: ${loc.timezone}, Currency: ${loc.currency}`);
});

This is the cleanest answer to "javascript ip location" in a real app. The browser never sees the key, and your server decides exactly what data leaves it.

Get the country from an IP address in JavaScript

Sometimes you only need the country, for example to preselect a dropdown or show local pricing. You can add a lighter route to the same server that returns just that.

// server.js (add alongside /api/geo)
app.get("/api/country", async (req, res) => {
  const greipRes = await fetch(
    `https://v2.greipapi.com/lookup/ip/${encodeURIComponent(req.ip)}`,
    { headers: { Authorization: `Bearer ${process.env.GREIP_API_KEY}` } }
  );
  const json = await greipRes.json();
  if (!json.success) return res.status(502).json({ error: "Lookup failed" });
  const { country, country_code } = json.data.geo;
  res.json({ country, countryCode: country_code });
});
// browser
const { country, countryCode } = await (await fetch("/api/country")).json();
document.querySelector("#country").value = countryCode;

If you already know an IP, say from a log line or an order record, the same /lookup/ip/{ip} call works for that address too. That's the core of "javascript get country from ip address": one authenticated server call, two fields out.

Moving from the old gregeoip.com examples

If your code still uses the legacy v1 style with the key in the query string, it's worth upgrading. v2 uses the same account, API key, and plan, but different base URLs, routes, Bearer authentication, and a nested response shape with data.ip and data.geo. The v1 to v2 migration guide has a practical checklist, and you can run both versions side by side while you switch.

Browser Geolocation API vs IP geolocation: permission prompt or no prompt

When people search for JavaScript geolocation, they often mean the browser's built-in navigator.geolocation. It's a different tool from IP geolocation, and knowing when to use each saves you from awkward UX.

navigator.geolocation.getCurrentPosition(
  (pos) => console.log(pos.coords.latitude, pos.coords.longitude),
  (err) => console.warn("Location denied or unavailable:", err.message)
);

The Browser Geolocation API can be very precise, especially on phones with GPS. But it only works in a secure context (HTTPS), it always triggers a permission prompt, and users can say no. You also get raw coordinates, so you still need to translate them into a country or city yourself.

IP geolocation works the other way around. There's no prompt and nothing for the user to approve, so you have a country and approximate city on the first request. The precision is lower, usually at the city or region level, and VPNs or proxies can shift the result. A sensible default is to use IP geolocation for everything that doesn't need street-level accuracy, and ask for browser location only when a feature truly needs it, like finding the nearest store.

Using IP location in signup and checkout flows

Location data becomes really useful when you treat it as a signal rather than a fact. At signup, comparing the IP country with the country a user selects can flag accounts worth a second look without blocking anyone outright. At checkout, a mismatch between IP country and billing country, or an IP marked as VPN, proxy, Tor, or hosting, is a reasonable trigger for extra verification.

With Greip, adding params=security to your lookup returns flags like vpn<em>or</em>proxy, tor, bot, relay, and hosting in the same response as the location. That means one call gives you both "where is this user" and "does this connection look normal," which keeps your fraud checks simple and fast.

Conclusion

Getting a user's IP in JavaScript always means asking a server, and you have a few solid choices. Cloudflare trace and AWS checkip are fine for quick scripts, while Greip's key-free GET https://v2.greipapi.com/ip gives you documented, structured JSON without an account. For location, keep your key on the server, call /lookup/ip/{ip} with the client IP, and return just what the browser needs.

If you're evaluating a free ip geolocation api for your project, you can start with the Greip free ip geolocation api options: the Get-IP endpoint costs nothing, and paid plans include a free trial so you can test full lookups in your own stack. Check Greip pricing when you're ready to go live, and keep the IP Geolocation docs handy as you add modules like security, timezone, and currency.

Get started

Start protecting your business today

Our service is trusted by thousands of businesses worldwide.

  • 1,000 requests during trial
  • Cancel anytime

Related Articles