NAV
shell php python javascript

Introduction

Unwired Labs' Geolocation API locates IoT, M2M and other connected devices from visible cell towers and WiFi networks, without needing GPS.

Authentication

Each request to Unwired's APIs needs to be authenticated with an access token.

We recommend calling these APIs from your server backend rather than from public-facing code such as JavaScript running in a browser or a mobile app, since access tokens used this way are visible to anyone inspecting the request and currently have no referrer or IP restriction to limit their use elsewhere. If you need to call an API directly from a public-facing client, proxy the request through your own backend so the token itself is never exposed. Generate access tokens on your User Dashboard, create a separate token for each application, label them accordingly - e.g. "my server" - and reissue these tokens frequently to prevent misuse.

Endpoints

Unwired Labs' APIs are hosted in two regions, each with its own base URL. Choose the region that's geographically closer to your servers for minimal latency, then send requests to the endpoint for the specific API you're calling - see Available Endpoints below.

Regions

Region 1: United States (Northern Virginia)
https://us1.unwiredlabs.com

Region 2: Europe (Germany)
https://eu1.unwiredlabs.com

Available Endpoints

Replace <region> below with us1 or eu1.

Method Path Used by
POST https://<region>.unwiredlabs.com/v2/process Geolocation
GET https://<region>.unwiredlabs.com/v2/search Forward Geocoding
GET https://<region>.unwiredlabs.com/v2/reverse Reverse Geocoding
GET https://<region>.unwiredlabs.com/v2/timezone Timezone
GET https://<region>.unwiredlabs.com/v2/balance Balance

Geolocation

The Geolocation API helps developers locate IoT, M2M and other connected devices anywhere in the world without GPS. The device or client first sends the API data about which Cellular networks and WiFi networks it can see nearby. The API then uses Unwired Labs' large datasets of Cell towers, WiFi networks backed by numerous algorithms to calculate and return the device's location.

Getting Started

Integrating the Geolocation API comes down to three steps: send it what the device can see, read the location back, and decide what to do if the result isn't confident enough. Here's a walkthrough using a typical IoT tracker with a 2G (GSM) modem, which can see one serving cell tower and two neighbouring cells.

1. Pick a region and get a token

Sign up for a free token at my.unwiredlabs.com, then pick the region closest to your servers - us1 or eu1.

2. Send what the device can see

POST this request as JSON to https://<region>.unwiredlabs.com/v2/process. You only need to send the cells the device actually reports - a 2G tracker doesn't have WiFi or GPS, so this request only needs token, radio and cells:

{
  "token":"your_API_token",
  "radio":"gsm",
  "cells":[
    {"lac":7033,"cid":17811,"mcc":310,"mnc":410,"radio":"gsm"},
    {"lac":7033,"cid":17812,"mcc":310,"mnc":410,"radio":"gsm"},
    {"lac":7033,"cid":18923,"mcc":310,"mnc":410,"radio":"gsm"}
  ]
}

The first cell object should be the serving cell (the tower the device is connected to); the rest are neighbours. Always include radio on each cell - it's needed to correctly interpret values like cid and lac, which are read differently depending on radio type. See Cells for the full parameter list, including optional signal and ta values that improve accuracy if your modem exposes them.

If you're not sure where these values come from on your device, most GSM/2G modules expose them directly:

Field Typically comes from
radio The network type the modem is registered on (e.g. gsm, umts, lte) - usually available from the modem/OS alongside the network registration info
mcc / mnc The network operator's codes, often decoded from the device's IMSI or reported directly by the modem/OS
lac The Location/Tracking Area Code, available via standard AT commands (e.g. AT+CREG? / AT+CGREG?) or your OS's cell-info API
cid The Cell ID, reported alongside lac from the same source

3. Read the response

The API returns the location it calculated, along with a few fields that tell you how much to trust it:

{
  "status":"ok",
  "balance":4999,
  "lat":39.56764454,
  "lon":-105.00728197,
  "accuracy":1200
}

accuracy and fallback together tell you how much to trust a result. A result with fallback present is based on nearby cells or networks rather than the ones reported, so treat it as less precise even if accuracy looks reasonable.

