Developer Documentation

Everything you need to integrate the IPPubblico.org free public IP API into your application. No registration, no API key, no rate limits.

✓ Free forever ✓ No API key ✓ No rate limit ✓ CORS enabled ✓ 43 languages

Quick Start 30 seconds

Make a single HTTP GET request — no authentication required:

curl
# Get your public IP as JSON
curl https://ippubblico.org/?api=1

Response:

json
{
  "status": "ok",
  "ip":     "93.45.12.88",
  "ipv4":  "93.45.12.88",
  "ipv6":  null,
  "isp":   "Fastweb SPA",
  "asn":   "AS30722",
  "tz":    "Europe/Rome",
  "dt":    "2026-05-26T14:30:00+02:00",
  "city":  "Naples",
  "region":"Campania",
  "country":"Italy",
  "lat":   40.85,
  "lon":   14.26,
  "cached":false
}
✓ That's it. No API key in headers, no OAuth flow, no registration email. Just a GET request.

Endpoints reference

Base URL https://ippubblico.org/ All endpoints respond to GET requests only.
EndpointReturnsContent-TypeDescription
GET /?api=1 JSON application/json Full data object — all available fields
GET /?text=1 text/plain text/plain IPv4 and IPv6 on two lines, or NONE
GET https://ipv4.ippubblico.org/ text/plain text/plain IPv4 address only, or NONE
GET https://ipv6.ippubblico.org/ text/plain text/plain IPv6 address only, or NONE
CORS All endpoints include Access-Control-Allow-Origin: * — safe to call from browser JavaScript on any domain.

Response Format ?api=1

FieldTypeDescription
statusstring"ok" or "partial" if geolocation failed
ipstringDetected IP — may be IPv4 or IPv6
ipv4string|nullIPv4 address if available
ipv6string|nullIPv6 address if available
ispstring|nullInternet Service Provider name
asnstring|nullAutonomous System Number, e.g. "AS3269"
tzstring|nullIANA timezone, e.g. "Europe/Rome"
dtstring|nullISO 8601 datetime in the caller's timezone
citystring|nullApproximate city name
regionstring|nullRegion / state name
countrystring|nullCountry name
latfloat|nullApproximate latitude
lonfloat|nullApproximate longitude
cachedbooltrue if served from 1-hour geolocation cache

Plain text endpoints

/?text=1 returns exactly two lines:

plain text
93.45.12.88
NONE

Line 1 = IPv4 (or NONE), Line 2 = IPv6 (or NONE). https://ipv4.ippubblico.org/ and https://ipv6.ippubblico.org/ return a single line.

Code Examples copy & paste

Python

python
import requests

r = requests.get("https://ippubblico.org/?api=1", timeout=5)
r.raise_for_status()
data = r.json()

print(data["ip"])       # "93.45.12.88"
print(data["country"]) # "Italy"
print(data["isp"])     # "Fastweb SPA"
print(data["tz"])      # "Europe/Rome"
python
import urllib.request, json

with urllib.request.urlopen("https://ippubblico.org/?api=1") as res:
    data = json.loads(res.read())

print(data["ip"], data["country"])
python — requires httpx
import asyncio, httpx

async def get_ip():
    async with httpx.AsyncClient() as client:
        r = await client.get("https://ippubblico.org/?api=1", timeout=5)
        return r.json()

data = asyncio.run(get_ip())
print(data["ip"])

Node.js

javascript — Node 18+
const res  = await fetch("https://ippubblico.org/?api=1");
const data = await res.json();

console.log(data.ip);       // "93.45.12.88"
console.log(data.country); // "Italy"
console.log(data.isp);     // "Fastweb SPA"
javascript — npm install axios
const axios = require("axios");

const { data } = await axios.get("https://ippubblico.org/?api=1");
console.log(data.ip, data.country);
javascript — no dependencies
const https = require("https");

