If you are a legacy GeoIP customer, please see our “What’s New in GeoIP2” document for a general overview of the changes from legacy GeoIP to GeoIP2.
Product Information
To learn more about the GeoIP2 Precision services and to purchase credits, please view our GeoIP2 Precision Services page.
Release Notes
Changes to the GeoIP2 Precision web services are documented in our release notes.
Client APIs
MaxMind APIs
If you are using one of the languages listed in the table below, we strongly encourage you to use the officially supported library. There will be no need to interface with the REST API directly.
Language or Framework | Package Repository | Documentation | Version Control |
---|---|---|---|
.NET (C#) | NuGet | GitHub Pages | GitHub |
Java | Maven Central Repository | GitHub Pages | GitHub |
JavaScript (browser) | API Docs | ||
Node.js | NPM | GitHub Pages | GitHub |
Perl (deprecated) | CPAN | MetaCPAN | GitHub |
PHP | Packagist | GitHub Pages | GitHub |
Python | PyPI | Read the Docs | GitHub |
Ruby | RubyGems | RubyDoc | GitHub |
Third-Party APIs
Language or Framework | API Name | Package Repository | Documentation | Version Control |
---|---|---|---|---|
Go | geoip2 | GoDoc | GitHub |
Per-Service URIs
The URI for each service is as specified below. Please replace
{ip_address}
with the address you are querying. All
API calls should be made with HTTP GET.
Service | URI | Content-Type |
---|---|---|
Country | https://geoip.maxmind.com/geoip/v2.1/country/{ip_address} | application/vnd.maxmind.com-country+json; charset=UTF-8; version=2.1 |
City | https://geoip.maxmind.com/geoip/v2.1/city/{ip_address} | application/vnd.maxmind.com-city+json; charset=UTF-8; version=2.1 |
Insights | https://geoip.maxmind.com/geoip/v2.1/insights/{ip_address} | application/vnd.maxmind.com-insights+json; charset=UTF-8; version=2.1 |
GeoLite2 Country | https://geolite.info/geoip/v2.1/country/{ip_address} | application/vnd.maxmind.com-country+json; charset=UTF-8; version=2.1 |
GeoLite2 City | https://geolite.info/geoip/v2.1/city/{ip_address} | application/vnd.maxmind.com-city+json; charset=UTF-8; version=2.1 |
The geoip.maxmind.com and geolite.info hostnames automatically pick the data center geographically closest to you.
IP Address
The IP address can be either an IPv4 or an IPv6 address. IPv4
addresses should be passed in the standard dotted quad form, for
example 1.2.3.4
. IPv6 addresses should be passed as
strings as well. We recommend using the canonical form as
described in RFC
5952, for example 2001:db8::1:0:0:1
, but we will
handle any valid IPv6 string representation.
You can also use the string me
as the IP address.
In this case, the record for the IP address you are querying from
will be returned. This is useful when your application does not
have easy access to its public IP address, e.g., when the system
making the query is behind a NAT.
Request Headers
The Accept
header for a request is entirely
optional. If you do include one, you must accept one of the
following:
application/json
application/vnd.maxmind.com-country+json
application/vnd.maxmind.com-country+json; charset=UTF-8; version=2.1
Substitute the appropriate service’s type for “country”. A
request for any other MIME type will result in a 415
Unsupported Media Type
error.
If you set the Accept-Charset
header in your
client code, you must accept the UTF-8
character
set. If you don’t you will receive a 406 Not
Acceptable
response, because this data is only available
in UTF-8.
Authorization/Security
The HTTP Authorization header is required for authorization. The username is your MaxMind account ID. The password is your MaxMind license key. You must be approved for a trial or GeoLite2 account, or purchase credit for use with our web services in order to receive an account ID and license key.
We use basic HTTP authentication. The APIs which require authentication are only available via HTTPS. The credentials are never transmitted unencrypted. If you attempt to access this service via HTTP, you will receive a 403 Forbidden
HTTP response.
We require TLS 1.2 or greater for all requests to our servers to keep your data secure.
Response Headers
The Content-Type
header for a successful response
varies based on the service you are using.
Errors may be returned with the Content-Type
set
to application/vnd.maxmind.com-error+json; charset=UTF-8;
version=2.1
. If this is the case, then the body of the
response contains a JSON document with two keys,
code
and error
. See the Errors section for more details.
The response will always include a Content-Length
header as well.
Response Body
All services return data as a JSON document. The document that is returned always consists of an object (aka map or hash). Each key in the object in turn maps to an object or an array of objects. The top-level structure of a document will look something like this:
{
"city": { ... },
"continent": { ... },
"country": { ... },
"location": { ... },
"postal": { ... },
"registered_country": { ... },
"represented_country": { ... },
"subdivisions": [{ ... }, ... ],
"traits": { ... },
"maxmind": { ... }
}
The exact set of top-level keys varies based on the particular GeoIP2 Precision service you are using. If a key maps to an undefined or empty value, it is not included in the JSON object. This applies both to top-level keys and the objects they map to.
The data returned in the document will be in UTF-8 encoding.
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.
Languages
Many of the objects listed below include a names
key. The value of that key is in turn an object which maps locale
codes to a name in the appropriate language and script.
Currently, this web service may return the following locale codes:
Code | Language | Notes |
---|---|---|
de | German | |
en | English | English names may still include accented characters if that is the accepted spelling in English. In other words, English does not mean ASCII. |
es | Spanish | |
fr | French | |
ja | Japanese | |
pt-BR | Brazilian Portuguese | |
ru | Russian | |
zh-CN | Chinese (Simplified) |
If an object has any name data, then en
will be
one of the keys in the names
object. No other
language is guaranteed. However, it possible that we might not
have any name data at all for a given object.
city
A JSON object containing details about the city associated with the IP address.
Included in … | ||||||
---|---|---|---|---|---|---|
Key | Value Type | Description | Country? | City? | Insights? | |
confidence | integer | A value from 0-100 representing our confidence that the city is correct. | ||||
geoname_id | integer |
A unique identifier for the city as specified by GeoNames. |
||||
names | JSON object (map) |
A map from locale codes, such as |
continent
A JSON object containing information about the continent associated with the IP address.
Included in … | ||||||
---|---|---|---|---|---|---|
Key | Value Type | Description | Country? | City? | Insights? | |
code | string (2) |
A two-character code for the continent associated with the IP address. The possible codes are:
|
||||
geoname_id | integer |
A unique identifier for the continent as specified by GeoNames. |
||||
names | JSON object (map) |
A map from locale codes, such as |
country
A JSON object containing details about the country where MaxMind believes the end user is located.
Included in … | ||||||
---|---|---|---|---|---|---|
Key | Value Type | Description | Country? | City? | Insights? | |
confidence | integer | A value from 0-100 representing our confidence that the country is correct. | ||||
geoname_id | integer |
A unique identifier for the country as specified by GeoNames. |
||||
is_in_european_union | boolean | This is true if the country is a member state of the European Union. Otherwise, the key is not included in the country object. |
||||
iso_code | string (2) | A two-character ISO 3166-1 country code for the country associated with the IP address. | ||||
names | JSON object (map) |
A map from locale codes, such as |
location
A JSON object containing specific details about the location associated with the IP address.
Included in … | ||||||
---|---|---|---|---|---|---|
Key | Value Type | Description | Country? | City? | Insights? | |
accuracy_radius | integer | The approximate accuracy radius, in kilometers, around the latitude and longitude for the geographical entity (country, subdivision, city or postal code) associated with the IP address. We have a 67% confidence that the location of the end-user falls within the area defined by the accuracy radius and the latitude and longitude coordinates. | ||||
average_income | integer | The average annual income associated with the IP address in US dollars. This is only available for IP addresses in the US. | ||||
latitude | decimal | The approximate WGS84 latitude of the postal code, city, subdivision or country associated with the IP address.* | ||||
longitude | decimal | The approximate WGS84 longitude of the postal code, city, subdivision or country associated with the IP address.* | ||||
metro_code | integer | The metro code associated with the IP address. These are only available for IP addresses in the US. | ||||
population_density | integer | The estimated number of people per square kilometer. This is only available for IP addresses in the US. | ||||
time_zone | string | The time zone associated with location, as specified by the IANA Time Zone Database, e.g., “America/New_York”. |
* The coordinates are not precise and should not be used to identify a particular street address or household. To better represent a level of accuracy, please include the accuracy_radius when displaying latitude and longitude and make it clear that the coordinates refer to a larger geographical area instead of a precise location.
postal
A JSON object containing details about the postal code associated with the IP address.
Included in … | ||||||
---|---|---|---|---|---|---|
Key | Value Type | Description | Country? | City? | Insights? | |
code | string | A postal code close to the user’s location. For the following countries, we return partial postal codes with the number of characters indicated below:
|
||||
confidence | integer | A value from 0-100 representing our confidence that the postal code is correct. |
registered_country
A JSON object containing details about the country in which the ISP has registered the IP address.
Included in … | ||||||
---|---|---|---|---|---|---|
Key | Value Type | Description | Country? | City? | Insights? | |
geoname_id | integer |
A unique identifier for the country as specified by GeoNames. |
||||
is_in_european_union | boolean | This is true if the registered country is a member state of the European Union. Otherwise, the key is not included in the registered_country object. |
||||
iso_code | string (2) | A two-character ISO 3166-1 country code for the registered country. | ||||
names | JSON object (map) |
A map from locale codes, such as |
represented_country
A JSON object containing details about the country which is represented by users of the IP address. For instance, the country represented by an overseas military base.
Included in … | ||||||
---|---|---|---|---|---|---|
Key | Value Type | Description | Country? | City? | Insights? | |
geoname_id | integer |
A unique identifier for the country as specified by GeoNames. |
||||
is_in_european_union | boolean | This is true if the represented country is a member state of the European Union. Otherwise, the key is not included in the represented_country object. |
||||
iso_code | string (2) | A two-character ISO 3166-1 country code for the represented country. | ||||
names | JSON object (map) |
A map from locale codes, such as |
||||
type | string | The type of represented country. Currently limited to military but may include other types in the future. |
subdivisions
An array of JSON objects. Each of these objects contains details about a subdivision of the country in which the IP address resides. Subdivisions are arranged from largest to smallest.
For instance, the response for Oxford in the United Kingdom
would have an object for England as the first element in
subdivisions
array and an object for Oxfordshire as
the second element. The subdivisions
array for
Minneapolis in the United States will have a single object for
Minnesota.
Included in … | ||||||
---|---|---|---|---|---|---|
Key | Value Type | Description | Country? | City? | Insights? | |
confidence | integer | A value from 0-100 representing our confidence that the region is correct. | ||||
geoname_id | integer |
A unique identifier for the region as specified by GeoNames. |
||||
iso_code | string | A string of up to three characters containing the region-portion of the ISO 3166-2 code for the region associated with the IP address. | ||||
names | JSON object (map) |
A map from locale codes, such as |
traits
A JSON object containing general traits associated with the IP address.
Included in … | ||||||
---|---|---|---|---|---|---|
Key | Value Type | Description | Country? | City? | Insights? | |
autonomous_system_number | integer | The autonomous system number associated with the IP address. | ||||
autonomous_system_organization | string | The organization associated with the registered autonomous system number for the IP address. | ||||
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”. *This field is not present in the GeoLite2 City web service. | ||||
ip_address | string | The requested IP address. | ||||
is_anonymous | boolean | This is true if the IP address belongs to any sort of anonymous network. Otherwise, the key is not included in the traits object. |
||||
is_anonymous_proxy | boolean | Deprecated. Consider using one of our anonymizer service outputs, such as is_anonymous and is_anonymous_vpn . These anonymizing service outputs are available in the GeoIP2 Anonymous IP database and the GeoIP2 Precision Insights services.
|
||||
is_anonymous_vpn | boolean | This is true if the IP address is registered to an anonymous VPN provider. Otherwise, the key is not included in the traits object.If a VPN provider does not register subnets under names associated with them, we will likely only flag their IP ranges using the is_hosting_provider flag. |
||||
is_hosting_provider | boolean | This is true if the IP address belongs to a hosting or VPN provider (see description of is_anonymous_vpn flag). Otherwise, the key is not included in the traits object. |
||||
is_public_proxy | boolean | This is true if the IP address belongs to a public proxy. Otherwise, the key is not included in the traits object. |
||||
is_residential_proxy | boolean | This is true if the IP address is on a suspected anonymizing network and belongs to a residential ISP (does not include peer-to-peer proxy IPs). Otherwise, the key is not included in the traits object. |
||||
is_satellite_provider | boolean | Deprecated. | ||||
is_tor_exit_node | boolean | This is true if the IP address is a Tor exit node. Otherwise, the key is not included in the traits object. |
||||
isp | string | The name of the ISP associated with the IP address. *This field is not present in the GeoLite2 City web service. | ||||
network | string | The network in CIDR notation associated with the record. In particular, this is the largest network where all of the fields besides ip_address have the same value. |
||||
organization | string | The name of the organization associated with the IP address. *This field is not present in the GeoLite2 City web service. | ||||
static_ip_score | decimal |
An indicator of how static or dynamic an IP address is. The value ranges from 0 to 99.99 with higher values meaning a greater static association. For example, many IP addresses with a user_type of cellular have a score under one. Broadband IPs that don’t change very often typically have a score above thirty.
This indicator can be useful for deciding whether an IP address represents the same user over time. |
||||
user_count | integer | The estimated number of users sharing the IP/network during the past 24 hours. For IPv4, the count is for the individual IP. For IPv6, the count is for the /64 network. | ||||
user_type | string |
The user type associated with the IP address. This will be one of the following values.
|
maxmind
A JSON object containing information related to your MaxMind account.
Included in … | ||||||
---|---|---|---|---|---|---|
Key | Value Type | Description | Country? | City? | Insights? | |
queries_remaining | integer | The approximate number of remaining queries available for the end point which is being called. *This field is not present in the GeoLite2 web services. |
Returned Values as Database, Map, Dict, or Hash Keys
We strongly discourage your from using a value from any
names
field as a key in a database or map/dict/hash data
structure.
These names may change between releases. Instead we recommend using one of the following:
Data object | Recommended key |
---|---|
city | geoname_id |
continent | code or geoname_id |
country, registered_country, and represented_country | iso_code or geoname_id |
postal | code |
subdivisions | iso_code or geoname_id |
Output Examples
Below is an Insights output example containing all of the possible fields. Note: This example shows sample data for illustration purposes.
{
"city": {
"confidence": 25,
"geoname_id": 54321,
"names": {
"de": "Los Angeles",
"en": "Los Angeles",
"es": "Los Ángeles",
"fr": "Los Angeles",
"ja": "ロサンゼルス市",
"pt-BR": "Los Angeles",
"ru": "Лос-Анджелес",
"zh-CN": "洛杉矶"
}
},
"continent": {
"code": "NA",
"geoname_id": 123456,
"names": {
"de": "Nordamerika",
"en": "North America",
"es": "América del Norte",
"fr": "Amérique du Nord",
"ja": "北アメリカ",
"pt-BR": "América do Norte",
"ru": "Северная Америка",
"zh-CN": "北美洲"
}
},
"country": {
"confidence": 75,
"geoname_id": 6252001,
"is_in_european_union": true,
"iso_code": "US",
"names": {
"de": "USA",
"en": "United States",
"es": "Estados Unidos",
"fr": "États-Unis",
"ja": "アメリカ合衆国",
"pt-BR": "Estados Unidos",
"ru": "США",
"zh-CN": "美国"
}
},
"location": {
"accuracy_radius": 20,
"average_income": 128321,
"latitude": 37.6293,
"longitude": -122.1163,
"metro_code": 807,
"population_density": 7122,
"time_zone": "America/Los_Angeles"
},
"postal": {
"code": "90001",
"confidence": 10
},
"registered_country": {
"geoname_id": 6252001,
"is_in_european_union": true,
"iso_code": "US",
"names": {
"de": "USA",
"en": "United States",
"es": "Estados Unidos",
"fr": "États-Unis",
"ja": "アメリカ合衆国",
"pt-BR": "Estados Unidos",
"ru": "США",
"zh-CN": "美国"
}
},
"represented_country": {
"geoname_id": 6252001,
"is_in_european_union": true,
"iso_code": "US",
"names": {
"de": "USA",
"en": "United States",
"es": "Estados Unidos",
"fr": "États-Unis",
"ja": "アメリカ合衆国",
"pt-BR": "Estados Unidos",
"ru": "США",
"zh-CN": "美国"
},
"type": "military"
},
"subdivisions": [
{
"confidence": 50,
"geoname_id": 5332921,
"iso_code": "CA",
"names": {
"de": "Kalifornien",
"en": "California",
"es": "California",
"fr": "Californie",
"ja": "カリフォルニア",
"ru": "Калифорния",
"zh-CN": "加州"
}
}
],
"traits": {
"autonomous_system_number": 1239,
"autonomous_system_organization": "Linkem IR WiMax Network",
"domain": "example.com",
"is_anonymous": true,
"is_anonymous_proxy": true,
"is_anonymous_vpn": true,
"is_hosting_provider": true,
"is_public_proxy": true,
"is_residential_proxy": true,
"is_satellite_provider": true,
"is_tor_exit_node": true,
"isp": "Linkem spa",
"ip_address": "1.2.3.4",
"network": "1.2.3.0/24",
"organization": "Linkem IR WiMax Network",
"static_ip_score": 1.5,
"user_count": 1,
"user_type": "traveler"
},
"maxmind": {
"queries_remaining": 54321
}
}
Command Line (curl) Example
The web service may be accessed using curl
, a simple
command-line HTTP client. The -u
flag is used to
pass the
HTTP basic authentication header that provides the web
service with your credentials.
Please replace {account_id}
and
{license_key}
with your account ID and
license key.
Retrieving Data for Your IP Address
curl -u "{account_id}:{license_key}" \
"https://geoip.maxmind.com/geoip/v2.1/country/me?pretty"
Retrieving Data for an Arbitrary IP Address
Replace {ip_address}
with the IP address
you wish to look up.
curl -u "{account_id}:{license_key}" \
"https://geoip.maxmind.com/geoip/v2.1/country/{ip_address}?pretty"
Please replace {account_id}
and
{license_key}
with your account ID and
license key.
Retrieving Data for Your IP Address
curl -u "{account_id}:{license_key}" \
"https://geoip.maxmind.com/geoip/v2.1/city/me?pretty"
Retrieving Data for an Arbitrary IP Address
Replace {ip_address}
with the IP address
you wish to look up.
curl -u "{account_id}:{license_key}" \
"https://geoip.maxmind.com/geoip/v2.1/city/{ip_address}?pretty"
Please replace {account_id}
and
{license_key}
with your account ID and
license key.
Retrieving Data for Your IP Address
curl -u "{account_id}:{license_key}" \
"https://geoip.maxmind.com/geoip/v2.1/insights/me?pretty"
Retrieving Data for an Arbitrary IP Address
Replace {ip_address}
with the IP address
you wish to look up.
curl -u "{account_id}:{license_key}" \
"https://geoip.maxmind.com/geoip/v2.1/insights/{ip_address}?pretty"
Please replace {account_id}
and
{license_key}
with your account ID and
license key.
Retrieving Data for Your IP Address
curl -u "{account_id}:{license_key}" \
"https://geolite.info/geoip/v2.1/country/me?pretty"
Retrieving Data for an Arbitrary IP Address
Replace {ip_address}
with the IP address
you wish to look up.
curl -u "{account_id}:{license_key}" \
"https://geolite.info/geoip/v2.1/country/{ip_address}?pretty"
Please replace {account_id}
and
{license_key}
with your account ID and
license key.
Retrieving Data for Your IP Address
curl -u "{account_id}:{license_key}" \
"https://geolite.info/geoip/v2.1/city/me?pretty"
Retrieving Data for an Arbitrary IP Address
Replace {ip_address}
with the IP address
you wish to look up.
curl -u "{account_id}:{license_key}" \
"https://geolite.info/geoip/v2.1/city/{ip_address}?pretty"
Errors
When the server returns an error (4xx or 5xx), the response
may include a JSON document in the body. This document is a
single object with the keys code
and
error
. The code
field is a static error
code for machine use. The value of any given code will never
change, though codes can be added or removed. The
error
field is a human-readable description of the
error and may change at any time.
Not all errors include a JSON body. An error in content
negotiation will not include a body, nor will many 5xx errors,
which typically happen outside of our web service request
handling code. You should check the Content-Type
type of an error response before attempting to decode the body as
JSON.
In addition to the errors documented below, client code should also be prepared to handle any valid HTTP 4xx or 5xx status code.
Code | HTTP Status | Description |
---|---|---|
IP_ADDRESS_INVALID | 400 Bad Request |
You have not supplied a valid IPv4 or IPv6 address. |
IP_ADDRESS_REQUIRED | 400 Bad Request |
You have not supplied an IP address, which is a required field. |
IP_ADDRESS_RESERVED | 400 Bad Request |
You have supplied an IP address which belongs to a reserved or private range. |
IP_ADDRESS_NOT_FOUND | 404 Not Found |
The supplied IP address is not in the database. |
AUTHORIZATION_INVALID | 401 Unauthorized |
You have supplied an invalid MaxMind account ID and/or license key in the Authorization header. |
LICENSE_KEY_REQUIRED | 401 Unauthorized |
You have not supplied a MaxMind license key in the Authorization header. |
ACCOUNT_ID_REQUIRED | 401 Unauthorized |
You have not supplied a MaxMind account ID in the Authorization header. |
INSUFFICIENT_FUNDS | 402 Payment Required |
The license key you have provided does not have sufficient funds to use this service. Please purchase more service credits. |
PERMISSION_REQUIRED | 403 Forbidden |
You do not have permission to use the service. Please contact support@maxmind.com for more information. |
(none) | 415 Unsupported Media Type |
Your request included a |
(none) | 503 Service Not Available |
There is a problem with the web service server. You can try this request again later. |
Versioning
The GeoIP2 Precision web services use two part versions. Our current release is version 2.1. The major version number will remain at 2 for the foreseeable future and will not change unless we are releasing an entirely new product (“GeoIP3”).
The minor version will only change if there are breaking changes in the web service. A breaking change is one that breaks client code that follows the documentation on this page. Breaking changes include changing the type of an existing field, deleting a field entirely, or changing URIs.
All changes to the web services will be documented in the GeoIP2 release notes, whether or not the version number is changed.
The following changes are not considered to be breaking changes and will not be accompanied by a version number change:
- Adding a new field, either at the top level of the structure or in one particular object such as the country or city. Client code should be written to allow for new fields to appear.
- Adding new values to enum fields such as
user_type
. Note that this also applies to fields such as country codes, country subdivision codes, time zones, etc. - Adding a new language for localized names. We may add additional locale codes in the future.
- Adding or removing error codes, and/or changing the body
type for an error. Client code should always check the
Content-Type
header for any error response. Client code should also be prepared to handle any valid HTTP 4xx or 5xx status code. - Adding a new service. If we add a GeoIP2 Inter-Galactic
service, we will use a new path such as
/geoip/v2.1/inter-galactic
. This should not break any existing client code.