GeoIP Legacy Web Services

We have implemented recent changes to our GeoIP Legacy web services in line with the retirement of GeoIP Legacy Databases. Please see our blog post for more information.
Note: This documentation is for the GeoIP legacy services. New customers do not have access to these services. Please use the GeoIP2 web services.

The GeoIP web services allow you to look up information about a given IP address using an HTTP-based API.

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:

ServiceURI
Countryhttps://geoip.maxmind.com/geoip/v1.0/country
Cityhttps://geoip.maxmind.com/geoip/v1.0/city
City/ISP/Orghttps://geoip.maxmind.com/geoip/v1.0/city-isp-org
Insights (formerly Omni)https://geoip.maxmind.com/geoip/v1.0/insights

You might also be using the original GeoIP Legacy URIs:

ServiceURI
Countryhttps://geoip.maxmind.com/a
Cityhttps://geoip.maxmind.com/b
City/ISP/Orghttps://geoip.maxmind.com/f
Insights (formerly Omni)https://geoip.maxmind.com/e

The geoip.maxmind.com hostname automatically picks the data center geographically closest to you.

Security

You must access this service via HTTPS. We require TLS 1.2 or greater for HTTPS requests to our servers to keep your data secure.

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 …
NameType (length)DescriptionCountry?City?City/ISP/Org?Insights (formerly Omni)?
Accuracy radiusintegerThe radius in kilometers around the specified location where the IP address is likely to be.YES
City namestringThe city or town name as defined by GeoNames associated with the IP address.YESYESYES
Region codestring

The 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.

YESYESYES
Region namestringThe region name as defined by GeoNames associated with the IP address.YES
Postal codestringThe 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.YESYES
Metro codeintegerThe metro code associated with the IP address. These are only available for IP addresses in the US.YESYES
Area codestring

Deprecated. This field will be empty in the updated legacy web service. See our blog post detailing changes to our legacy web services.

YESYES
Country codestring (2)

A 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:

  • A1 – an anonymous proxy.
  • A2 – a satellite provider.
  • EU – an IP in a block used by multiple European countries.
  • AP – an IP in a block used by multiple Asia/Pacific region countries.

The US country code is returned for IP addresses associated with overseas US military bases.

YESYESYESYES
Country namestringThe country name as defined by GeoNames associated with the IP address.YES
Continent codestring (2)

A two-character code for the continent associated with the IP address. The possible codes are:

  • AF – Africa
  • AN – Antarctica
  • AS – Asia
  • EU – Europe
  • NA – North America
  • OC – Oceania
  • SA – South America
YES
LatitudedecimalThe 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 householdYESYESYES
LongitudedecimalThe 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.YESYESYES
Time zonestringThe time zone associated with the IP address. Time zone names are taken from the IANA time zone database. See the list of possible values.YES
AS numberstringThe autonomous system number associated with the IP address.YES
User typeenum

The user type associated with the IP address. This will be one of the following values.

  • business
  • cafe
  • cellular
  • college
  • contentDeliveryNetwork
  • government
  • hosting
  • library
  • military
  • residential
  • router
  • school
  • searchEngineSpider
  • traveler
YES
Netspeedenum

The network speed associated with the IP address. This can be one of the following values:

  • Dialup
  • Cable/DSL
  • Corporate
  • Cellular
YES
DomainstringThe second level domain associated with the IP address. This will be something like "example.com" or "example.co.uk", not "foo.example.com".YES
ISP namestringThe name of the ISP associated with the IP address.YESYES
Organization namestringThe name of the organization associated with the IP address.YESYES
City confidence factorstringA value from 0-100 representing our confidence that the city is correct.YES
Region confidence factorstringA value from 0-100 representing our confidence that the region is correct.YES
Postal confidence factorstringA value from 0-100 representing our confidence that the postal code is correct.YES
Country confidence factorstringA value from 0-100 representing our confidence that the country is correct.YES
Error codestring

If there was an error or warning with this request, this field contains an error code string.

The possible error codes are:

  • PERMISSION_REQUIRED – This is returned if you do not have permission to use the service. Please contact our support team for more information.
  • INVALID_LICENSE_KEY – This error will be returned when the license key you pass is not a valid license key or when your account has run out of queries.
  • LICENSE_REQUIRED – The Insight service returns this instead of INVALID_LICENSE_KEY.
  • IP_NOT_FOUND – This error will be returned if the IP address it not valid, if it is not public, or if it is not in our GeoIP database. It will also be returned if you do not pass an IP address at all.
