Note: This documentation is for the GeoIP legacy services. New customers do not have access to these services. Please use the GeoIP2 Precision Web Services.
The GeoIP web services allow you to look up information about a given IP address using an HTTP-based API.
Release Notes
Changes to the GeoIP web services are documented in our release notes.
IP Geolocation Usage
IP geolocation is inherently imprecise. Locations are often near the center of the population. Any location provided by a GeoIP database should not be used to identify a particular address or household.
HTTP-based API
The HTTP API requires you to pass a set of parameters as an HTTP GET or POST. Results are returned in a simple text format documented below.
We offer several different services, each providing a different amount of information about the IP address.
All of the services take the same parameters as inputs. The only difference between them is the URI they use and the data they return. The two parameters that each service takes are the IP address to look up and your MaxMind license key.
The parameters should be passed in a query string or as a form post (application/x-www-form-urlencoded). The IP address parameter should be named i (lower case "I") and the license key should be named l (lower case "L").
The IP address should be passed as a string like "44.55.66.77" or "2001:db8::2:1".
Per-Service URIs
The URIs for each service are as follows:
Service | URI |
---|---|
Country | https://geoip.maxmind.com/v1.0/country |
City | https://geoip.maxmind.com/v1.0/city |
City/ISP/Org | https://geoip.maxmind.com/v1.0/city-isp-org |
Insights (formerly Omni) | https://geoip.maxmind.com/v1.0/insights |
The geoip.maxmind.com hostname automatically picks the data center geographically closest to you.
Security
We require TLS 1.2 or greater for HTTPS requests to our servers to keep your data secure. We also recommend you access this service via HTTPS.
Output
All services return data as a set of comma-separated fields. The ISP name, Organization name, and AS number fields are quoted, since they may contain a comma. The other fields are not escaped or quoted, but they will never contain a comma.
All strings are returned in the ISO-8859-1 encoding. This encoding is also referred to as latin1.
Included in … | ||||||
---|---|---|---|---|---|---|
Name | Type (length) | Description | Country? | City? | City/ISP/Org? | Insights (formerly Omni)? |
Accuracy radius | integer | The radius in kilometers around the specified location where the IP address is likely to be. | ||||
City name | string | The city or town name associated with the IP address. | ||||
Region code | string (2) |
A two character ISO-3166-2 code for the state/region associated with the IP address. We previously returned a FIPS 10-4 code for all countries other than the United States and Canada. See our blog post detailing changes to our legacy web services. For customers who have not yet updated their integration to reflect the changes detailed in the above blog post, we provide a CSV file which maps our region codes to region names. The columns are ISO country code, region code (FIPS or ISO), and the region name. |
||||
Region name | string | The region name associated with the IP address. | ||||
Postal code | string | The postal code associated with the IP address. These are available for some IP addresses in Australia, Canada, France, Germany, Italy, Spain, Switzerland, United Kingdom, and the US. We return the first 3 characters for Canadian postal codes. We return the first 2-4 characters (outward code) for postal codes in the United Kingdom. | ||||
Metro code | integer | The metro code associated with the IP address. These are only available for IP addresses in the US. | ||||
Area code | string |
Deprecated. This field will be empty in the updated legacy web service. See our blog post detailing changes to our legacy web services. For customers who have not yet updated their integration to reflect the changes detailed in the above blog post, this field will be the telephone area code associated with the IP address. These are only available for IP addresses in the US. This output may not reflect newer area codes. |
||||
Country code | string (2) |
A two-character ISO 3166-1 country code for the country associated with the IP address. In addition to the standard codes, we may also return one of the following:
The US country code is returned for IP addresses associated with overseas US military bases. |
||||
Country name | string | The country name associated with the IP address. | ||||
Continent code | string (2) |
A two-character code for the continent associated with the IP address. The possible codes are:
|
||||
Latitude | decimal | The approximate latitude of the location associated with the network. This value is not precise and should not be used to identify a particular address or household | ||||
Longitude | decimal | The approximate longitude of the location associated with the network. Latitude and Longitude are often near the center of population. These values are not precise and should not be used to identify a particular address or household. | ||||
Time zone | string | The time zone associated with the IP address. Time zone names are taken from the IANA time zone database. See the list of possible values. | ||||
AS number | string | The autonomous system number associated with the IP address. | ||||
User type | enum |
The user type associated with the IP address. This will be one of the following values.
|
||||
Netspeed | enum |
The network speed associated with the IP address. This can be one of the following values:
|
||||
Domain | string | The second level domain associated with the IP address. This will be something like "example.com" or "example.co.uk", not "foo.example.com". | ||||
ISP name | string | The name of the ISP associated with the IP address. | ||||
Organization name | string | The name of the organization associated with the IP address. | ||||
City confidence factor | string | A value from 0-100 representing our confidence that the city is correct. | ||||
Region confidence factor | string | A value from 0-100 representing our confidence that the region is correct. | ||||
Postal confidence factor | string | A value from 0-100 representing our confidence that the postal code is correct. | ||||
Country confidence factor | string | A value from 0-100 representing our confidence that the country is correct. | ||||
Error code | string |
If there was an error or warning with this request, this field contains an error code string. The possible error codes are:
|
Output field order
Since all output is returned as a comma separated string, the order in which fields are returned must be known in order to parse the result. If the request is successful, the error field may be omitted entirely, since it always comes last.
Service | Field Order |
---|---|
Country |
|
City |
|
City/ISP/Org |
|
Insights |
|
Client Code Examples
The examples below are all for the Insights or City/ISP/Org web services. Client code for other services will be very similar. The only differences are the URI path and the fields which are returned.
Perl
This is an example for the Insights web service.
#!/usr/bin/env perl
use strict;
use warnings;
use Encode qw( decode );
use Getopt::Long;
use LWP::UserAgent;
use Text::CSV_XS;
use URI;
use URI::QueryParam;
my @fields = qw(
country_code
country_name
region_code
region_name
city_name
latitude
longitude
metro_code
area_code
time_zone
continent_code
postal_code
isp_name
organization_name
domain
as_number
netspeed
user_type
accuracy_radius
country_confidence
city_confidence
region_confidence
postal_confidence
error
);
my $license_key = 'YOUR_LICENSE_KEY';
my $ip_address = '24.24.24.24';
GetOptions(
'license:s' => \$license_key,
'ip:s' => \$ip_address,
);
my $uri = URI->new('https://geoip.maxmind.com/v1.0/insights');
$uri->query_param( l => $license_key );
$uri->query_param( i => $ip_address );
my $ua = LWP::UserAgent->new( timeout => 5 );
my $response = $ua->get($uri);
die 'Request failed with status ' . $response->code()
unless $response->is_success();
my $csv = Text::CSV_XS->new( { binary => 1 } );
$csv->parse( decode( 'ISO-8859-1', $response->content() ) );
my %insights;
@insights{@fields} = $csv->fields();
binmode STDOUT, ':encoding(UTF-8)';
if ( defined $insights{error} && length $insights{error} ) {
die "MaxMind returned an error code for the request: $insights{error}\n";
}
else {
print "\nMaxMind Insights data for $ip_address\n\n";
for my $field (@fields) {
print sprintf( " %-20s %s\n", $field, $insights{$field} );
}
print "\n";
}
PHP
This is an example for the Insights web service.
#!/usr/bin/env php
<?php
$params = getopt('l:i:');
if (!isset($params['l'])) $params['l'] = 'YOUR_LICENSE_KEY';
if (!isset($params['i'])) $params['i'] = '24.24.24.24';
$query = 'https://geoip.maxmind.com/v1.0/insights?' . http_build_query($params);
$insights_keys =
array(
'country_code',
'country_name',
'region_code',
'region_name',
'city_name',
'latitude',
'longitude',
'metro_code',
'area_code',
'time_zone',
'continent_code',
'postal_code',
'isp_name',
'organization_name',
'domain',
'as_number',
'netspeed',
'user_type',
'accuracy_radius',
'country_confidence',
'city_confidence',
'region_confidence',
'postal_confidence',
'error'
);
$curl = curl_init();
curl_setopt_array(
$curl,
array(
CURLOPT_URL => $query,
CURLOPT_USERAGENT => 'MaxMind PHP Sample',
CURLOPT_RETURNTRANSFER => true
)
);
$resp = curl_exec($curl);
if (curl_errno($curl)) {
throw new Exception(
'GeoIP request failed with a curl_errno of '
. curl_errno($curl)
);
}
$insights_values = str_getcsv($resp);
$insights_values = array_pad($insights_values, sizeof($insights_keys), '');
$insights = array_combine($insights_keys, $insights_values);
print_r($insights);
Python 2
This is an example for the Insights web service.
#!/usr/bin/env python
import argparse
import csv
import requests
import sys
fields = ['country_code',
'country_name',
'region_code',
'region_name',
'city_name',
'latitude',
'longitude',
'metro_code',
'area_code',
'time_zone',
'continent_code',
'postal_code',
'isp_name',
'organization_name',
'domain',
'as_number',
'netspeed',
'user_type',
'accuracy_radius',
'country_confidence',
'city_confidence',
'region_confidence',
'postal_confidence',
'error']
parser = argparse.ArgumentParser(description='MaxMind Insights web service client')
parser.add_argument('--license', default='YOUR_LICENSE_KEY')
parser.add_argument('--ip', default='24.24.24.24')
args = parser.parse_args()
payload = {'l': args.license, 'i': args.ip};
response = requests.get('https://geoip.maxmind.com/v1.0/insights', params=payload)
if response.status_code != requests.codes.ok:
sys.stderr.write("Request failed with status %s\n" % response.status_code)
sys.exit(1)
reader = csv.reader([response.content])
insights = dict(zip(fields, [unicode(s, 'latin_1') for s in reader.next()]))
if len(insights['error']):
sys.stderr.write("MaxMind returned an error code for the request: %s\n" % insights['error'])
sys.exit(1)
else:
print "\nMaxMind Insights data for %s\n\n" % args.ip
for (key, val) in insights.items():
print " %-20s %s" % (key, val)
print "\n"
Python 3
This is an example for the Insights web service.
#!/usr/bin/env python
import argparse
import csv
import requests
import sys
fields = ['country_code',
'country_name',
'region_code',
'region_name',
'city_name',
'latitude',
'longitude',
'metro_code',
'area_code',
'time_zone',
'continent_code',
'postal_code',
'isp_name',
'organization_name',
'domain',
'as_number',
'netspeed',
'user_type',
'accuracy_radius',
'country_confidence',
'city_confidence',
'region_confidence',
'postal_confidence',
'error']
parser = argparse.ArgumentParser(description='MaxMind Insights web service client')
parser.add_argument('--license', default='YOUR_LICENSE_KEY')
parser.add_argument('--ip', default='24.24.24.24')
args = parser.parse_args()
payload = {'l': args.license, 'i': args.ip};
response = requests.get('https://geoip.maxmind.com/v1.0/insights', params=payload)
if response.status_code != requests.codes.ok:
sys.stderr.write("Request failed with status %s\n" % response.status_code)
sys.exit(1)
reader = csv.reader([response.text])
insights = dict(zip(fields, next(reader)))
if len(insights['error']):
sys.stderr.write("MaxMind returned an error code for the request: %s\n" % insights['error'])
sys.exit(1)
else:
print("\nMaxMind Insights data for %s\n\n" % args.ip)
for (key, val) in insights.items():
print(" %-20s %s" % (key, val))
print("\n")
Ruby 1.9
This is an example for the Insights web service.
#!/usr/bin/env ruby
require 'csv'
require 'net/http'
require 'open-uri'
require 'optparse'
require 'uri'
fields = [:country_code,
:country_name,
:region_code,
:region_name,
:city_name,
:latitude,
:longitude,
:metro_code,
:area_code,
:time_zone,
:continent_code,
:postal_code,
:isp_name,
:organization_name,
:domain,
:as_number,
:netspeed,
:user_type,
:accuracy_radius,
:country_confidence,
:city_confidence,
:region_confidence,
:postal_confidence,
:error]
options = { :license => "YOUR_LICENSE_KEY", :ip => "24.24.24.24" }
OptionParser.new { |opts|
opts.banner = "Usage: insights-geoip-ws.rb [options]"
opts.on("-l", "--license LICENSE", "MaxMind license key") do |l|
options[:license] = l
end
opts.on("-i", "--ip IPADDRESS", "IP address to look up") do |i|
options[:ip] = i
end
}.parse!
uri = URI::HTTP.build(:scheme => 'https',
:host => 'geoip.maxmind.com',
:path => '/v1.0/insights',
:query => URI.encode_www_form(:l => options[:license],
:i => options[:ip]))
response = Net::HTTP.get_response(uri)
unless response.is_a?(Net::HTTPSuccess)
abort "Request failed with status #{response.code}"
end
insights = Hash[fields.zip(response.body.encode('utf-8', 'iso-8859-1').parse_csv)]
if insights[:error]
abort "MaxMind returned an error code for the request: #{insights[:error]}"
else
puts
puts "MaxMind Insights data for #{options[:ip]}";
puts
insights.each { |key, val| printf " %-20s %s\n", key, val }
puts
end
Java
This is an example for the Insights web service.
import java.net.MalformedURLException;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class InsightsReader {
public static void main(String[] args) throws Exception {
String license_key = "YOUR_LICENSE_KEY";
String ip_address = "24.24.24.24";
String url_str = "https://geoip.maxmind.com/v1.0/insights?l=" + license_key + "&i=" + ip_address;
URL url = new URL(url_str);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String inLine;
while ((inLine = in.readLine()) != null) {
// Alternatively use a CSV parser here.
Pattern p = Pattern.compile("\"([^\"]*)\"|(?<=,|^)([^,]*)(?:,|$)");
Matcher m = p.matcher(inLine);
List<String> fields = new ArrayList<String>();
String f;
while (m.find()) {
f = m.group(1);
if (f!=null) {
fields.add(f);
}
else {
fields.add(m.group(2));
}
}
String countrycode = fields.get(0);
String countryname = fields.get(1);
String regioncode = fields.get(2);
String regionname = fields.get(3);
String city = fields.get(4);
String lat = fields.get(5);
String lon = fields.get(6);
String metrocode = fields.get(7);
String areacode = fields.get(8);
String timezone = fields.get(9);
String continent = fields.get(10);
String postalcode = fields.get(11);
String isp = fields.get(12);
String org = fields.get(13);
String domain = fields.get(14);
String asnum = fields.get(15);
String netspeed = fields.get(16);
String usertype = fields.get(17);
String accuracyradius = fields.get(18);
String countryconf = fields.get(19);
String cityconf = fields.get(20);
String regionconf = fields.get(21);
String postalconf = fields.get(22);
String error = fields.get(23);
}
in.close();
}
}
C#
This is an example for the Insights web service.
// Contributed by Gokhan Saltik
private string GetMaxMindInsightsData(string IP) {
System.Uri objUrl = new System.Uri("https://geoip.maxmind.com/v1.0/insights?l=YOUR_LICENSE_KEY&i=" + IP);
System.Net.WebRequest objWebReq;
System.Net.WebResponse objResp;
System.IO.StreamReader sReader;
string strReturn = string.Empty;
try
{
objWebReq = System.Net.WebRequest.Create(objUrl);
objResp = objWebReq.GetResponse();
sReader = new System.IO.StreamReader(objResp.GetResponseStream());
strReturn = sReader.ReadToEnd();
sReader.Close();
objResp.Close();
}
catch (Exception ex)
{
}
finally
{
objWebReq = null;
}
return strReturn;
}
VB.Net
This is an example for the City/ISP/Org web service.
' Contributed by Rubens A. Lucca
Private Function ReturnData(ByVal IP As String) As String
Dim objUrl As New System.Uri("https://geoip.maxmind.com/v.10/city-isp-org?l=YOUR_LICENSE_KEY&i=" & IP)
Dim objWebReq As System.Net.WebRequest
Dim objResp As System.Net.WebResponse
Dim sReader As System.IO.StreamReader
Dim strReturn As String
'Try to connect to the server and retrieve data.
Try
objWebReq = System.Net.WebRequest.Create(objUrl)
objResp = objWebReq.GetResponse
'Get the data and store in a return string.
sReader = New System.IO.StreamReader(objResp.GetResponseStream)
strReturn = sReader.ReadToEnd
'Close the objects.
sReader.Close()
objResp.Close()
Catch ex As Exception
Finally
objWebReq = Nothing
End Try
Return strReturn
End Function
Cold Fusion
This is an example for the City/ISP/Org web service.
<!--- contributed by reinhard jung --->
<cfhttp method="get" url="https://geoip.maxmind.com/v1.0/city-isp-org?l=LicenceKey&i=#CGI.REMOTE_ADDR#"></cfhttp>
<cfset resultMaxMind = cfhttp.FileContent>
<!--- create Array --->
<cfset qMaxMindByID = structNew()/>
<cfset qMaxMindByName = structNew()/>
<cfset thisField = "country,region,city,postal,latitude,longitude,metroCode,area,ISP,organization"/>
<cfset thisPos = 1/>
<cfset thisValue = ""/>
<cfset stringField = "false"/>
<cfloop from="1" to="#Len(resultMaxMind)#" index="mmField">
<cfif mid(resultMaxMind,mmField,1) IS ',' AND NOT stringField>
<cfset qMaxMindByID[thisPos] = thisValue>
<cfset qMaxMindByName['#ListgetAt(thisField,thisPos)#'] = thisValue>
<cfset thisPos = thisPos +1/>
<cfset thisValue = ""/>
<cfelse>
<cfif mid(resultMaxMind,mmField,1) IS '"'>
<cfset stringField = iif(stringField,"false","true")/>
<cfelse>
<cfset thisValue = thisValue &mid(resultMaxMind,mmField,1)/>
</cfif>
</cfif>
<cfif Len(resultMaxMind) EQ mmField>
<cfset qMaxMindByID[thisPos] = thisValue/>
<cfset qMaxMindByName['#ListgetAt(thisField,thisPos)#'] = thisValue>
</cfif>
</cfloop>
<!--- access Array --->
<br /><cfoutput>#qMaxMindByID[3]#</cfoutput>
<br /><cfoutput>#qMaxMindByName['city']#</cfoutput>
<!--- dump Array for overview --->
<cfdump var="#qMaxMindByID#" label="qMaxMindByID"><br />
<cfdump var="#qMaxMindByName#" label="qMaxMindByName"><br />
ASP
This is an example for the City/ISP/Org web service.
Dim objHttp, strQuery
strQuery = "https://geoip.maxmind.com/v1.0/city-isp-org?l=" & license_key & "&i=" & ipaddress
set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP")
objHttp.open "GET", strQuery, false
objHttp.send
Response.Write objHttp.ResponseText
Set objHttp = Nothing
VBScript
This is an example for the City/ISP/Org web service.
Set request = Server.CreateObject("AspHTTP.Conn")
request.Url = "https://geoip.maxmind.com/v1.0/city-isp-org?l=" & license_key & "&i=" & ip_address
request.RequestMethod = "GET"
string = request.GetURL
data = Split(string, ",")
country = arr(0)
region = arr(1)
city = arr(2)
postal = arr(3)
latitude = arr(4)
longitude = arr(5)
metro_code = arr(6)
area_code = arr(7)
isp = arr(8)
organization = arr(9)
error = arr(10)