Free IP API
A free REST API for IP addresses. Get the caller's own IP as plain text or JSON, or look up the location of any IPv4 or IPv6 address. Every endpoint answers with CORS and JSONP, so it works straight from a browser. No key, no sign-up.
Your IP address, as plain text
Returns the caller's public IP (IPv4 or IPv6) as plain text. Handy in shell scripts, or any time you need your external address.
| Endpoint | Description |
|---|---|
| https://api.ip.sb/ip | Answers on both IPv4 and IPv6 |
| https://api-ipv4.ip.sb/ip | IPv4 only |
| https://api-ipv6.ip.sb/ip | IPv6 only |
In a shell script
curl ip.sb # both IPv4 and IPv6
curl ipv4.ip.sb # IPv4 only (same as: curl -4 ip.sb)
curl ipv6.ip.sb # IPv6 only (same as: curl -6 ip.sb)
#!/bin/sh
ip=$(curl -s https://api.ip.sb/ip -A My-User-Agent)
echo "My IP address is: $ip"Sample output
192.0.2.2or (on IPv6):
2001:db8::2Code examples
Fetch your public IP from the plain-text endpoint. Most HTTP libraries send a default User-Agent that the edge blocks, so each example sets a custom one. Replace My-User-Agent with your own.
Python
import requests
r = requests.get("https://api.ip.sb/ip", headers={"User-Agent": "My-User-Agent"})
print("My public IP address is:", r.text.strip())Ruby
require "net/http"
uri = URI("https://api.ip.sb/ip")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
http.get(uri.path, "User-Agent" => "My-User-Agent")
end
puts "My public IP address is: #{res.body.strip}"PHP
<?php
$context = stream_context_create(["http" => ["header" => "User-Agent: My-User-Agent"]]);
$ip = file_get_contents("https://api.ip.sb/ip", false, $context);
echo "My public IP address is: " . trim($ip);Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://api.ip.sb/ip"))
.header("User-Agent", "My-User-Agent")
.build();
var ip = client.send(request, HttpResponse.BodyHandlers.ofString()).body();
System.out.println("My public IP address is: " + ip.strip());
}
}Perl
use strict;
use warnings;
use LWP::UserAgent;
my $ua = LWP::UserAgent->new(agent => "My-User-Agent");
my $ip = $ua->get("https://api.ip.sb/ip")->decoded_content;
print "My public IP address is: $ip";C#
using var client = new HttpClient();
client.DefaultRequestHeaders.UserAgent.ParseAdd("My-User-Agent");
string ip = (await client.GetStringAsync("https://api.ip.sb/ip")).Trim();
Console.WriteLine($"My public IP address is: {ip}");Node.js
const https = require("https");
const options = { headers: { "User-Agent": "My-User-Agent" } };
https.get("https://api.ip.sb/ip", options, (res) => {
let ip = "";
res.on("data", (chunk) => (ip += chunk));
res.on("end", () => console.log("My public IP address is:", ip.trim()));
});Go
package main
import (
"io"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.ip.sb/ip", nil)
req.Header.Set("User-Agent", "My-User-Agent")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
io.Copy(os.Stdout, res.Body)
}Rust
// Cargo.toml: reqwest = { version = "0.13.4", features = ["blocking"] }
use reqwest::blocking::Client;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let ip = Client::new()
.get("https://api.ip.sb/ip")
.header("User-Agent", "My-User-Agent")
.send()?
.text()?;
println!("My public IP address is: {}", ip.trim());
Ok(())
}Your IP address, as JSON
The same address wrapped in a JSON object. Add a callback parameter to get JSONP instead.
| Endpoint | Description |
|---|---|
| https://api.ip.sb/jsonip | JSON |
| https://api.ip.sb/jsonip?callback=getip | JSONP |
Usage
<script src="https://api.ip.sb/jsonip?callback=getip"></script>
<script>
function getip(json) {
console.log("My IP address is", json.ip);
}
</script>Geolocation, as JSON
Call /geoip with no argument to locate the caller's own IP:
| Endpoint | Description |
|---|---|
| https://api.ip.sb/geoip | JSON |
| https://api.ip.sb/geoip?callback=getgeoip | JSONP |
Append any IP address to the path to locate that one instead:
| Endpoint | Description |
|---|---|
| https://api.ip.sb/geoip/172.225.7.7 | IPv4 |
| https://api.ip.sb/geoip/2a02:26f7:b38c:fff0:: | IPv6 |
Usage
<script src="https://api.ip.sb/geoip?callback=getgeoip"></script>
<script>
function getgeoip(json) {
console.log(json.country, json.latitude, json.longitude);
}
</script>Response fields
Not every field is known for every IP. Anything missing is left out of the response rather than returned empty.
| Field | Description |
|---|---|
| ip | Caller IP, or the IP you asked about |
| country_code | Two-letter ISO 3166-1 alpha-2 country code |
| country | Country name |
| region_code | State or region code (ISO 3166-2 for the US and Canada, FIPS 10-4 elsewhere) |
| region | Region name |
| city | City name |
| postal_code | Postal or ZIP code |
| continent_code | Two-letter continent code |
| latitude | Latitude |
| longitude | Longitude |
| timezone | Time zone |
| offset | UTC offset in seconds |
| asn | Autonomous System Number |
| asn_organization | Organization that holds the ASN |
| isp | ISP name |
| organization | Organization name |
Sample output
Example response:
{
"region": "New York",
"organization": "iCloud Private Relay",
"region_code": "NY",
"isp": "iCloud Private Relay",
"city": "New York",
"asn_organization": "Akamai Technologies, Inc.",
"postal_code": "10118",
"asn": 36183,
"latitude": 40.7126,
"ip": "172.225.7.7",
"continent_code": "NA",
"offset": -18000,
"country": "United States",
"timezone": "America/New_York",
"country_code": "US",
"longitude": -74.0066
}Errors
Invalid input returns HTTP 400 (Bad Request) with a JSON error body.
| HTTP | Code | Message |
|---|---|---|
| 400 | 401 | Input string is not a valid IP address |
Rate limits
The free API allows 100 requests per minute per IP address (up to 5 per second), which is plenty for personal projects and light integrations. If you need a higher limit, an API key, or you are shipping a commercial product, take a look at our plans or get in touch for a custom setup.
Credits
Geolocation data comes from MaxMind GeoIP.