YESYESYESYES

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.

ServiceField Order
Country
  • Country code
  • Error
City
  • Country code
  • Region code
  • City name
  • Latitude
  • Longitude
  • Error
City/ISP/Org
  • Country code
  • Region code
  • City name
  • Postal code
  • Latitude
  • Longitude
  • Metro code
  • Area code
  • ISP name
  • Organization name
  • Error
Insights
  • 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 factor
  • City confidence factor
  • Region confidence factor
  • Postal confidence factor
  • Error

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.

 1#!/usr/bin/env perl
 2
 3use strict;
 4use warnings;
 5
 6use Encode qw( decode );
 7use Getopt::Long;
 8use LWP::UserAgent;
 9use Text::CSV_XS;
10use URI;
11use URI::QueryParam;
12
13my @fields = qw(
14    country_code
15    country_name
16    region_code
17    region_name
18    city_name
19    latitude
20    longitude
21    metro_code
22    area_code
23    time_zone
24    continent_code
25    postal_code
26    isp_name
27    organization_name
28    domain
29    as_number
30    netspeed
31    user_type
32    accuracy_radius
33    country_confidence
34    city_confidence
35    region_confidence
36    postal_confidence
37    error
38);
39
40my $license_key = 'YOUR_LICENSE_KEY';
41my $ip_address  = '24.24.24.24';
42
43GetOptions(
44    'license:s' => \$license_key,
45    'ip:s'      => \$ip_address,
46);
47
48my $uri = URI->new('https://geoip.maxmind.com/v1.0/insights');
49$uri->query_param( l => $license_key );
50$uri->query_param( i => $ip_address );
51
52my $ua = LWP::UserAgent->new( timeout => 5 );
53my $response = $ua->get($uri);
54
55die 'Request failed with status ' . $response->code()
56    unless $response->is_success();
57
58my $csv = Text::CSV_XS->new( { binary => 1 } );
59$csv->parse( decode( 'ISO-8859-1', $response->content() ) );
60
61my %insights;
62@insights{@fields} = $csv->fields();
63
64binmode STDOUT, ':encoding(UTF-8)';
65
66if ( defined $insights{error} && length $insights{error} ) {
67    die "MaxMind returned an error code for the request: $insights{error}\n";
68}
69else {
70    print "\nMaxMind Insights data for $ip_address\n\n";
71    for my $field (@fields) {
72        print sprintf( "  %-20s  %s\n", $field, $insights{$field} );
73    }
74    print "\n";
75}

PHP

This is an example for the Insights web service.

 1#!/usr/bin/env php
 2
 3<?php
 4
 5$params = getopt('l:i:');
 6
 7if (!isset($params['l'])) $params['l'] = 'YOUR_LICENSE_KEY';
 8if (!isset($params['i'])) $params['i'] = '24.24.24.24';
 9
10$query = 'https://geoip.maxmind.com/v1.0/insights?' . http_build_query($params);
11
12$insights_keys =
13  array(
14    'country_code',
15    'country_name',
16    'region_code',
17    'region_name',
18    'city_name',
19    'latitude',
20    'longitude',
21    'metro_code',
22    'area_code',
23    'time_zone',
24    'continent_code',
25    'postal_code',
26    'isp_name',
27    'organization_name',
28    'domain',
29    'as_number',
30    'netspeed',
31    'user_type',
32    'accuracy_radius',
33    'country_confidence',
34    'city_confidence',
35    'region_confidence',
36    'postal_confidence',
37    'error'
38    );
39
40$curl = curl_init();
41curl_setopt_array(
42    $curl,
43    array(
44        CURLOPT_URL => $query,
45        CURLOPT_USERAGENT => 'MaxMind PHP Sample',
46        CURLOPT_RETURNTRANSFER => true
47    )
48);
49
50$resp = curl_exec($curl);
51
52if (curl_errno($curl)) {
53    throw new Exception(
54        'GeoIP request failed with a curl_errno of '
55        . curl_errno($curl)
56    );
57}
58
59$insights_values = str_getcsv($resp);
60$insights_values = array_pad($insights_values, sizeof($insights_keys), '');
61$insights = array_combine($insights_keys, $insights_values);
62
63print_r($insights);

Python 2