https.get("https://ippubblico.org/?api=1", res => {
  let body = "";
  res.on("data", chunk => body += chunk);
  res.on("end", () => {
    const data = JSON.parse(body);
    console.log(data.ip, data.country);
  });
});

Browser JavaScript

javascript — works in any browser
const data = await (await fetch("https://ippubblico.org/?api=1")).json();
document.getElementById("my-ip").textContent = data.ip;

PHP

php
$ch = curl_init("https://ippubblico.org/?api=1");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 5,
    CURLOPT_USERAGENT      => "MyApp/1.0",
]);
$json = curl_exec($ch);
curl_close($ch);

$data = json_decode($json, true);
echo $data["ip"];       // "93.45.12.88"
echo $data["country"]; // "Italy"
php — allow_url_fopen must be enabled
$json = file_get_contents("https://ippubblico.org/?api=1");
$data = json_decode($json, true);
echo $data["country"];

curl

bash
# Full JSON (IPv4 + IPv6 + ISP + ASN + geolocation)
curl https://ippubblico.org/?api=1

# Plain text — IPv4 and IPv6 on two lines
curl https://ippubblico.org/?text=1

# IPv4 address only (or NONE)
curl https://ipv4.ippubblico.org/

# IPv6 address only (or NONE)
curl https://ipv6.ippubblico.org/

# Pretty print JSON with jq
curl -s https://ippubblico.org/?api=1 | jq .

Go

go
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
)

type IPData struct {
    IP      string  `json:"ip"`
    Country string  `json:"country"`
    ISP     string  `json:"isp"`
    Lat     float64 `json:"lat"`
    Lon     float64 `json:"lon"`
}

func main() {
    resp, _ := http.Get("https://ippubblico.org/?api=1")
    defer resp.Body.Close()
    var d IPData
    json.NewDecoder(resp.Body).Decode(&d)
    fmt.Println(d.IP, d.Country)
}

Use Cases real world

🌍
Geofencing & Content Localization
Automatically redirect users to the correct regional version of your site, show local prices, or restrict content to specific countries — all based on the caller's IP country.
country region lat/lon
🛡️
Fraud Detection & Risk Scoring
Cross-check the billing country against the IP country during checkout. Flag mismatches between declared location and ISP ASN. Identify data center IPs that may indicate VPN or proxy usage.
isp asn country
📡
Network Monitoring & Connectivity Check
Verify the public IP of servers, routers or IoT devices from within your infrastructure. Detect IP changes after ISP reconnects. Monitor dual-stack IPv4/IPv6 availability in real time.
ipv4 ipv6 isp
CDN & Load Balancer Routing
Use the timezone and country fields to pre-select the nearest CDN edge node or API region. Reduce latency by routing requests server-side before the user's browser makes any additional calls.
tz country lat/lon
🌐
Automatic Language & Currency Detection
Pre-select the UI language and local currency on first visit using the country field. Combine with Accept-Language header for a two-signal detection approach that covers most edge cases.
country tz
🔒
Access Control & Allowlisting
Verify that incoming API calls originate from the expected ISP or ASN. Build lightweight IP allowlists for internal tools without maintaining static IP lists — use ASN membership instead.
asn isp ipv4

Geofencing example — Python

python
import requests

# Allowed countries for your service
ALLOWED = {"Italy", "Germany", "France", "Spain"}

def check_access():
    data = requests.get("https://ippubblico.org/?api=1", timeout=5).json()
    country = data.get("country", "")
    if country not in ALLOWED:
        raise PermissionError(f"Access denied from {country}")
    return data

# Fraud detection — IP country vs billing country
def verify_checkout(billing_country: str) -> bool:
    data = requests.get("https://ippubblico.org/?api=1", timeout=5).json()
    ip_country = data.get("country", "")
    is_datacenter = data.get("asn", "").startswith(("AS14618", "AS16509", "AS15169"))
    if is_datacenter:
        return False  # AWS / GCP / Azure — likely VPN/proxy
    return ip_country == billing_country

Network monitoring — Node.js

