Developer documentation

Your IP. No credentials.

Everything you need to add IP intelligence to your application.

Free public access. No signup, API key or application quota. Respect the acceptable-use terms; availability depends on service capacity.

Make a request

Use GET /json to detect the caller, GET /json?ip=ADDRESS for a supplied address, or GET /ADDRESS/json for the path form. For only country code, region, city and timezone, use /json_lite. Both IPv4 and IPv6 literals are supported. URL-encode query values.

curl --fail "https://ip-info.com/json"
curl --fail "https://ip-info.com/json?ip=8.8.8.8"
curl --fail "https://ip-info.com/8.8.8.8/json"
curl --fail "https://ip-info.com/json?ip=2001:4860:4860::8888"

Replace https:// with http:// for HTTP access. HTTP is not redirected; HTTPS encrypts the connection. Reused HTTPS connections can avoid a fresh handshake.

JSON lookups accept only public unicast addresses. Private, loopback, multicast, documentation and other special-purpose ranges are rejected. IPv4-mapped IPv6 addresses are normalized to IPv4. Hostnames, duplicate parameters, unknown parameters and conflicting path/query IPs are rejected. Matching path/query values are accepted.

Get only your IP address

Use GET /myip for just the visitor’s IPv4 or IPv6 address, followed by a newline, with Content-Type: text/plain; charset=utf-8. No JSON wrapper or geolocation fields are included.

curl --fail https://ip-info.com/myip
8.8.8.8

The example address is illustrative. This endpoint uses the same trusted-proxy and authenticated-ingress rules as /json and reports the requesting device or proxy’s network exit. Query parameters are ignored and cannot override the caller address. It works without the geolocation database and also returns local/private caller addresses when run locally. IPv4-mapped IPv6 addresses are normalized to IPv4.

Responses use Cache-Control: no-store and support public cross-origin GET. If the caller cannot be determined or trusted-ingress headers are invalid, the response is HTTP 400 with the standard JSON error body. HEAD returns the same headers with no body.

The full JSON response

This example illustrates the response format. Live values may differ. Every listed field is present; unavailable values are null.

{
  "ip": "8.8.8.8",
  "city": "Mountain View",
  "city_geoname_id": 5375480,
  "region": "California",
  "region_code": "CA",
  "region_geoname_id": 5332921,
  "district": "Santa Clara",
  "district_code": null,
  "district_geoname_id": 5393021,
  "country": "US",
  "country_name": "United States",
  "country_geoname_id": 6252001,
  "is_eu": false,
  "continent": "NA",
  "continent_name": "North America",
  "continent_geoname_id": 6255149,
  "loc": "37.422,-122.085",
  "latitude": 37.422,
  "longitude": -122.085,
  "postal": "94043",
  "timezone": "America/Los_Angeles",
  "weather_code": "USCA0746",
  "asn": 15169,
  "as_name": "Google LLC",
  "isp": "Google LLC",
  "org": "Level 3",
  "connection_type": "Corporate",
  "user_type": "hosting",
  "is_anycast": true
}

Field reference

ipstring
Normalized public IP address that was looked up.
citystring | null
City name in English.
city_geoname_idinteger | null
City GeoNames identifier.
regionstring | null
First administrative subdivision in English.
region_codestring | null
Subdivision code as stored in the database; not prefixed with country.
region_geoname_idinteger | null
First subdivision GeoNames identifier.
districtstring | null
Second administrative subdivision in English.
district_codestring | null
Second subdivision code, where available.
district_geoname_idinteger | null
Second subdivision GeoNames identifier.
countrystring | null
Two-letter ISO country code.
country_namestring | null
Country name in English.
country_geoname_idinteger | null
Country GeoNames identifier.
is_euboolean | null
European Union membership; null means unknown.
continentstring | null
Two-letter continent code.
continent_namestring | null
Continent name in English.
continent_geoname_idinteger | null
Continent GeoNames identifier.
locstring | null
Approximate latitude,longitude pair; null if either coordinate is missing.
latitudenumber | null
Approximate latitude in decimal degrees.
longitudenumber | null
Approximate longitude in decimal degrees.
postalstring | null
Postal code, where available.
timezonestring | null
IANA time zone name.
weather_codestring | null
Nearest weather station code supplied by the database.
asninteger | null
Autonomous system number as a number, without AS prefix.
as_namestring | null
Autonomous system organization name.
ispstring | null
Internet service provider name.
orgstring | null
Organization using the IP; separate from ASN and ISP.
connection_typestring | null
Network connection classification, such as Cable/DSL, Cellular, Corporate or Dialup.
user_typestring | null
Network usage classification, such as business, residential, cellular or hosting.
is_anycastboolean | null
Anycast classification; not a VPN or proxy detection flag.