This is an example for the Insights web service.

 1#!/usr/bin/env python
 2
 3import argparse
 4import csv
 5import requests
 6import sys
 7
 8fields = ['country_code',
 9          'country_name',
10          'region_code',
11          'region_name',
12          'city_name',
13          'latitude',
14          'longitude',
15          'metro_code',
16          'area_code',
17          'time_zone',
18          'continent_code',
19          'postal_code',
20          'isp_name',
21          'organization_name',
22          'domain',
23          'as_number',
24          'netspeed',
25          'user_type',
26          'accuracy_radius',
27          'country_confidence',
28          'city_confidence',
29          'region_confidence',
30          'postal_confidence',
31          'error']
32
33parser = argparse.ArgumentParser(description='MaxMind Insights web service client')
34parser.add_argument('--license', default='YOUR_LICENSE_KEY')
35parser.add_argument('--ip', default='24.24.24.24')
36
37args = parser.parse_args()
38
39payload = {'l': args.license, 'i': args.ip};
40response = requests.get('https://geoip.maxmind.com/v1.0/insights', params=payload)
41
42if response.status_code != requests.codes.ok:
43    sys.stderr.write("Request failed with status %s\n" % response.status_code)
44    sys.exit(1)
45
46reader = csv.reader([response.content])
47
48insights = dict(zip(fields, [unicode(s, 'latin_1') for s in reader.next()]))
49if len(insights['error']):
50    sys.stderr.write("MaxMind returned an error code for the request: %s\n" % insights['error'])
51    sys.exit(1)
52else:
53    print "\nMaxMind Insights data for %s\n\n" % args.ip
54    for (key, val) in insights.items():
55        print "  %-20s  %s" % (key, val)
56    print "\n"

Python 3

This is an example for the Insights web service.

 1#!/usr/bin/env python
 2
 3import argparse
 4import csv
 5import requests
 6import sys
 7
 8fields = ['country_code',
 9          'country_name',
10          'region_code',
11          'region_name',
12          'city_name',
13          'latitude',
14          'longitude',
15          'metro_code',
16          'area_code',
17          'time_zone',
18          'continent_code',
19          'postal_code',
20          'isp_name',
21          'organization_name',
22          'domain',
23          'as_number',
24          'netspeed',
25          'user_type',
26          'accuracy_radius',
27          'country_confidence',
28          'city_confidence',
29          'region_confidence',
30          'postal_confidence',
31          'error']
32
33parser = argparse.ArgumentParser(description='MaxMind Insights web service client')
34parser.add_argument('--license', default='YOUR_LICENSE_KEY')
35parser.add_argument('--ip', default='24.24.24.24')
36
37args = parser.parse_args()
38
39payload = {'l': args.license, 'i': args.ip};
40response = requests.get('https://geoip.maxmind.com/v1.0/insights', params=payload)
41
42if response.status_code != requests.codes.ok:
43    sys.stderr.write("Request failed with status %s\n" % response.status_code)
44    sys.exit(1)
45
46reader = csv.reader([response.text])
47
48insights = dict(zip(fields, next(reader)))
49if len(insights['error']):
50    sys.stderr.write("MaxMind returned an error code for the request: %s\n" % insights['error'])
51    sys.exit(1)
52else:
53    print("\nMaxMind Insights data for %s\n\n" % args.ip)
54    for (key, val) in insights.items():
55        print("  %-20s  %s" % (key, val))
56    print("\n")

Ruby 1.9

