Batch processing gives you the ability to query multiple IP addresses in one HTTP request.
This is significantly faster than submitting individual queries.

The API base path is

Only POST requests are accepted.


Query parameters (such as custom fields) are appended as GET request parameters, for example:

fieldsresponse fields optional
langresponse language optional

There is no API key required.

Building a request

A request needs to formatted as a JSON array, containing up to 100 objects.

HTTP 422 Unprocessable Entity will be returned for requests containing more than the beforementioned amount.

An object can contain the following:

    "query": "IPv4/IPv6 required",
    "fields": "response fields optional",
    "lang": "response language optional"

You can also supply default values for fields and lang as GET parameters. Setting them individually, as shown above, will override the defaults.

cURL examples

curl \
--data '[{"query": ""}, {"query": ""}]'

curl \
--data '[{"query": "", "fields": "country"}, {"query": ""}]'

Quick test

You can edit this query and experiment with the options


Actual response

Returned data

The API can return the following fields and values

If you don't require all the returned fields, use the GET parameter fields to specify which data should be returned.
Separate the fields by comma (fields=status,message,query,country,city) or use a generated, numeric value (to save bandwidth)

statussuccess or failsuccessstring
messageincluded only when status is fail
Can be one of the following: private range, reserved range, invalid query
invalid querystring
continentContinent nameNorth Americastring
continentCodeTwo-letter continent codeNAstring
countryCountry nameUnited Statesstring
countryCodeTwo-letter country code ISO 3166-1 alpha-2USstring
regionRegion/state short code (FIPS or ISO)CA or 10string
cityCityMountain Viewstring
districtDistrict (subdivision of city)Old Farm Districtstring
zipZip code94043string
timezoneCity timezoneAmerica/Los_Angelesstring
currencyNational currencyUSDstring
ispISP nameGooglestring
orgOrganization nameGooglestring
asAS number and organization, separated by space (RIR). Empty for IP blocks not being announced in BGP tables.AS15169 Google Inc.string
asnameAS name (RIR). Empty for IP blocks not being announced in BGP tables.GOOGLEstring
mobileMobile (cellular) connectiontruebool
proxyProxy (anonymous)truebool
queryIP used for the query173.194.67.94string
generated fields

generated numeric


Localized city, regionName and country can be requested by setting the GET parameter lang to one of the following:

lang (ISO 639)description
enEnglish (default)
deDeutsch (German)
esEspañol (Spanish)
pt-BREspañol - Argentina (Spanish)
frFrançais (French)
ja日本語 (Japanese)
zh-CN中国 (Chinese)
ruРусский (Russian)


256-bit SSL encryption is not available for this free API. Please see our pro service.

Usage limits

This endpoint is limited to 150 HTTP requests per minute from an IP address. If you go over this limit your IP address will be blackholed. You can unban here.
The returned HTTP header X-Rl contains the number of requests remaining in the current rate limit window.

We do not allow commercial use of this endpoint. Please see our pro service for SSL access, unlimited queries and commercial support.

PHP code example

// An example script doing a batch request

// List of IP addresses to query, up to 100
$ips = ['', '', ''];

// ip-api endpoint URL
// see for documentation
$endpoint = '';

// Build the query array
$queries = array_map(function($ip) { return ['query' => $ip]; }, $ips);
$options = [
	'http' => [
		'method' => 'POST',
		'user_agent' => 'Batch-Example/1.0',
		'header' => 'Content-Type: application/json',
		'content' => json_encode($queries)
$response = file_get_contents($endpoint, false, stream_context_create($options));

// Decode the response and print it
$array = json_decode($response, true);

JavaScript code example

// An example script doing a batch request

// List of IP addresses to query, up to 100
var IPs = ["", "", ""];

// ip-api endpoint URL
// see for documentation
var endpoint = '';

// Build the query array
var queries = new Array();
IPs.forEach(function (ip) {
	queries.push({ query: ip });

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
	if (this.readyState == 4 && this.status == 200) {
		// Result array
		var response = JSON.parse(this.responseText);
		response.forEach(function (item) {
			console.log(item.query + " is in " + + ", " +; 
var data = JSON.stringify(queries);
console.log("sending:", data);'POST', '', true);