4. Decide what to do with a low-confidence result

If you're seeing fallback often, or accuracy is worse than you need:

Usage

curl --request POST \
  --url https://us1.unwiredlabs.com/v2/process \
  --header 'Content-Type: application/json' \
  --data '{"token": "your_API_token","radio": "gsm","mcc": 310,"mnc": 410,"cells": [{"lac": 7033,"cid": 17811}],"wifi": [{"bssid": "00:17:c5:cd:ca:aa","channel": 11,"frequency": 2412}, {"bssid": "d8:97:ba:c2:f0:5a"}],"address": 1}'

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://us1.unwiredlabs.com/v2/process",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => array(
    "Content-Type: application/json"
  ),
  CURLOPT_POSTFIELDS => "{\"token\": \"your_API_token\",\"radio\": \"gsm\",\"mcc\": 310,\"mnc\": 410,\"cells\": [{\"lac\": 7033,\"cid\": 17811}],\"wifi\": [{\"bssid\": \"00:17:c5:cd:ca:aa\",\"channel\": 11,\"frequency\": 2412}, {\"bssid\": \"d8:97:ba:c2:f0:5a\"}],\"address\": 1}",
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}

import requests

url = "https://us1.unwiredlabs.com/v2/process"

payload = {
    "token": "your_API_token",
    "radio": "gsm",
    "mcc": 310,
    "mnc": 410,
    "cells": [{"lac": 7033, "cid": 17811}],
    "wifi": [
        {"bssid": "00:17:c5:cd:ca:aa", "channel": 11, "frequency": 2412},
        {"bssid": "d8:97:ba:c2:f0:5a"}
    ],
    "address": 1
}
response = requests.post(url, json=payload)

print(response.text)

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://us1.unwiredlabs.com/v2/process",
  "method": "POST",
  "headers": {
    "Content-Type": "application/json"
  },
  "processData": false,
  "data": "{\"token\": \"your_API_token\",\"radio\": \"gsm\",\"mcc\": 310,\"mnc\": 410,\"cells\": [{\"lac\": 7033,\"cid\": 17811}],\"wifi\": [{\"bssid\": \"00:17:c5:cd:ca:aa\",\"channel\": 11,\"frequency\": 2412}, {\"bssid\": \"d8:97:ba:c2:f0:5a\"}],\"address\": 1}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});

POST requests can be sent to the following URL:

https://us1.unwiredlabs.com/v2/process

Replace us1 with a region that's closer to your location.

Sandbox

Use the sandbox to send sample Geolocation requests.

Request

A sample JSON request body

{
   "token":"your_API_token",
   "radio":"gsm",
   "mcc":310,
   "mnc":410,
   "cells":[
      {
         "lac":7033,
         "cid":17811
      }
   ],
   "wifi":[
      {
         "bssid":"00:17:c5:cd:ca:aa",
         "channel":11,
         "frequency":2412
      },
      {
         "bssid":"d8:97:ba:c2:f0:5a"
      }
   ],
   "address":1
}

Send the following data as a POST request in the JSON format. The token parameter is always mandatory. At least one of cells, wifi, gps or ip (with ipf fallback enabled) must also be provided so the API has data to locate against - see Cells, WiFi, GPS and Fallbacks for the requirements specific to each.