This is an example for the Insights web service.

 1#!/usr/bin/env ruby
 2
 3require 'csv'
 4require 'net/http'
 5require 'open-uri'
 6require 'optparse'
 7require 'uri'
 8
 9fields = [:country_code,
10          :country_name,
11          :region_code,
12          :region_name,
13          :city_name,
14          :latitude,
15          :longitude,
16          :metro_code,
17          :area_code,
18          :time_zone,
19          :continent_code,
20          :postal_code,
21          :isp_name,
22          :organization_name,
23          :domain,
24          :as_number,
25          :netspeed,
26          :user_type,
27          :accuracy_radius,
28          :country_confidence,
29          :city_confidence,
30          :region_confidence,
31          :postal_confidence,
32          :error]
33
34options = { :license => "YOUR_LICENSE_KEY", :ip => "24.24.24.24" }
35OptionParser.new { |opts|
36  opts.banner = "Usage: insights-geoip-ws.rb [options]"
37
38  opts.on("-l", "--license LICENSE", "MaxMind license key") do |l|
39    options[:license] = l
40  end
41
42  opts.on("-i", "--ip IPADDRESS", "IP address to look up") do |i|
43    options[:ip] = i
44  end
45}.parse!
46
47uri = URI::HTTP.build(:scheme => 'https',
48                      :host   => 'geoip.maxmind.com',
49                      :path   => '/v1.0/insights',
50                      :query  => URI.encode_www_form(:l => options[:license],
51                                                     :i => options[:ip]))
52
53response = Net::HTTP.get_response(uri)
54
55unless response.is_a?(Net::HTTPSuccess)
56  abort "Request failed with status #{response.code}"
57end
58
59insights = Hash[fields.zip(response.body.encode('utf-8', 'iso-8859-1').parse_csv)]
60
61if insights[:error]
62  abort "MaxMind returned an error code for the request: #{insights[:error]}"
63else
64  puts
65  puts "MaxMind Insights data for #{options[:ip]}";
66  puts
67  insights.each { |key, val| printf "  %-20s  %s\n", key, val }
68  puts
69end

Java

This is an example for the Insights web service.

 1import java.net.MalformedURLException;
 2import java.net.URL;
 3import java.io.BufferedReader;
 4import java.io.InputStreamReader;
 5import java.io.IOException;
 6import java.util.ArrayList;
 7import java.util.List;
 8import java.util.regex.Pattern;
 9import java.util.regex.Matcher;
10
11public class InsightsReader {
12    public static void main(String[] args) throws Exception {
13        String license_key = "YOUR_LICENSE_KEY";
14        String ip_address = "24.24.24.24";
15
16        String url_str = "https://geoip.maxmind.com/v1.0/insights?l=" + license_key + "&i=" + ip_address;
17
18        URL url = new URL(url_str);
19        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
20        String inLine;
21
22        while ((inLine = in.readLine()) != null) {
23            // Alternatively use a CSV parser here.
24            Pattern p = Pattern.compile("\"([^\"]*)\"|(?<=,|^)([^,]*)(?:,|$)");
25            Matcher m = p.matcher(inLine);
26
27            List<String> fields = new ArrayList<String>();
28            String f;
29            while (m.find()) {
30                f = m.group(1);
31                if (f!=null) {
32                    fields.add(f);
33                }
34                else {
35                    fields.add(m.group(2));
36                }
37            }
38
39            String countrycode = fields.get(0);
40            String countryname = fields.get(1);
41            String regioncode = fields.get(2);
42            String regionname = fields.get(3);
43            String city = fields.get(4);
44            String lat = fields.get(5);
45            String lon = fields.get(6);
46            String metrocode = fields.get(7);
47            String areacode = fields.get(8);
48            String timezone = fields.get(9);
49            String continent = fields.get(10);
50            String postalcode = fields.get(11);
51            String isp = fields.get(12);
52            String org = fields.get(13);
53            String domain = fields.get(14);
54            String asnum = fields.get(15);
55            String netspeed = fields.get(16);
56            String usertype = fields.get(17);
57            String accuracyradius = fields.get(18);
58            String countryconf = fields.get(19);
59            String cityconf = fields.get(20);
60            String regionconf = fields.get(21);
61            String postalconf = fields.get(22);
62            String error = fields.get(23);
63        }
64
65        in.close();
66    }
67}

C#

This is an example for the Insights web service.

 1// Contributed by Gokhan Saltik
 2private string GetMaxMindInsightsData(string IP) {
 3  System.Uri objUrl = new System.Uri("https://geoip.maxmind.com/v1.0/insights?l=YOUR_LICENSE_KEY&i=" + IP);
 4  System.Net.WebRequest objWebReq;
 5  System.Net.WebResponse objResp;
 6  System.IO.StreamReader sReader;
 7  string strReturn = string.Empty;
 8
 9  try
10    {
11      objWebReq = System.Net.WebRequest.Create(objUrl);
12      objResp = objWebReq.GetResponse();
13
14      sReader = new System.IO.StreamReader(objResp.GetResponseStream());
15      strReturn = sReader.ReadToEnd();
16
17      sReader.Close();
18      objResp.Close();
19    }
20  catch (Exception ex)
21    {
22    }
23  finally
24    {
25      objWebReq = null;
26    }
27
28  return strReturn;
29}