javascript
// Poll every 60 seconds, alert on IP change
let lastIP = null;

setInterval(async () => {
  const data = await (await fetch("https://ippubblico.org/?api=1")).json();
  if (lastIP && data.ip !== lastIP) {
    console.warn(`IP changed: ${lastIP} → ${data.ip}`);
    // trigger alert, update DNS, notify team...
  }
  lastIP = data.ip;
}, 60_000);

Error Handling resilience

HTTP StatusMeaningAction
200OK — full dataUse normally
200*status: "partial" — IP detected, geolocation failedIP fields are reliable; location fields may be null
429Rate limit exceeded (if enforced in future)Retry after 60s with exponential backoff
500Server errorRetry up to 3 times, then fail gracefully
503Temporary unavailabilityRetry after 30s
python — robust wrapper
import requests, time

def get_ip_data(retries=3, timeout=5):
    for attempt in range(retries):
        try:
            r = requests.get("https://ippubblico.org/?api=1", timeout=timeout)
            r.raise_for_status()
            data = r.json()
            if data.get("status") == "partial":
                # IP ok, location fields may be null
                pass
            return data
        except (requests.RequestException, ValueError):
            if attempt == retries - 1:
                return None  # fail gracefully
            time.sleep(2 ** attempt)  # exponential backoff

Limits & Cache performance

✓ No rate limit enforced today The API is free and currently has no hard rate limit. We ask that automated systems use reasonable intervals (≥ 60 seconds for polling) to ensure availability for all users.
1-hour geolocation cache Geolocation data (country, city, ISP, ASN) is cached server-side for 1 hour per IP. The cached: true field in the JSON response indicates a cache hit. The IP address itself is always live and accurate.
⚠ Geolocation accuracy Location data is approximate — city/region level, typically within 50 km for residential connections. It is not suitable for precise location tracking, legal compliance, or surveillance purposes. ISPs using CGNAT may cause multiple users to share the same public IP.

Recommended polling intervals

Use caseRecommended interval
Dynamic IP monitoring60 seconds
Server/IoT heartbeat5 minutes
Application startup checkOnce, cache result
User session (web app)Once per session

Force IPv4 / IPv6 dual-stack

Use dedicated subdomains to force the connection protocol, regardless of your client's default stack:

SubdomainDNS recordUse case
ipv4.ippubblico.org A record only Retrieve IPv4 even on dual-stack clients
ipv6.ippubblico.org AAAA record only Retrieve IPv6 even on dual-stack clients
ippubblico.org A + AAAA OS default — usually IPv6 preferred
bash — test dual-stack
# What is my IPv4?
curl https://ipv4.ippubblico.org/

# What is my IPv6?
curl https://ipv6.ippubblico.org/

# Full JSON (uses OS default stack — usually IPv6 preferred)
curl https://ippubblico.org/?api=1

FAQ common questions

Do I need to send any headers?

No. Just make a plain GET request. No Authorization, no X-API-Key, nothing.

Will this API stay free?

The free tier will always exist. We may introduce optional paid plans for higher volume or SLA guarantees in the future, but basic access will remain free with no registration required.

Can I use this in a commercial product?

Yes. There are no restrictions on commercial use of the free API tier.

Why does my IP show the wrong city?

IP geolocation databases map IP ranges to locations based on ISP registration data, not physical device location. The displayed location is often the ISP's regional infrastructure, not your actual address. Discrepancies of 50–200 km are normal for residential connections.

What is CGNAT and does it affect the response?

Carrier-Grade NAT means your ISP shares one public IPv4 across multiple customers. If your router's "public IP" differs from what this API returns, you are behind CGNAT. The API always returns the actual public IP visible to the internet.

Is there an SDK or official library?

Not yet. The API is simple enough that the code examples above are all you need. Official client libraries for Python and Node.js are planned.

How do I report an issue or request a feature?

Use the contact form on the main site. For enterprise enquiries see the Enterprise page.