Parameter Description Type           Required
token Your API token. If you don't have one, get one free here! string yes
id ID of the device, in case you are in a per-device plan. This could be any unique string such as an IMEI, IMSI, phone number or a hash of any of the previous values, etc. Maximum accepted length is 20 chars, and values should only be alphanumeric (a-z, 0-9) string no
radio Radio type of the device. Supported values are gsm, cdma, umts, lte, nbiot and nr. Always include this for accurate results - values like cid and lac are interpreted differently depending on radio type, so an omitted or wrong radio can lead to a misread cell. See Cells for per-cell usage. string no
mcc Mobile Country Code of your operator's network represented by an integer. Range: 0 to 999. An updated list of MCCs can be found here. integer no
mnc Mobile Network Code of your operator's network represented by an integer. Range: 0 to 999. On CDMA, provide the System ID or SID, with range: 1 to 32767. integer no
cells An array of cell ID objects visible to the device. Read more. array no
wifi An array of WiFi objects visible to the device. Read more. array no
ip IP address of device. Read more string no
gps An array of gps objects that contains GPS information about where the request data was scanned. Read more array no
gps_sandbox Must be set to 0 to submit data and 1 to test in sandbox. Defaults to 1. integer no
geolocation Must be used along with gps object. When set to 0, response will not include any location information and requests are not charged and do not affect balance. Defaults to 1. integer no
address The physical address of the returned location. Read more integer no
accept-language Preferred language order for showing address results. Read more string no
fallbacks An array of fallback options to enable or disable. Lets the API return a coarser location instead of failing outright when it can't locate the reported cells or networks directly. Read more array no
bt Controls how strictly locations are validated against geographic boundaries. Read more integer no
metadata Additional information about the request or response, if any, is returned if set to 1. Defaults to 0. Read more integer no

Cells

Each cells object contains information about a single Cell Tower.

GSM - GSM, EDGE, GPRS, 2G

Parameter Description Type Accepted Required
lac the Location Area Code of your operator's network. integer 0 - 65533 no
cid Cell ID integer 0 - 65535 yes
radio Radio type of the device string gsm recommended
mcc Mobile Country Code of your operator's network. integer 0 - 999 yes
mnc Mobile Network Code of your operator's network. integer 0 - 999 yes
signal Signal Strength (RSSI) integer -113 - -51 recommended
asu Arbitrary Strength Unit integer 0 - 31 no
ta Timing Advance integer 0 - 63 no
timestamp The time this Cell data was scanned, measured in milliseconds since the UNIX epoch integer no



CDMA - 1xRTT, CDMA, eHRPD, EVDO_0, EVDO_A, EVDO_B, IS95A, IS95B

Parameter Description Type Accepted Required
lac Network ID (NID). integer 0 - 65534 no
cid Base ID / Station ID integer 0 - 65535 yes
radio Radio type of the device string cdma recommended
mcc Mobile Country Code of your operator's network integer 0 - 999 yes
mnc System ID (SID) integer 1 - 32767 yes
signal Signal Strength of the radio, measured in dBm integer -100 - -75 recommended
asu Arbitrary Strength Unit measured by the mobile phone integer 1 - 16 no
timestamp The time this Cell data was scanned, measured in milliseconds since the UNIX epoch integer no



UMTS - UMTS, HSPA, HSDPA, HSPA+, HSUPA, WCDMA, 3G

Parameter Description Type Accepted Required
lac Location Area Code of your operator's network. integer 0 - 65533 no
cid Cell ID integer 0 - 268435455 yes
radio Radio type of the device string umts recommended
mcc Mobile Country Code of your operator's network. integer 0 - 999 yes
mnc Mobile Network Code of your operator's network. integer 0 - 999 yes
signal Signal Strength (RSCP) of your operator's network. integer -121 - -25 recommended
psc Primary Scrambling Code integer 0 - 511 recommended
asu Arbitrary Strength Unit measured by the mobile phone integer -5 - 91 no
timestamp The time this Cell data was scanned, measured in milliseconds since the UNIX epoch integer no



LTE - LTE, 4G, CAT-M

Parameter Description Type Accepted Required
lac Tracking Area Code of your operator's network. integer 0 - 65533 no
cid Cell ID integer 0 - 268435455 yes
radio Radio type of the device string lte recommended
mcc Mobile Country Code of your operator's network. integer 0 - 999 yes
mnc Mobile Network Code of your operator's network. integer 0 - 999 yes
signal Signal Strength (RSRP) of the radio, measured in dBm integer -137 - -45 recommended
psc Physical Cell ID on LTE integer 0 - 503 recommended
asu Arbitrary Strength Unit measured by the mobile phone integer 0 - 97 no
ta Timing Advance integer 0 - 63 no
timestamp The time this Cell data was scanned, measured in milliseconds since the UNIX epoch integer no



NB-IoT (Private Beta)