VB.Net

This is an example for the City/ISP/Org web service.

 1' Contributed by Rubens A. Lucca
 2Private Function ReturnData(ByVal IP As String) As String
 3        Dim objUrl As New System.Uri("https://geoip.maxmind.com/v.10/city-isp-org?l=YOUR_LICENSE_KEY&i=" & IP)
 4        Dim objWebReq As System.Net.WebRequest
 5        Dim objResp As System.Net.WebResponse
 6        Dim sReader As System.IO.StreamReader
 7        Dim strReturn As String
 8
 9        'Try to connect to the server and retrieve data.
10        Try
11            objWebReq = System.Net.WebRequest.Create(objUrl)
12            objResp = objWebReq.GetResponse
13
14            'Get the data and store in a return string.
15            sReader = New System.IO.StreamReader(objResp.GetResponseStream)
16            strReturn = sReader.ReadToEnd
17
18            'Close the objects.
19            sReader.Close()
20            objResp.Close()
21        Catch ex As Exception
22        Finally
23            objWebReq = Nothing
24        End Try
25
26        Return strReturn
27
28    End Function

Cold Fusion

This is an example for the City/ISP/Org web service.

 1<!--- contributed by reinhard jung --->
 2<cfhttp method="get" url="https://geoip.maxmind.com/v1.0/city-isp-org?l=LicenceKey&i=#CGI.REMOTE_ADDR#"></cfhttp>
 3<cfset resultMaxMind = cfhttp.FileContent>
 4
 5<!--- create Array --->
 6<cfset qMaxMindByID = structNew()/>
 7<cfset qMaxMindByName = structNew()/>
 8<cfset thisField = "country,region,city,postal,latitude,longitude,metroCode,area,ISP,organization"/>
 9<cfset thisPos = 1/>
10<cfset thisValue = ""/>
11<cfset stringField = "false"/>
12<cfloop from="1" to="#Len(resultMaxMind)#" index="mmField">
13        <cfif mid(resultMaxMind,mmField,1) IS ',' AND NOT stringField>
14                <cfset qMaxMindByID[thisPos] = thisValue>
15                <cfset qMaxMindByName['#ListgetAt(thisField,thisPos)#'] = thisValue>
16                <cfset thisPos = thisPos +1/>
17                <cfset thisValue = ""/>
18        <cfelse>
19                <cfif mid(resultMaxMind,mmField,1) IS '"'>
20                        <cfset stringField = iif(stringField,"false","true")/>
21                <cfelse>
22                        <cfset thisValue = thisValue &mid(resultMaxMind,mmField,1)/>
23                </cfif>
24        </cfif>
25        <cfif Len(resultMaxMind) EQ mmField>
26                <cfset qMaxMindByID[thisPos] = thisValue/>
27                <cfset qMaxMindByName['#ListgetAt(thisField,thisPos)#'] = thisValue>
28        </cfif>
29</cfloop>
30
31<!--- access Array --->
32<br /><cfoutput>#qMaxMindByID[3]#</cfoutput>
33<br /><cfoutput>#qMaxMindByName['city']#</cfoutput>
34
35<!--- dump Array for overview --->
36<cfdump var="#qMaxMindByID#" label="qMaxMindByID"><br />
37<cfdump var="#qMaxMindByName#" label="qMaxMindByName"><br />

ASP

This is an example for the City/ISP/Org web service.

1Dim objHttp, strQuery
2strQuery = "https://geoip.maxmind.com/v1.0/city-isp-org?l=" & license_key & "&i=" & ipaddress
3set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP")
4objHttp.open "GET", strQuery, false
5objHttp.send
6Response.Write objHttp.ResponseText
7Set objHttp = Nothing

VBScript

This is an example for the City/ISP/Org web service.

 1Set request = Server.CreateObject("AspHTTP.Conn")
 2request.Url = "https://geoip.maxmind.com/v1.0/city-isp-org?l=" & license_key & "&i=" & ip_address
 3request.RequestMethod = "GET"
 4string = request.GetURL
 5data = Split(string, ",")
 6country = arr(0)
 7region = arr(1)
 8city = arr(2)
 9postal = arr(3)
10latitude = arr(4)
11longitude = arr(5)
12metro_code = arr(6)
13area_code = arr(7)
14isp = arr(8)
15organization = arr(9)
16error = arr(10)