Free IP API – get your IP address and country from code
Send a plain GET request to https://api.ipgeo.ru/ and one line of JSON comes back: {"ok":true,"ip":"203.0.113.10","country":"US"}. There is no key, no sign-up and no header to set, and the same request works from a terminal, from a page in a browser and from a server. The answer always describes whoever sent the request – so a call made by your server returns your server's IP address, not your visitor's.
Updated 11 August 2026
The endpoint and your first request
There is one address to call: https://api.ipgeo.ru/. It takes an ordinary GET request – no body, no headers, no key. Plain http is redirected to https, so start with https and save yourself the extra hop.
The quickest way to see it work is one line in a terminal:
curl -s https://api.ipgeo.ru/
One line comes back:
{"ok":true,"ip":"203.0.113.10","country":"US"}Keep one thing in mind from the start: the answer is always about whoever sent the request. Run it on your laptop and you see your home IP address. Run it on a server and you see the server's. Let a visitor's browser send it and you see that visitor's.
What comes back
Three fields, no nesting, always in the same place.
- ok – true when the IP address was read successfully;
- ip – the address the request came from. It can be IPv4 (203.0.113.10) or IPv6 (2001:db8::1), depending on which protocol the connection actually used;
- country – a two-letter country code: US, GB, DE, RU. If the country cannot be worked out, the field comes back empty. That is not an error, it is an honest "we do not know".
If no readable address reached us at all, the answer is:
{"ok":false,"err":"no_ip"}So read it in that order: check ok first, then use ip. The response is sent as application/json in utf-8 with caching turned off, so you get the current answer rather than yesterday's. Field names stay as they are. If anything new is ever added, it will sit alongside these three fields instead of replacing them, and code that already works will keep working.
Examples in curl, JavaScript, PHP and Python
Command line:
curl -s https://api.ipgeo.ru/ curl -4 -s https://api.ipgeo.ru/ # force IPv4 curl -6 -s https://api.ipgeo.ru/ # force IPv6
JavaScript, straight from a page in the browser. Calls from any site are allowed, so you do not need to route them through a server of your own:
fetch('https://api.ipgeo.ru/')
.then(r => r.json())
.then(d => {
if (d.ok) console.log(d.ip, d.country);
});PHP:
<?php
$ctx = stream_context_create(array('http' => array('timeout' => 5)));
$raw = @file_get_contents('https://api.ipgeo.ru/', false, $ctx);
$d = $raw ? json_decode($raw, true) : null;
if (!empty($d['ok'])) {
echo $d['ip'] . ' ' . $d['country'];
}Python, standard library only:
import json, urllib.request
with urllib.request.urlopen('https://api.ipgeo.ru/', timeout=5) as r:
d = json.load(r)
if d['ok']:
print(d['ip'], d['country'])In every one of these, set a short timeout – five seconds is plenty – and let a failed call be something your code shrugs off rather than a reason to stop. Networks have bad moments: show a fallback and try again later.
Showing visitors their own IP address on your site
A common job: someone writes to support and you need their IP address and country without asking them to go and look it up themselves. The request has to leave the visitor's browser – if your server makes it, you get your server's address instead.
<p>Your IP address: <span id="myip">checking...</span></p>
<script>
fetch('https://api.ipgeo.ru/')
.then(r => r.json())
.then(d => {
document.getElementById('myip').textContent = d.ok
? d.ip + ' (' + (d.country || 'country unknown') + ')'
: 'could not be determined';
})
.catch(() => {
document.getElementById('myip').textContent = 'could not be determined';
});
</script>That fallback branch is not decoration. Plenty of visitors run content blockers that cut requests to any address-lookup service, and your page should not look broken because of it.
No key, no sign-up, no ads
There is nothing to set up first: no account, no key, no signed request. There is also no dashboard, which means there is no switch anyone can flip later to cut your access off.
- requests are not tied to you and do not build up into a history – the caller's IP address is not stored and request logs are not kept;
- no ads and no third-party trackers – the answer is those three fields, with nothing mixed in;
- the country is worked out on our own server from network databases held locally, so no outside service is queried and an outage somewhere else cannot break the answer;
- calls from any site are allowed by header, and the browser's preflight OPTIONS request is answered;
- there is no hard request limit.
One thing we ask in return: hold on to the answer for a few minutes instead of calling once a second. A public IP address changes rarely. If thousands of requests a minute start arriving from one address we may slow it down, but an ordinary site or a script on your own machine will never come close to that.
What this endpoint will not tell you
The limits, stated plainly, so you do not spend an evening on something that was never going to work.
- the answer is always about the caller. A query string such as ?ip=203.0.113.10 is not supported and is simply ignored, so you cannot look up somebody else's address here;
- there is no city, no coordinates and no provider name in the response – only the IP address and the country code. The provider and the network are shown on the ipgeo.ru page itself, where a person is reading them;
- nothing marks an address as a VPN, a proxy or a shared exit. That would be guesswork, and passing guesswork off as fact would not be honest;
- the country comes from a local network database, and no database is perfect: mobile networks and recently issued ranges sometimes land in the wrong country;
- only the root path works. Any other path returns 404, on purpose, so there are no extra entry points to keep track of;
- there is no request history, so "which address did I have yesterday" is a question nobody here can answer – we do not keep it.
What people use it for, and what to check when nothing comes back
A short, key-free answer fits the places where a full geolocation database or a paid service would be overkill.
- show people their own IP address and country on your site – on a help page or in a support form, so they do not have to hunt for it;
- pick a default language, currency or pickup point by country without wiring in a paid database;
- find out which address your server or home machine goes out with – one line, nothing to install;
- see which protocol a connection really uses: if curl -6 answers with something like 2001:db8::1, IPv6 is genuinely working on your side;
- in a small monitoring script: ask once an hour and notify yourself when the address changes, which is how you spot your provider handing you a new one;
- check that a VPN or proxy is really carrying your traffic. With it on, the same request should come back with a different address and country. If the answer is unchanged, the traffic is going out directly and every site you open still sees your usual address.
If no answer arrives, work through this:
- check the address in full – https, trailing slash, no extra path;
- repeat it from the command line. If that works and the browser does not, a content blocker is the usual reason: filter lists have long cut anything that looks like an address-lookup service;
- remember that a request from your server returns your server's address, not the address of the person visiting your site. To show visitors their own address, the request must leave their browser;
- if a proxy is set in the system or inside the program itself, the request goes through it and you see its address. That is not a fault, it is exactly what happened;
- if ok comes back false, no readable address reached us. That happens with unusual proxies along the way – try another connection.
Open ipgeo.ru to see the same data in the browser – your IP address, country, provider and network, plus the WebRTC, IPv6 and time zone checks.
AnonVPN extension in Chrome Web StoreFrequently asked questions
How do I get my IP address from a script?
Make one GET request to https://api.ipgeo.ru/ and read the ip field of the JSON that comes back. From a terminal that is curl -s https://api.ipgeo.ru/; in JavaScript, PHP or Python it is a single call with no key and no headers.
Do I need a key or an account?
No. There is nothing to register and nothing to paste into your code – the endpoint answers any GET request. Because there is no account, there is also no dashboard where access could be switched off later.
Why does my server get a different IP address than my visitor?
Because the answer always describes whoever sent the request. A call made by your backend reports the backend's address. To show visitors their own address, the request has to be made by their browser, as in the JavaScript example above.
Can I look up someone else's IP address with it?
No. A parameter such as ?ip=203.0.113.10 is ignored, and the response is always about the caller. This endpoint answers the question "which address am I coming from", nothing else.
Does it return the city or the provider?
No – the JSON has only the IP address and a two-letter country code. The provider, the network and the leak checks are on the ipgeo.ru page itself, where a person is reading them.
How accurate is the country?
For home and office connections it is usually right. The country comes from a network database kept on our own server, and no such database is perfect: mobile networks and recently issued address ranges sometimes show the wrong country. If the code cannot be worked out at all, the field is left empty instead of guessing.
Does it support IPv6?
Yes. You get back whichever address the connection actually used, IPv4 or IPv6. To test one on purpose, run curl -4 or curl -6 – it is a quick way to confirm that IPv6 really works on your side.
How often can I call it, and are my requests logged?
There is no hard limit, and requests are not recorded: the caller's address is not stored, no request log is kept and there are no third-party trackers. Still, cache the answer for a few minutes rather than asking every second – a public address changes rarely.
My VPN is on, but the API still shows my usual IP address. Why?
Then that traffic is not going through the VPN. It is worth checking what it covers: a browser extension only changes what the browser sends, while other programs on the machine keep going out directly. Our own Chrome extension, AnonVPN, is one option for the browser – with it on, this request comes back with a different address, and sites you open see that one instead of yours. It is not a cloak of invisibility: your provider still handles the connection, and anything you sign in to still knows who you are.