Parameter Description Type Accepted Required
lac Tracking Area Code of your operator's network. integer 0 - 65533 no
cid Cell ID integer 0 - 268435455 yes
radio Radio type of the device string nbiot recommended
mcc Mobile Country Code of your operator's network. integer 0 - 999 yes
mnc Mobile Network Code of your operator's network. integer 0 - 999 yes
signal Signal Strength (RSRP) of the radio, measured in dBm.
Currently not considered at the moment.
integer -137 - -45 no
psc Equivalent to PCI in LTE. Some devices may report
this as NCID or NB-IoT local Cell ID.
integer 0 - 503 recommended
timestamp The time this Cell data was scanned, measured in milliseconds since the UNIX epoch integer no



New Radio - NR, 5G (Public BETA)

Parameter Description Type Accepted Required
lac Tracking Area Code or TAC of your operator's network. integer 0 - 16777215 no
cid Cell ID integer 0 - 68719476735 yes
radio Radio type of the device string nr recommended
mcc Mobile Country Code of your operator's network. integer 0 - 999 yes
mnc Mobile Network Code of your operator's network. integer 0 - 999 yes
signal Signal Strength (RSRP) of the radio, measured in dBm. integer -140 - -44 no
psc Physical Cell ID or PCI. integer 0 - 1007 recommended
asu Arbitrary Strength Unit measured by the mobile phone integer 0 - 97 no
timestamp The time this Cell data was scanned, measured in milliseconds since the UNIX epoch integer no

WiFi

Each wifi object contains information about a single WiFi Access Point.

Note: WiFi positioning is enabled for eligible deployments based on region and intended use.

Parameter Description Type          
bssid Basic Service Set Identifier or MAC address of the Access Point. Typical format of a MAC address is xx-xx-xx-xx-xx-xx. However, the delimiter can be any of these when sent to the API: : or - or . string
channel Channel the WiFi network is operating in (optional) integer
frequency Frequency the WiFi network is operating in (MHz) (optional) integer
timestamp The time this WiFi data was scanned, measured in milliseconds since the UNIX epoch (optional) integer

Fallbacks

When the API can't locate the specific cells or networks a device reports, fallbacks let it return a coarser location instead of failing outright - using signals like nearby cells sharing the same LAC/TAC, or the device's IP address. They trade some accuracy for a higher chance of getting a result at all.

Parameter Description Type           Accepted Default
all Enable or disable all fallbacks. integer 0 or 1 N/A
ipf Enable IP address fallback. Specify IP address of the device in the "ip" field if it's different from the device making the API call. integer 0 or 1 0
lacf Setting this to 1 enables LAC fallback. If we are unable to locate a cell,
we will return an approximate location based on nearby cells that share the same LAC / TAC in our database. Setting this to 2 will return only a fallback location even if a more accurate location exists.
integer 0 to 2 1
scf Enable Short CID fallback. Adds support for devices
that can only see 16-bit (short) CID
of an UMTS 28-bit UTRAN CID.
integer 0 or 1 1

There are additional fallbacks and validations available for specific use-cases. Please drop our team a note to explore these.

GPS

Sample request with the gps object

{
    "cells": [{"lac": 7033, "cid": 17811, "radio": "gsm", "mcc": 310, "mnc": 410}],
    "wifi": [{"bssid": "00:17:c5:cd:ca:aa"}],
    "gps": [{
        "source": "gps",
        "lat": 39.56764858,
        "lon": -105.0073312,
        "accuracy": 30.0,
        "altitude": 100.0,
        "altitude_accuracy": 50.0,
        "speed": 10.2,
        "heading": 35.5,
        "timestamp": 1480510819000
    }],
    "gps_sandbox": 1,
    "geolocation": 0
}

Each gps object contains GPS location information about when and where the data in the request body was observed.

Parameter Description Type Required
lat The latitude of the observation (WGS 84) float yes
lon The longitude of the observation (WGS 84) float yes
accuracy The horizontal accuracy of the observed position in meters float no
altitude The altitude at which the data was observed in meters above sea-level float no
altitude_accuracy The accuracy of the altitude estimate in meters float no
speed The measured speed of the device in meters per second float no
heading The direction of travel of the device in degrees (0° - 360°) clockwise relative to true north float no
timestamp The time this GPS position was observed, measured in milliseconds since the UNIX epoch integer no