Get only the location fields

Use GET /json_lite for the caller, GET /json_lite?ip=ADDRESS for a supplied address, or GET /ADDRESS/json_lite for the path form. IPv4 and IPv6 are supported. Successful responses are compact application/json with exactly four fields: country_code, region, city and timezone.

curl --fail "https://ip-info.com/json_lite"
curl --fail "https://ip-info.com/json_lite?ip=8.8.8.8"
curl --fail "https://ip-info.com/8.8.8.8/json_lite"
curl --fail "https://ip-info.com/json_lite?ip=2001:4860:4860::8888"
{"country_code":"US","region":"California","city":"Mountain View","timezone":"America/Los_Angeles"}

This example is illustrative. Every key is present, with null for an unavailable value. country_code is the same two-letter ISO code returned as country by /json. The full response keeps its existing field names. Lite lookups use the same database, caller detection, input validation and JSON errors as full lookups. Public GET CORS, Cache-Control: no-store and HEAD requests are supported.

country_codestring | null
Two-letter ISO country code.
regionstring | null
First administrative subdivision in English.
citystring | null
City name in English.
timezonestring | null
IANA time zone name.

Use your language

curl --fail --max-time 10 "https://ip-info.com/json"

Select Full JSON or Lite JSON for each language and lookup mode. Complete examples remain available below without JavaScript. The interactive selector also offers HTTP variants.

cURL — complete examples

Detect caller IP

curl --fail --max-time 10 "https://ip-info.com/json"

Look up a supplied IP

curl --fail --max-time 10 "https://ip-info.com/json?ip=8.8.8.8"

Lite location for the caller

curl --fail --max-time 10 "https://ip-info.com/json_lite"

Lite location for a supplied IP

curl --fail --max-time 10 "https://ip-info.com/json_lite?ip=8.8.8.8"
JavaScript / Node.js — complete examples

Detect caller IP

