REST API for IP intelligence — geolocation, network, timezone, currency and threat data, returned as JSON, XML or CSV.
Overview
This API is built for developers who require high performance, low latency, and production-grade reliability at scale. Our platform runs on a proprietary Anycast network with globally distributed, redundant, and self-scaling infrastructure, ensuring low-latency responses worldwide. The core is built with a highly optimized stack combining OpenResty and Rust, designed for maximum throughput and minimal overhead. IP geolocation databases are stored in a compact binary format and loaded directly into high-speed memory, enabling constant-time lookups without disk access. This in-memory architecture allows the API to process over 1 billion requests per day with consistently stable performance. Our database is updated multiple times per day and enhanced using AI-driven data aggregation and validation techniques, improving accuracy by continuously analyzing signals from multiple trusted sources. With a clean and developer-friendly interface, flexible integration options, and predictable performance under heavy load, this API is designed to integrate seamlessly into modern production environments.
Please note: The example response above includes all available fields for illustration. Actual fields may vary depending on your plan and request parameters.
Response fields
The API response contains fields based on your plan and request options. The table below lists all available response fields:
name
description
ip
IP used for the query (e.g. 8.8.4.4)
success
If the query is successful, true will be returned, and false if it fails.
message
Included only when success is false Can be one of the following: See error codes →
type
IP address type (IPv4 or IPv6)
continent
The name of the continent (e.g. North America)
continent_code
Two-letter (ISO 3166-1) continent code (e.g. NA)
country
The name of the country (e.g. United States)
country_code
Two-letter (ISO 3166-1) country code (e.g. US)
region
The name of the region/state (e.g. California)
region_code
The state/region code (ISO 3166-2), when available (e.g. CA)
city
The name of the city (e.g. Mountain View)
latitude
The approximate (WGS84) latitude of the location associated with the IP (e.g. 37.3860517)
longitude
The approximate (WGS84) longitude of the location associated with the IP (e.g. -122.0838511)
is_eu
Returns true or false depending on whether the country associated with the IP is in the European Union.
postal
The ZIP code associated with location.
calling_code
The calling/dial code of the country (e.g. 1)
capital
The capital city of the country (e.g. Washington)
borders
Two-letter (ISO 3166-1) code of the countries that border the country associated with this IP (e.g. CA,MX)
flag > img
Returns an HTTP URL leading to an SVG-flag icon for the country.
flag > emoji
An emoji version of the flag of the country (e.g. 🇺🇸)
flag > emoji_unicode
The unicode value of the emoji icon for the flag.
connection > asn
The Autonomous System (AS) Number (e.g. 15169)
connection > org
The name of the organization that owns the Autonomous System for the IP address that is analyzed (e.g. Google LLC)
connection > isp
The name of the ISP associated with the IP (e.g. Google LLC)
connection > domain
The domain name associated with the organization that owns the connection IP (e.g. google.com)
timezone > id
The ID of the time zone associated with location (e.g. America/Los_Angeles)
timezone > abbr
The Abbreviation of the Timezone (e.g. PDT)
timezone > is_dst
true or false depending on whether or not Daylight Savings have been accounted for.
timezone > offset
The offset from UTC (in seconds) for the given location (e.g. -25200 for PDT's -7h UTC offset)
timezone > utc
The UTC offset of the Timezone (e.g. -07:00)
timezone > current_time
The exact current date and time (ISO 8601 format) associated with location (e.g. 2022-04-22T14:31:48-07:00)
currency > name
The name of the currency (e.g. US Dollar)
currency > code
The 3-letter (ISO 4217) currency code (e.g. USD)
currency > symbol
The native (local) symbol of the given currency (e.g. $)
currency > plural
The plural version of the currency (e.g. US dollars)
currency > exchange_rate
The current exchange rate against the US dollar.
security > anonymous
Boolean with true value if proxy, vpn OR tor is satisfied.
security > proxy
true or false depending on whether the IP Address is a known proxy or any type.
security > vpn
Returns true when the IP address under search is used by a VPN, false otherwise.
security > tor
true or false depending on whether the IP Address is a known Tor exit node or relay.
security > hosting
true or false depending on whether the IP address is used for hosting purposes.
rate > limit
The total number of API requests that your account is limited to over the given time period (month).
rate > remaining
The number of API requests remaining in the given time period (month).
Specify response fields
You can limit the API response to specific data fields by adding the fields GET parameter to the request URL. Use a comma-separated list to request multiple fields.
For example:
fields=country,city,flag.emoji
fields=city,timezone
fields=ip,timezone.current_time
JSONP Callback
The API supports JSONP callbacks. Add the callback GET parameter to your request URL and set it to your callback function name. The JSON response will be wrapped in the specified function.
For example:
callback=getIPinfo
Localized responses
Localized city, region, country, capital and continent fields can be returned by setting the GET parameter lang to one of the following:
lang
description
demo
en
English (default)
ru
Русский (Russian)
de
Deutsch (German)
es
Español (Spanish)
pt-BR
Português - Brasil (Portuguese)
fr
Français (French)
zh-CN
中国 (Chinese)
ja
日本語 (Japanese)
Enable Threat Detection
Available in: Business and Unlimited Plan
Add security=1 to your request URL to include security signals for abuse prevention, fraud checks, and risk scoring. The response includes detection fields for anonymous traffic, proxies, VPNs, Tor, and hosting providers.
Add rate=1 to your request URL to include quota details in the JSON response, including your total limit and remaining requests. Example JSON response:
{"success":false,"message":"Bulk lookup accepts up to 100 IP addresses per request"}
401
Unauthorized
{"success":false,"message":"Invalid API key or subscription expired"}
403
Access denied
{"success":false,"message":"The current subscription plan does not support this API endpoint"}
403
Source not allowed
{"success":false,"message":"API key not allowed access from this source. Please check your API key security rules: https://ipwhois.io/dashboard/settings"}
404
URL Not Found
{"success":false,"message":"404 not found"}
405
HTTP method is not allowed
{"success":false,"message":"HTTP method is not allowed"}
414
Request-URI Too Large
{"success":false,"message":"URI Too Long"}
429
The limit has been exceeded
{"success":false,"message":"You've hit the monthly limit"}
In general, a 2xx HTTP status code indicates that the request was successfully processed.
However, in some cases the API may return a 200 OK response while indicating an application-level error in the response body. In such cases, the request was technically valid, but the operation could not be completed.
These responses include a JSON object with "success":false and an explanatory "message", for example:
import requests
ips = ['8.8.8.8', '1.1.1.1', '208.67.222.222']
url = 'https://ipwhois.pro/bulk?key=YOUR_API_KEY'response = requests.post(url, json=ips)
data = response.json()
print(data[0]['ip'], data[0]['country'], data[0]['flag']['emoji']) # Example output: 8.8.8.8 United States 🇺🇸
import org.json.JSONArray;
import java.net.URI;
import java.net.http.*;
public class Main {
public static void main(String[] args) throws Exception {
var client = HttpClient.newHttpClient();
var url = "https://ipwhois.pro/bulk?key=YOUR_API_KEY";
var body = "[\"8.8.8.8\",\"1.1.1.1\",\"208.67.222.222\"]";
var request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
var data = new JSONArray(client.send(request, HttpResponse.BodyHandlers.ofString()).body());
var first = data.getJSONObject(0);
System.out.println(first.getString("ip") + ": " + first.getString("country") + " " + first.getJSONObject("flag").getString("emoji")); // Example output: 8.8.8.8 United States 🇺🇸
}
}
require'net/http'require'json'require'uri'ips = ['8.8.8.8', '1.1.1.1', '208.67.222.222']
url = 'https://ipwhois.pro/bulk?key=YOUR_API_KEY'uri = URI(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = 'application/json'req.body = ips.to_json
res = http.request(req)
data = JSON.parse(res.body)
puts data[0]['ip'] + ': ' + data[0]['country'] + ' ' + data[0]['flag']['emoji'] # Example output: 8.8.8.8: United States 🇺🇸
import Foundation
leturl = "https://ipwhois.pro/bulk?key=YOUR_API_KEY"letips = ["8.8.8.8", "1.1.1.1", "208.67.222.222"]
varrequest = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: ips)
letsem = DispatchSemaphore(value: 0)
URLSession.shared.dataTask(with: request) { data, _, _ in
guard let data = data else { sem.signal(); return }
let json = try? JSONSerialization.jsonObject(with: data) as? [[String: Any]]
let first = json?.first
let ip = first?["ip"] as? String ?? ""
let country = first?["country"] as? String ?? ""
let flag = (first?["flag"] as? [String: Any])?["emoji"] as? String ?? ""
print(ip, country, flag) // Example output: 8.8.8.8 United States 🇺🇸
sem.signal()
}.resume()
sem.wait()
use reqwest;
use serde_json::Value;
#[tokio::main]async fnmain() -> Result<(), Box<dyn std::error::Error>> {
leturl = format!("https://ipwhois.pro/bulk?key=YOUR_API_KEY");
letips = vec!["8.8.8.8", "1.1.1.1", "208.67.222.222"];
letdata: Value = reqwest::Client::new()
.post(url)
.json(&ips)
.send().await?
.json().await?;
println!("{}: {}", data[0]["ip"], data[0]["country"]); // Example output: 8.8.8.8: United States
Ok(())
}