Notes

Address

The physical address of the returned location. Pass a value of 1 (default) to return address, 2 to return address components - street, city, postcode, etc - separately and 0 to suppress it. If we do not have an address for a location, the API will return Not available.

Type Accepted Default
integer 0 or 1 or 2 1

Border Threshold

The API validates location results against geographic boundaries. The border threshold parameter allows you to control how strictly this validation is applied:

Type Accepted Default
integer 0 or 1 or 2 1

Other Notes

Response

Sample JSON response:


{
"status":"ok",
"balance":0,
"lat":39.56764454,
"lon":-105.00728197,
"accuracy":10,
"address":"High Line Canal Trail, Littleton, Douglas County, Colorado, 80129, United States of America"
}

The response will be a JSON object and may contain the following elements. Every location is calculated from our large, continuously-updated database of cell and WiFi observations - use the accuracy and fallback fields below to gauge confidence in a given result.

Parameter Description
status If the request is successful, ok is returned. Otherwise error is returned
message Contains a specific error message when status is error. This field can be used for programmatic error handling. Read more
help When present, may include additional context about errors for informational purposes. This field is provided for human readability and should not be used for programmatic error handling.
balance Approximate remaining balance on the API token. Requests that return error are not charged. Use the balance endpoint for more accurate values.
balance_slots Approximate remaining balance of device slots. Requests that return error are not charged. A value of -1 indicates an error in retrieving the slots balance. Only appears for device plans.
lat The latitude representing the location
lon The longitude representing the location
accuracy The accuracy of the position is returned in meters
address The physical address of the location
address_detail The physical address of the location broken into sub-components. Read more
aged Shown when the location is based on a single measurement or those older than 90 days or is an LAC fallback
fallback Shown when the location is based on a fallback. Possible options include ipf, lacf, scf, cidf, ncf.
metadata An object that contains additional information about the request or response, if any, and is shown when metadata is set to 1 in the request. Read more

Address Detail

The API only returns components that have valid values for a location. Component town is normalized to city to make things simple. For more granular control, please use our Geocoding service - LocationIQ.

Components that would be returned are:

Metadata

Sample response with the metadata object

{
    "status": "ok",
    "balance": 266647,
    "lat": 39.56764858,
    "lon": -105.00733121,
    "accuracy": 120,
    "metadata": {
        "gps": {
            "status": "ok",
            "gps_sandbox": 0
        }
    }
}

When metadata is enabled, the Geolocation API returns additional information about the request or response. For example, when a gps object is sent in the request, the API response will look similar to the one on your right.

Errors

{
   "status": "error",
   "message": "error_message",
   "balance": 0
}

When the API encounters errors, it responds with one of the following exact error messages in the message field:

Error Details

Error Description
Token balance over; you have used up all your requests for today Daily request limit has been exceeded. Balance is reset at midnight UTC everyday (00:00 UTC), unless you are on a custom plan with a different reset schedule. You can also upgrade your plan for more requests.
Invalid token The API token is invalid or missing. Sign up at my.unwiredlabs.com to get a token.
No slots available Device slot limit has been reached on your account.
Inactive device This device has been marked as inactive on your device plan. Contact support to activate it.
WiFi access not enabled WiFi positioning is not enabled for this account. Contact support for details.
Invalid request The request is malformed or contains invalid data. Check the help field for specific details. Common causes include malformed JSON, invalid data types, or invalid parameter values.
No matches found Unable to determine a location based on the provided data. This can occur when the cells, WiFi access points, or IP address sent in the request are not found in our database, or when location results failed validation checks (such as border threshold filtering).
Internal server error An internal server error occurred. This is a temporary issue on our side, please retry the request.
Rate Limited Second You have exceeded the per-second request limit allocated to your token. Reduce your request rate and retry.

Best Practices

Geocoding

Forward Geocoding

Forward Geocoding is when you need to convert addresses (like a street address) into geographic coordinates (like latitude and longitude). You can then use these coordinates to do a number of things such as place markers on a map, calculate the distance between your office and those coordinates, send a drone over to that location, and so on.

