Introduction
The Geolocation API returns a location and accuracy radius based on information about cell towers and WiFi nodes that the mobile client can detect. This document describes the protocol used to send this data to the server and to return a response to the client.
Communication is done over HTTPS using POST. Both request and response are
formatted as JSON, and the content type of both is
application/json
.
Before you begin
Before you start developing with the Geolocation API, review the authentication requirements (you need an API key) and the API usage and billing information (you need to enable billing on your project).
Geolocation requests
Geolocation requests are sent using POST to the following URL:
https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY
You must specify a key in your request, included as the value of a
key
parameter. A key
is your application's
API key. This key identifies your application for purposes of quota
management. Learn how to get a key.
Request body
The request body must be formatted as JSON. If the request body is not included, the results will be returned based on the IP address of request location. The following fields are supported, and all fields are optional, unless otherwise stated:
Field | JSON type | Description | Notes |
---|---|---|---|
homeMobileCountryCode |
number (uint32 ) |
The mobile country code (MCC) for the device's home network. | Supported for radioType gsm (default),
wcdma , lte and nr ; not used for cdma .Valid range: 0–999. |
homeMobileNetworkCode |
number (uint32 ) |
The Mobile Network Code for the device's home network.
This is the MNC for GSM, WCDMA, LTE and NR. CDMA uses the System ID (SID) |
Valid range for MNC: 0–999. Valid range for SID: 0–32767. |
radioType |
string |
The mobile radio type. Supported values are gsm , cdma ,
wcdma , lte and nr . |
While this field is optional, it should always be included if the radio type is
known by the client. If the field is omitted, Geolocation API will default to gsm ,
which will result in invalid or zero results if the assumed radio type is
incorrect. |
carrier |
string |
The carrier name. | |
considerIp |
boolean |
Specifies whether to fall back to IP geolocation if WiFi and cell tower signals are missing, empty, or not sufficient to estimate device location. | Defaults to true . Set considerIp to false to disable
fall back. |
cellTowers |
array |
An array of cell tower objects. | See the Cell Tower Objects section below. |
wifiAccessPoints |
array |
An array of WiFi access point objects. | See the WiFi Access Point Objects section below. |
An example Geolocation API request body is shown below.
{ "homeMobileCountryCode": 310, "homeMobileNetworkCode": 410, "radioType": "gsm", "carrier": "Vodafone", "considerIp": true, "cellTowers": [ // See the Cell Tower Objects section below. ], "wifiAccessPoints": [ // See the WiFi Access Point Objects section below. ] }
Cell tower objects
The request body's cellTowers
array contains zero or more
cell tower objects.
Field | JSON type | Description | Notes |
---|---|---|---|
cellId |
number (uint32 ) |
Unique identifier of the cell. | Required for radioType gsm (default), cdma ,
wcdma and lte ; rejected for nr .See the Calculating cellId section below, which also lists the valid value ranges for each radio type. |
newRadioCellId |
number (uint64 ) |
Unique identifier of the NR (5G) cell. | Required for radioType nr ; rejected for other
types.See the Calculating newRadioCellId section below, which also lists the valid value range for the field. |
locationAreaCode |
number (uint32 ) |
The Location Area Code (LAC) for GSM and WCDMA networks. The Network ID (NID) for CDMA networks. The Tracking Area Code (TAC) for LTE and NR networks. |
Required for radioType gsm (default) and
cdma , optional for other values.Valid range with gsm , cdma , wcdma and
lte : 0–65535.Valid range with nr : 0–16777215. |
mobileCountryCode |
number (uint32 ) |
The cell tower's Mobile Country Code (MCC). | Required for radioType gsm (default), wcdma ,
lte and nr ; not used for cdma .Valid range: 0–999. |
mobileNetworkCode |
number (uint32 ) |
The cell tower's Mobile Network Code.
This is the MNC for GSM, WCDMA, LTE and NR. CDMA uses the System ID (SID). |
Required. Valid range for MNC: 0–999. Valid range for SID: 0–32767. |
The following optional fields are not currently used, but may be included if values are available.
Field | JSON type | Description | Notes |
---|---|---|---|
age |
number (uint32 ) |
The number of milliseconds since this cell was primary. | If age is 0, the cellId or newRadioCellId represents a current
measurement. |
signalStrength |
number (double ) |
Radio signal strength measured in dBm. | |
timingAdvance |
number (double ) |
The timing advance value. |
Calculating cellId
Radio types prior to NR (5G) use the 32-bit cellId
field for passing the network
cell ID to Geolocation API.
- GSM (2G) networks use the 16-bit Cell ID (CID) as is. Valid range: 0–65535.
- CDMA (2G) networks use the 16-bit Base Station ID (BID) as is. Valid range: 0–65535.
- WCDMA (3G) networks use the UTRAN/GERAN Cell Identity (UC-ID), which is a 28-bit integer
value concatenating the 12-bit Radio Network Controller Identifier (RNC-ID) and 16-bit
Cell ID (CID).
Formula:rnc_id << 16 | cid
.
Valid range: 0–268435455.
Note: Specifying only the 16-bit Cell ID value in WCDMA networks will result in incorrect or zero results. - LTE (4G) networks use the E-UTRAN Cell Identity (ECI), which is a 28-bit integer value
concatenating the 20-bit E-UTRAN Node B Identifier (eNBId) and the 8-bit Cell ID (CID).
Formula:enb_id << 8 | cid
.
Valid range: 0–268435455.
Note: Specifying only the 8-bit Cell ID value in LTE networks will result in incorrect or zero results.
Placing values outside these ranges in the API request may result in undefined behavior. The API,
at Google's discretion, may truncate the number so it fits in the documented range, infer a
correction to the radioType
, or return a NOT_FOUND
result without any
indicator in the response.
An example LTE cell tower object is below.
{ "cellTowers": [ { "cellId": 170402199, "locationAreaCode": 35632, "mobileCountryCode": 310, "mobileNetworkCode": 410, "age": 0, "signalStrength": -60, "timingAdvance": 15 } ] }
Calculating newRadioCellId
Newer networks, whose cell IDs are longer than 32 bits use the 64-bit
newRadioCellId
field for passing the network cell ID to
Geolocation API.
- NR (5G) networks use the 36-bit New Radio Cell Identity (NCI) as is.
Valid range: 0–68719476735.
An example NR cell tower object is below.
{ "cellTowers": [ { "newRadioCellId": 68719476735, "mobileCountryCode": 310, "mobileNetworkCode": 410, "age": 0, "signalStrength": -60, } ] }
WiFi access point objects
The request body's wifiAccessPoints
array must contain two
or more WiFi access point objects. macAddress
is required; all
other fields are optional.
Field | JSON type | Description | Notes |
---|---|---|---|
macAddress |
string |
The MAC address of the WiFi node. It's typically called a BSS, BSSID or MAC address. | Required. : (colon) separated hexadecimal string. |
signalStrength |
number (double ) |
The current signal strength measured in dBm. | For WiFi access points, dBm values are typically -35 or lower and range from -128 to -10 dBm. Be sure to include the minus sign. |
age |
number (uint32 ) |
The number of milliseconds since this access point was detected. | |
channel |
number (uint32 ) |
The channel over which the client is communicating with the access point. | |
signalToNoiseRatio |
number (double ) |
The current signal to noise ratio measured in dB. |
An example WiFi access point object is shown below.
{ "macAddress": "9c:1c:12:b0:45:f1", "signalStrength": -43, "signalToNoiseRatio": 0, "channel": 11, "age": 0 }
Geolocation responses
A successful geolocation request will return a JSON-formatted response defining a location and radius.
location
: The user’s estimated latitude and longitude, in degrees. Contains onelat
and onelng
subfield.accuracy
: The accuracy of the estimated location, in meters. This represents the radius of a circle around the givenlocation
.
{ "location": { "lat": 37.421875199999995, "lng": -122.0851173 }, "accuracy": 120 }
Errors
In the case of an error, a standard format error response body will be returned and the HTTP status code will be set to an error status.
The response contains an object with a single error
object with
the following keys:
code
: This is the same as the HTTP status of the response.message
: A short description of the error.errors
: A list of errors which occurred. Each error contains an identifier for the type of error (thereason
) and a short description (themessage
).
For example, sending invalid JSON will return the following error:
{ "error": { "errors": [ { "domain": "global", "reason": "parseError", "message": "Parse Error", } ], "code": 400, "message": "Parse Error" } }
Possible errors include:
Reason | Domain | HTTP Status Code | Description |
---|---|---|---|
dailyLimitExceeded |
usageLimits |
403 | You have exceeded your daily limit. |
keyInvalid |
usageLimits |
400 | Your API key is not valid for the Geolocation API. Please ensure that you've included the entire key, and that you've either purchased the API or have enabled billing and activated the API to obtain the quota at no charge. |
userRateLimitExceeded |
usageLimits |
403 | You have exceeded the request limit that you configured in the Google Cloud Console. This limit is typically set as requests per day, requests per 100 seconds, and requests per 100 seconds per user. This limit should be configured to prevent a single or small group of users from exhausting your daily quota, while still allowing reasonable access to all users. See Capping API Usage to configure these limits. |
notFound |
geolocation |
404 | The request was valid, but no results were returned. |
parseError |
global |
400 | The request body is not valid JSON. Refer to the Request Body section for details on each field. |
Sample requests
If you'd like to try the Geolocation API with sample data, save the following JSON to a file:
{ "considerIp": "false", "wifiAccessPoints": [ { "macAddress": "84:d4:7e:f6:99:64", "signalStrength": -54, "signalToNoiseRatio": 0 }, { "macAddress": "84:d4:7e:f6:99:71", "signalStrength": -43, "signalToNoiseRatio": 0 }, { "macAddress": "84:d4:7e:f7:21:35", "signalStrength": -32, "signalToNoiseRatio": 0 } ] }
You can then use cURL to make your request from the command line:
$ curl -d @your_filename.json -H "Content-Type: application/json" -i "https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY"
The response for the above Mac addresses looks like this:
{ "location": { "lat": 37.4237423, "lng": -122.0915814 }, "accuracy": 20 }
(See Get an API Key if you don't have an API key.)
For additional testing, you can gather information from your Android device using the Places SDK for Android and the Android Location APIs, and from your iOS device using the Places SDK for iOS.
Frequently asked questions
Why am I getting a very large accuracy
radius in my
Geolocation response?
If your Geolocation response shows a very high value in the
accuracy
field, the service may be geolocating based on the
request IP, instead of WiFi points or cell towers. This can happen if no
cell towers or access points are valid or recognized.
To confirm that this is the issue, set considerIp
to
false
in your request. If the response is a 404
,
you've confirmed that your wifiAccessPoints
and
cellTowers
objects could not be geolocated.