// Node.js 18+ or a modern browser
const response = await fetch("https://ip-info.com/json", {
  signal: AbortSignal.timeout(10000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());

Look up a supplied IP

// Node.js 18+ or a modern browser
const response = await fetch("https://ip-info.com/json?ip=8.8.8.8", {
  signal: AbortSignal.timeout(10000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());

Lite location for the caller

// Node.js 18+ or a modern browser
const response = await fetch("https://ip-info.com/json_lite", {
  signal: AbortSignal.timeout(10000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());

Lite location for a supplied IP

// Node.js 18+ or a modern browser
const response = await fetch("https://ip-info.com/json_lite?ip=8.8.8.8", {
  signal: AbortSignal.timeout(10000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());
Python — complete examples

Detect caller IP

# Python 3; standard library only
import json
from urllib.request import urlopen

with urlopen("https://ip-info.com/json", timeout=10) as response:
    print(json.load(response))

Look up a supplied IP

# Python 3; standard library only
import json
from urllib.request import urlopen

with urlopen("https://ip-info.com/json?ip=8.8.8.8", timeout=10) as response:
    print(json.load(response))

Lite location for the caller

# Python 3; standard library only
import json
from urllib.request import urlopen

with urlopen("https://ip-info.com/json_lite", timeout=10) as response:
    print(json.load(response))

Lite location for a supplied IP

# Python 3; standard library only
import json
from urllib.request import urlopen

with urlopen("https://ip-info.com/json_lite?ip=8.8.8.8", timeout=10) as response:
    print(json.load(response))
PHP — complete examples

Detect caller IP

<?php
$curl = curl_init('https://ip-info.com/json');
curl_setopt_array($curl, [Chttps://ip-info.com/jsonOPT_RETURNTRANSFER => true,
    Chttps://ip-info.com/jsonOPT_TIMEOUT => 10, Chttps://ip-info.com/jsonOPT_FAILONERROR => true]);
$body = curl_exec($curl);
if ($body === false) { throw new RuntimeException(curl_error($curl)); }
curl_close($curl);
print_r(json_decode($body, true, 512, JSON_THROW_ON_ERROR));

Look up a supplied IP

<?php
$curl = curl_init('https://ip-info.com/json?ip=8.8.8.8');
curl_setopt_array($curl, [Chttps://ip-info.com/json?ip=8.8.8.8OPT_RETURNTRANSFER => true,
    Chttps://ip-info.com/json?ip=8.8.8.8OPT_TIMEOUT => 10, Chttps://ip-info.com/json?ip=8.8.8.8OPT_FAILONERROR => true]);
$body = curl_exec($curl);
if ($body === false) { throw new RuntimeException(curl_error($curl)); }
curl_close($curl);
print_r(json_decode($body, true, 512, JSON_THROW_ON_ERROR));

Lite location for the caller

<?php
$curl = curl_init('https://ip-info.com/json_lite');
curl_setopt_array($curl, [Chttps://ip-info.com/json_liteOPT_RETURNTRANSFER => true,
    Chttps://ip-info.com/json_liteOPT_TIMEOUT => 10, Chttps://ip-info.com/json_liteOPT_FAILONERROR => true]);
$body = curl_exec($curl);
if ($body === false) { throw new RuntimeException(curl_error($curl)); }
curl_close($curl);
print_r(json_decode($body, true, 512, JSON_THROW_ON_ERROR));

Lite location for a supplied IP

<?php
$curl = curl_init('https://ip-info.com/json_lite?ip=8.8.8.8');
curl_setopt_array($curl, [Chttps://ip-info.com/json_lite?ip=8.8.8.8OPT_RETURNTRANSFER => true,
    Chttps://ip-info.com/json_lite?ip=8.8.8.8OPT_TIMEOUT => 10, Chttps://ip-info.com/json_lite?ip=8.8.8.8OPT_FAILONERROR => true]);
$body = curl_exec($curl);
if ($body === false) { throw new RuntimeException(curl_error($curl)); }
curl_close($curl);
print_r(json_decode($body, true, 512, JSON_THROW_ON_ERROR));
Go — complete examples

Detect caller IP

package main

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

func main() {
    client := &http.Client{Timeout: 10 * time.Second}
    resp, err := client.Get("https://ip-info.com/json")
    if err != nil { panic(err) }
    defer resp.Body.Close()
    if resp.StatusCode != 200 { panic(resp.Status) }
    var data map[string]any
    if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { panic(err) }
    fmt.Println(data)
}

Look up a supplied IP

package main

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

func main() {
    client := &http.Client{Timeout: 10 * time.Second}
    resp, err := client.Get("https://ip-info.com/json?ip=8.8.8.8")
    if err != nil { panic(err) }
    defer resp.Body.Close()
    if resp.StatusCode != 200 { panic(resp.Status) }
    var data map[string]any
    if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { panic(err) }
    fmt.Println(data)
}

Lite location for the caller

package main

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

func main() {
    client := &http.Client{Timeout: 10 * time.Second}
    resp, err := client.Get("https://ip-info.com/json_lite")
    if err != nil { panic(err) }
    defer resp.Body.Close()
    if resp.StatusCode != 200 { panic(resp.Status) }
    var data map[string]any
    if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { panic(err) }
    fmt.Println(data)
}

Lite location for a supplied IP

package main

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

func main() {
    client := &http.Client{Timeout: 10 * time.Second}
    resp, err := client.Get("https://ip-info.com/json_lite?ip=8.8.8.8")
    if err != nil { panic(err) }
    defer resp.Body.Close()
    if resp.StatusCode != 200 { panic(resp.Status) }
    var data map[string]any
    if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { panic(err) }
    fmt.Println(data)
}
Rust — complete examples

Detect caller IP

// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
// serde_json = "1"
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = reqwest::blocking::Client::builder()
        .timeout(std::time::Duration::from_secs(10)).build()?;
    let data: serde_json::Value = client.get("https://ip-info.com/json")
        .send()?.error_for_status()?.json()?;
    println!("{data}");
    Ok(())
}

Look up a supplied IP

// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
// serde_json = "1"
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = reqwest::blocking::Client::builder()
        .timeout(std::time::Duration::from_secs(10)).build()?;
    let data: serde_json::Value = client.get("https://ip-info.com/json?ip=8.8.8.8")
        .send()?.error_for_status()?.json()?;
    println!("{data}");
    Ok(())
}

Lite location for the caller

// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
// serde_json = "1"
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = reqwest::blocking::Client::builder()
        .timeout(std::time::Duration::from_secs(10)).build()?;
    let data: serde_json::Value = client.get("https://ip-info.com/json_lite")
        .send()?.error_for_status()?.json()?;
    println!("{data}");
    Ok(())
}

Lite location for a supplied IP

// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
// serde_json = "1"
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = reqwest::blocking::Client::builder()
        .timeout(std::time::Duration::from_secs(10)).build()?;
    let data: serde_json::Value = client.get("https://ip-info.com/json_lite?ip=8.8.8.8")
        .send()?.error_for_status()?.json()?;
    println!("{data}");
    Ok(())
}
Java — complete examples

Detect caller IP

// Java 11+
import java.net.URI;
import java.net.http.*;
import java.time.Duration;

class Lookup {
    public static void main(String[] args) throws Exception {
        var request = HttpRequest.newBuilder(URI.create("https://ip-info.com/json"))
            .timeout(Duration.ofSeconds(10)).GET().build();
        var response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() != 200) throw new RuntimeException("Lookup failed");
        System.out.println(response.body());
    }
}

Look up a supplied IP

// Java 11+
import java.net.URI;
import java.net.http.*;
import java.time.Duration;

class Lookup {
    public static void main(String[] args) throws Exception {
        var request = HttpRequest.newBuilder(URI.create("https://ip-info.com/json?ip=8.8.8.8"))
            .timeout(Duration.ofSeconds(10)).GET().build();
        var response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() != 200) throw new RuntimeException("Lookup failed");
        System.out.println(response.body());
    }
}

Lite location for the caller

// Java 11+
import java.net.URI;
import java.net.http.*;
import java.time.Duration;

class Lookup {
    public static void main(String[] args) throws Exception {
        var request = HttpRequest.newBuilder(URI.create("https://ip-info.com/json_lite"))
            .timeout(Duration.ofSeconds(10)).GET().build();
        var response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() != 200) throw new RuntimeException("Lookup failed");
        System.out.println(response.body());
    }
}

Lite location for a supplied IP

// Java 11+
import java.net.URI;
import java.net.http.*;
import java.time.Duration;

class Lookup {
    public static void main(String[] args) throws Exception {
        var request = HttpRequest.newBuilder(URI.create("https://ip-info.com/json_lite?ip=8.8.8.8"))
            .timeout(Duration.ofSeconds(10)).GET().build();
        var response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() != 200) throw new RuntimeException("Lookup failed");
        System.out.println(response.body());
    }
}
C# — complete examples

Detect caller IP

// .NET 6+
using System;
using System.Net.Http;
using System.Text.Json;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };
using var response = await client.GetAsync("https://ip-info.com/json");
response.EnsureSuccessStatusCode();
using var data = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
Console.WriteLine(data.RootElement);

Look up a supplied IP

// .NET 6+
using System;
using System.Net.Http;
using System.Text.Json;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };
using var response = await client.GetAsync("https://ip-info.com/json?ip=8.8.8.8");
response.EnsureSuccessStatusCode();
using var data = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
Console.WriteLine(data.RootElement);

Lite location for the caller

// .NET 6+
using System;
using System.Net.Http;
using System.Text.Json;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };
using var response = await client.GetAsync("https://ip-info.com/json_lite");
response.EnsureSuccessStatusCode();
using var data = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
Console.WriteLine(data.RootElement);

Lite location for a supplied IP

// .NET 6+
using System;
using System.Net.Http;
using System.Text.Json;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };
using var response = await client.GetAsync("https://ip-info.com/json_lite?ip=8.8.8.8");
response.EnsureSuccessStatusCode();
using var data = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
Console.WriteLine(data.RootElement);
Ruby — complete examples

Detect caller IP

require "net/http"
require "json"

uri = URI("https://ip-info.com/json")
response = Net::HTTP.start(uri.host, uri.port,
    use_ssl: uri.scheme == "https", open_timeout: 10, read_timeout: 10) do |http|
  http.get(uri.request_uri)
end
raise "HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess)
puts JSON.parse(response.body)

Look up a supplied IP

require "net/http"
require "json"

uri = URI("https://ip-info.com/json?ip=8.8.8.8")
response = Net::HTTP.start(uri.host, uri.port,
    use_ssl: uri.scheme == "https", open_timeout: 10, read_timeout: 10) do |http|
  http.get(uri.request_uri)
end
raise "HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess)
puts JSON.parse(response.body)

Lite location for the caller

require "net/http"
require "json"

uri = URI("https://ip-info.com/json_lite")
response = Net::HTTP.start(uri.host, uri.port,
    use_ssl: uri.scheme == "https", open_timeout: 10, read_timeout: 10) do |http|
  http.get(uri.request_uri)
end
raise "HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess)
puts JSON.parse(response.body)

Lite location for a supplied IP

require "net/http"
require "json"

uri = URI("https://ip-info.com/json_lite?ip=8.8.8.8")
response = Net::HTTP.start(uri.host, uri.port,
    use_ssl: uri.scheme == "https", open_timeout: 10, read_timeout: 10) do |http|
  http.get(uri.request_uri)
end
raise "HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess)
puts JSON.parse(response.body)

Verify a Shifter proxy exit

Send the caller-detection request through your proxy to see its exit IP and database location. Replace the username and password with your own Shifter credentials; do not put credentials into the IP Info URL.

curl --fail --max-time 15 \
  --proxy http://p.shifter.io:443 \
  --proxy-user "customer-USERNAME-country-us-sid-123ABC:PASSWORD" \
  https://ip-info.com/json

Compare country with your requested country code. Different services may report different city or country values.

Errors and retries

{
  "error": {
    "code": "invalid_ip",
    "message": "Supply a literal IPv4 or IPv6 address."
  }
}
400 · invalid_ip
Malformed, conflicting, non-public, or unsupported lookup input.
404 · ip_not_found
No record in the active database.
405 · method_not_allowed
Use GET for lookups.
431 · request_too_large
Request headers exceed the configured limit.
503 · database_unavailable
Database unavailable; retry later with backoff.
504 · timeout
Request timed out; retry later with backoff.

Fix 4xx inputs before retrying. For 503/504 or connection failures, use bounded exponential backoff, for example 1, 2 and 4 seconds, then report failure. Low-level malformed HTTP may be rejected before routing.

Browser access and caching

Public GET requests allow cross-origin reads. API responses use Cache-Control: no-store; do not cache visitor-specific responses in shared caches. An HTTPS page must use HTTPS for fetch requests to avoid mixed-content blocking.

Data limitations

Coordinates are approximate. Anycast IPs may be used in many locations. ASN and ISP fields do not establish a person’s identity or prove VPN/proxy status. The first subdivision maps to region and the second to district. English names only are returned. Data may be incomplete or outdated.

Download the OpenAPI 3.1 definition or read the plain-text reference.