Usage

<?php

$curl = curl_init('https://us1.unwiredlabs.com/v2/search?token=YOUR_API_TOKEN&q=SEARCH_STRING');

curl_setopt_array($curl, array(
  CURLOPT_RETURNTRANSFER    =>  true,
  CURLOPT_FOLLOWLOCATION    =>  true,
  CURLOPT_MAXREDIRS         =>  10,
  CURLOPT_TIMEOUT           =>  30,
  CURLOPT_CUSTOMREQUEST     =>  'GET',
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo 'cURL Error #:' . $err;
} else {
  echo $response;
}
import requests

url = "https://us1.unwiredlabs.com/v2/search"

data = {
    'token': 'YOUR_API_TOKEN',
    'q': 'SEARCH_STRING'
}

response = requests.get(url, params=data)

print(response.text)
curl --request GET \
  --url 'https://us1.unwiredlabs.com/v2/search?token=YOUR_API_TOKEN&q=SEARCH_STRING'
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://us1.unwiredlabs.com/v2/search?token=YOUR_API_TOKEN&q=SEARCH_STRING",
  "method": "GET"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});

GET requests can be sent to the following URL:

https://us1.unwiredlabs.com/v2/search?token=YOUR_API_TOKEN&q=SEARCH_STRING

Replace us1 with a region that's closer to your location.

Query Parameters

Name Description Required
token Authentication Token Yes
q Address which we want to search for Yes
accept-language Preferred language order for showing search results. Read more. Optional
limit Integer value to limit the number of returned results Optional
countrycodes Limit search to a list of countries. Read more. Optional
viewbox The preferred area to find search results. (left, right, top, bottom) Optional

Response

The above command returns JSON structured like this:

{
  "status": "ok",
  "balance": 5000,
  "address": [{
    "lat": "40.6892474",
    "lon": "-74.0445404280149",
    "display_name": "Statue of Liberty, Hudson River Waterfront Walkway, Jersey City, Hudson County, New Jersey, 10004, United States of America",
    "road": "Hudson River Waterfront Walkway",
    "county" : "Hudson County",
    "city": "Jersey City",
    "state": "New Jersey",
    "country": "United States of America",
    "country_code": "US",
    "postal_code": 10004
  }, {
    "lat": "41.3438648",
    "lon": "-86.3111653",
    "display_name": "Statue of Liberty, Rue Guynemer, Odéon, 6e, Paris, Île-de-France, 75006, France",
    "road": "Rue Guynemer",
    "city": "Île-de-France",
    "state": "Paris",
    "country":"France",
    "country_code" : "FR",
    "postal_code": 75006
  }]
}
Name Description
status ok on success; error on error
balance Balance left in the account
address Array of Address objects found for the search query. Read more

Reverse Geocoding

Reverse geocoding is the process of converting geographic coordinates into a human-readable address.

Usage

<?php

$curl = curl_init('https://us1.unwiredlabs.com/v2/reverse?token=YOUR_API_TOKEN&lat=LATITUDE&lon=LONGITUDE');

curl_setopt_array($curl, array(
  CURLOPT_RETURNTRANSFER    =>  true,
  CURLOPT_FOLLOWLOCATION    =>  true,
  CURLOPT_MAXREDIRS         =>  10,
  CURLOPT_TIMEOUT           =>  30,
  CURLOPT_CUSTOMREQUEST     =>  'GET',
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import requests

url = "https://us1.unwiredlabs.com/v2/reverse"

data = {
    'token': 'YOUR_API_TOKEN',
    'lat': 'LATITUDE',
    'lon': 'LONGITUDE'
}

response = requests.get(url, params=data)

print(response.text)
curl --request GET \
  --url 'https://us1.unwiredlabs.com/v2/reverse?token=YOUR_API_TOKEN&lat=LATITUDE&lon=LONGITUDE'
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://us1.unwiredlabs.com/v2/reverse?token=YOUR_API_TOKEN&lat=LATITUDE&lon=LONGITUDE",
  "method": "GET"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});

GET requests can be sent to the following URL:

https://us1.unwiredlabs.com/v2/reverse?token=YOUR_API_TOKEN&lat=LATITUDE&lon=LONGITUDE

Replace us1 with a region that's closer to your location.

Query Parameters

Name Description Required
token Authentication token Yes
lat Latitude of the location address Yes
lon Longitude of the location address Yes
zoom Zoom value lies between 0-18. Level of detail required where 0 is country and 18 is house/building Optional
accept-language Preferred language order for showing search results. Read more. Optional

Response

The above command returns JSON structured like this:

{
  "status": "ok",
  "balance": 5000,
  "address": {
    "lat": "41.3438648",
    "lon": "-86.3111653",    
    "display_name": "Southpark Lane, Littleton, Arapahoe County, Colorado, 80120, United States of America",
    "road": "Southpark Lane",
    "county": "Arapahoe County",
    "city": "Denver-Aurora-Lakewood",
    "state": "Colorado",
    "country": "United States of America",
    "country_code" : "US",
    "postal_code": 80120
  }
}
Name Description
status ok on success; error on error
balance Balance left in the account
address Address object found for the search query. Read more.

Notes

Address Object

Name Description
lat Latitude of the given location (decimal)
lon Longitude of the given location (decimal)
display_name Matched Address name for the given location
house_number House Number
road Road Name
neighbourhood Neighbourhood
suburb Suburb
city City name (normalized form of city, town, village, hamlet)
county County name (normalized form of county, state_district)
country Country name
country_code Country code
postcode Postal code

Accept Language

Preferred language order for showing search results, overrides the value specified in the Accept-Language HTTP header. Either uses standard rfc2616 accept-language string or a simple comma separated list of language codes.

Country Codes

Limit search results to a specific country (or a list of countries). Should be the ISO 3166-1 alpha-2 code. Here is a sample:

Country code Country
de Germany
gb United Kingdom
us United States of America

Errors

{
  "status": "error",
  "message": "Error message"
}

When certain types of errors are encountered, the API responds with one of the following error messages:

Error Message Description
INVALID_TOKEN The user's token set is not valid or missing
INACTIVE_TOKEN The user's token is not active
INVALID_REQUEST The request does not contain the required input in the specified format
RATELIMITED_DAY The user has reached the daily limit allocated
RATELIMITED_MINUTE The user has reached the per-minute limit allocated
RATELIMITED_SECOND The user has reached the per-second limit allocated
NO_MATCHES The request is valid and we could not find a proper result
UNKNOWN_ERROR Due to a server error, we are unable to serve your request. You can retry this request.

Timezone

The Unwired Labs TimeZone API provides time offset data for locations on the surface of the earth.

Usage

GET requests can be sent to the following URL:

https://us1.unwiredlabs.com/v2/timezone?token=YOUR_API_TOKEN&lat=LATITUDE&lon=LONGITUDE

Replace us1 with a region that's closer to your location.

Query Parameters

<?php

$curl = curl_init('https://us1.unwiredlabs.com/v2/timezone?token=YOUR_API_TOKEN&lat=LATITUDE&lon=LONGITUDE');

curl_setopt_array($curl, array(
  CURLOPT_RETURNTRANSFER    =>  true,
  CURLOPT_FOLLOWLOCATION    =>  true,
  CURLOPT_MAXREDIRS         =>  10,
  CURLOPT_TIMEOUT           =>  30,
  CURLOPT_CUSTOMREQUEST     =>  'GET',
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo 'cURL Error #:' . $err;
} else {
  echo $response;
}
import requests

url = "https://us1.unwiredlabs.com/v2/timezone"

data = {
    'token': 'YOUR_API_TOKEN',
    'lat': 'LATITUDE',
    'lon': 'LONGITUDE'
}

response = requests.get(url, params=data)

print(response.text)
curl --request GET \
  --url 'https://us1.unwiredlabs.com/v2/timezone?token=YOUR_API_TOKEN&lat=LATITUDE&lon=LONGITUDE'
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://us1.unwiredlabs.com/v2/timezone?token=YOUR_API_TOKEN&lat=LATITUDE&lon=LONGITUDE",
  "method": "GET"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
Name Description Required
token Authentication token Yes
lat Latitude of the location Yes
lon Longitude of the location Yes

Response

The above command returns JSON structured like this:

{
  "status": "ok",
  "balance": 5000,
  "timezone": {
    "name": "Asia/Kolkata",
    "now_in_dst": 0,
    "offset_sec": 19800,
    "short_name": "IST"
  }
}
Name Description
status ok on success; error on error
balance Balance left in the account
timezone Timezone object found for the location. Read more

Timezone Response

Name Description
short_name Short name of the Timezone
offset_sec The offset from UTC (in seconds) for the given location. Considers DST savings.
now_in_dst Represents whether the zone currently observing DST or not
name Timezone name of the Location

Errors

{
  "status": "error",
  "message": "Error message"
}

When certain types of errors are encountered, the API responds with the following error messages:

Error Message HTTP Status Description
INVALID_TOKEN 200 The user's token set is not valid
INACTIVE_TOKEN 200 The user's token is not active
INVALID_INPUT 400 The request does not contain the required input in the specified format
NO_RESULTS 200 The request is valid and we could not find a timezone for the given coordinates
DAILY_LIMIT 429 The daily quota for timezone lookups has been reached
UNKNOWN_ERROR 500 or 503 Due to a server error, we are unable to serve your request. You can retry this request.

Maps

LocationIQ Maps - an offering from Unwired Labs - offers beautiful and customizable map tiles to visualize location data on your websites and apps.

Static Maps

LocationIQ Static maps - an offering from Unwired Labs - are standalone images (in JPG or PNG format) that can be displayed on web and mobile devices without the aid of a mapping library or API. Our Static Maps API returns an image in response to an HTTP request. For each request, you can specify the map's location, size of the image, zoom level, type of map. You can also place markers or draw paths at locations on the map.

Balance

The Balance API provides a count of request credits left in the user's account for the day. Balance is reset at midnight UTC everyday (00:00 UTC).

For device accounts, this endpoint also returns the number of available device slots.

Usage

GET requests can be sent to the following URL. To prevent abuse, this endpoint is rate limited at 1 request per second.

https://us1.unwiredlabs.com/v2/balance?token=YOUR_API_TOKEN

Replace us1 with a region that's closer to your location.

<?php

$curl = curl_init('https://us1.unwiredlabs.com/v2/balance?token=YOUR_API_TOKEN');

curl_setopt_array($curl, array(
  CURLOPT_RETURNTRANSFER    =>  true,
  CURLOPT_FOLLOWLOCATION    =>  true,
  CURLOPT_MAXREDIRS         =>  10,
  CURLOPT_TIMEOUT           =>  30,
  CURLOPT_CUSTOMREQUEST     =>  'GET',
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo 'cURL Error #:' . $err;
} else {
  echo $response;
}
import requests

url = "https://us1.unwiredlabs.com/v2/balance"

data = {
    'token': 'YOUR_API_TOKEN',
}

response = requests.get(url, params=data)

print(response.text)
curl --request GET \
  --url 'https://us1.unwiredlabs.com/v2/balance?token=YOUR_API_TOKEN'
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://us1.unwiredlabs.com/v2/balance?token=YOUR_API_TOKEN",
  "method": "GET"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});

Query Parameters

Name Description Required
token Authentication Token Yes

Response

The above command returns JSON structured like this:

{
  "status": "ok",
  "balance_geolocation": 4500,
  "balance_geocoding": 4500,
  "balance_slots": -1
}
Name Description
status ok on success; error on error
balance_geolocation Remaining balance left in the account for geolocation requests
balance_geocoding Remaining balance left in the account for geocoding requests
balance_slots Remaining device slots available. Returns -1 if no slots are allocated. This field is only present for device accounts.

Errors

  {
    "status": "error",
    "message": "Error message"
  }

When certain types of errors are encountered, our API responds with the following error messages:

Error Message Description
INVALID_TOKEN The user's token set is not valid
INACTIVE_TOKEN The user's token is not active
UNKNOWN_ERROR Due to an unknown error, we are unable to serve your request
RATELIMITED_SECOND The user has exceeded the 1 request per-second limit for this endpoint