Authentication
Each request to Unwired's APIs or Map tiles needs to be authenticated with an access token
.
Access Tokens
For user-facing applications such as Javascript websites or mobile apps, we recommend that you generate new access tokens
on your User Dashboard. Create a separate access token
for each application, label them accordingly - e.g. "my website" - and reissue these tokens frequently to prevent misuse. You can use access tokens
in both public (websites, apps) and private environments (server backends).
Security Best Practices
As a best practice, you need to secure your API Access Tokens. We recommend use some or all of the options below to avoid abuse of your public access tokens.
HTTP Referrer restrictions
You can define a list of HTTP referrers (commonly mis-spelled as referer!) authorized to call our APIs or Maps with an access token. If not specified or empty, it will default to any referrer. Referrers can be targeted by matching a prefix or a suffix using the * character. For multiple HTTP referrers, specify one pattern per line, upto a maximum of 10 per access token.
You can test patterns on the User Dashboard while viewing an access token:
A few examples:
*example.com*
- allow access for the full domain and sub-domains of example.com- These refererrs match the pattern:
https://example.com
http://www1.example.com/
- These refererrs do not match the pattern:
https://example.org
-.org
does not matchhttps://ExamPLE.com
- because patterns are case-sensitive
- These refererrs match the pattern:
https://example.com/*
will restrict access to all referrers starting withhttps://example.com/
.- These refererrs match the pattern:
https://example.com/abc
https://example.com/
- These refererrs do not match the pattern:
https://www.example.com/
- becausewww.
does not matchhttps://example.com
- no trailing/
like the pattern requireshttp://example.com
-http:
does not match
- These refererrs match the pattern:
*.example.com/
- will restrict access to all referrers ending with.example.com/
.- These refererrs match the pattern:
https://abc.example.com/
http://www.example.com/
- These refererrs do not match the pattern:
http://www.example.com
- no trailing/
like the pattern requireshttps://ExamPLE.com
- because patterns are case-sensitive.http://example.com
-example
does not have the leading.
- These refererrs match the pattern:
The referrer is an HTTP header that is sent by browsers and like all HTTP headers, it can be spoofed. To limit misuse when using access tokens on a public site, we recommend frequent access token rotation along with referrer restrictions.
IP Address restrictions
You can define a list of IPv4 addresses or subnets authorized to call our APIs or Maps with an access token. If not specified or empty, it will default to any IP address. Specify one IPv4 address or a subnet using CIDR notation (e.g. 192.168.1.0/24). For multiple IP addresses or subnets, specify one per line, upto a maximum of 5 per access token.
A few examples:
192.168.1.1
will restrict access to to requests from this IP172.16.1.0/24
will restrict access to IPs in the range172.16.1.0
to172.16.1.255
Note: It may take up to 10 minutes for settings to take effect.
Endpoints
API requests can be sent to any of the following endpoints. Developers can choose the endpoint that's geographically closer to their servers for minimal latency.
Region 1: US East (Northern Virginia)
https://us1.unwiredlabs.com/v2/<specific_api_endpoint>
Region 2: US West (San Francisco)
https://us2.unwiredlabs.com/v2/<specific_api_endpoint>
Region 3: Europe (France)
https://eu1.unwiredlabs.com/v2/<specific_api_endpoint>
Region 4: Asia Pacific (Singapore)
https://ap1.unwiredlabs.com/v2/<specific_api_endpoint>
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.
Usage
curl --request POST \
--url https://us1.unwiredlabs.com/v2/process \
--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,"signal": -51}, {"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_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,\"signal\": -51}, {\"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,\"signal\": -51}, {\"bssid\": \"d8:97:ba:c2:f0:5a\"}],\"address\": 1}"
response = requests.request("POST", url, data=payload)
print(response.text)
var settings = {
"async": true,
"crossDomain": true,
"url": "https://us1.unwiredlabs.com/v2/process",
"method": "POST",
"headers": {},
"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,\"signal\": -51}, {\"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 an endpoint 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,
"signal":-51
},
{
"bssid":"d8:97:ba:c2:f0:5a"
}
],
"address":1
}
Send the following data as a POST
request in the JSON
format. Only the token
parameter is mandatory. All others are optional.
Parameter | Description | Type |
---|---|---|
token | Your API token. If you don't have one, get one free here! | string |
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 |
radio | Radio type of the device. Supported values are 'gsm', 'cdma', 'umts', 'lte' and 'nbiot'. This field should be included for more accurate results. | string |
mcc | Mobile Country Code of your operator's network represented by an integer (Optional). Range: 0 to 999. An updated list of MCCs can be found here. | integer |
mnc | Mobile Network Code of your operator's network represented by an integer (Optional). Range: 0 to 999. On CDMA, provide the System ID or SID, with range: 1 to 32767. | integer |
cells | An array of cell ID objects visible to the device. Read more. | array |
wifi | An array of WiFi objects visible to the device. Read more. | array |
ip | IP address of device. Read more | string |
gps | An array of gps objects that contains GPS information about where the request data was scanned. Read more |
array |
gps_sandbox | Must be set to 0 to submit data and 1 to test in sandbox. Defaults to 1. | integer |
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 |
address | The physical address of the returned location. Read more | integer |
accept-language | Preferred language order for showing address results. Read more | string |
fallbacks | An array of fallback options to enable or disable. Read more | array |
bt | Specify level of strictness to apply to Borders. Read more | integer |
metadata | Additional information about the request or response, if any, is returned if set to 1. Defaults to 0. Read more | integer |
Cells
Each cells
object contains information about a single Cell Tower.
- You can send 1 to 7 cell ID objects. If your device supports scanning for more than 7 cell objects, reach out to us and we'll increase this limit on your account.
- The first cell object has to be that of the serving cell, i.e. the tower the device is connected to. The others are neighbouring cell objects that are visible to the device.
- Except
cid
all other parameters mentioned below are optional. - Parameters vary depending on the radio type. Supported radio types and their corresponding parameters are:
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 |
yes |
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 |
yes |
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 |
yes |
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 |
yes |
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 |
yes |
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 |
yes |
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.
You can send a minimum of 2 and a maximum of 15 WiFi objects in 1 request.
If WiFi is not available,
wifi
object can be omitted all together.In accordance with our industry's privacy standards we require a minimum of 2 valid nearby Access Points to be sent.
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 |
signal | Signal Strength (RSSI) (optional) | integer |
signalToNoiseRatio | The current signal to noise ratio, measured in dB (optional) | integer |
timestamp | The time this WiFi data was scanned, measured in milliseconds since the UNIX epoch (optional) | integer |
Fallbacks
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": [{ ... }],
"wifi": [{ ... }],
"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.
You may send multiple
gps
objects if the device or client has multiple GPS locations.Always include
"geolocation": 1
to the request body while contributing to ensure such requests are not charged and do not affect balance.Contact us before you begin sending
gps
data since this feature has to be enabled manually.
Parameter | Description | Type | Required |
---|---|---|---|
lat | The latitude of the observation (WSG 84) | float |
yes |
lon | The longitude of the observation (WSG 84) | float |
yes |
accuracy | The horizontal accuracy of the observed position in meters | float |
yes |
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 |
yes |
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
You can choose what level of strictness to apply to border checks.
Type | Accepted | Default |
---|---|---|
integer |
0 or 1 or 2 |
1 |
strict - Only locations inside land parcels will be allowed. Value:
0
medium - Locations near known land in the range of upto 5 KM will be included. Locations may lie in a water body. Value:
1
low - Locations near known land parcels in the range of upto 15 KM will be included. Locations returned may lie in a water body. Value:
2
Other Notes
Don't use leading zeroes in any of the numerical values without encapsulating that value in quotes, as it is invalid JSON and the request will be discarded with
INVALID_REQUEST
error.Use double quotes (
"
) not single quotes ('
) to encapsulate strings as per JSON standards.The fields
mcc
,mnc
are not mandatory at the top level and will be overridden by values provided in thecells
objects.If the request contains only a CDMA element and doesn't have an MCC, the field
mcc
can be omitted. The fieldradio
is mandatory. Set it tocdma
.If the device has multiple radios or SIM cards, you can include
radio
,mcc
,mnc
in each cell object.
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.
Parameter | Description |
---|---|
status | If the request is successful, ok is returned. Otherwise error is returned |
message | Any additional information from the server is returned here |
balance | This represents the remaining balance on the API token. Requests that return error are not charged and do not affect balance. |
balance_slots | This represents the remaining balance of device slots. Requests that return error are not charged and do not affect balance. If -1 is returned, then observe it as an error while calculating slots balance. This element will only exist if you are on a device plan. |
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_details | 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 Details
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:
area
locality
district
county
city
state
country
country_code
postal_code
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
}
Possible return values for message
when status
is error
by category
Authentication error
Token balance over; you have used up all your requests for today
Invalid token - get a trial token by signing up for free
Parsing error
Invalid request
No cell ID provided
No location area code provided
No country code provided
No network data provided
No valid cell IDs or LACs provided
Invalid network code (mnc)
Invalid country code (mcc)
Unsuccessful
No matches found
No matches found, please try again shortly
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 an endpoint 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 an endpoint 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.
- List of
Accept-Language
codes: List of ISO 639-1 codes - Use
ISO 639-1
Code (2 characters). If the language is not available, useISO 639-2
Code (3 characters) from here - Default:
en
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 |
- List of accepted country codes: Officially assigned code elements
Errors
{
"status": "error",
"message": "Error message"
}
When certain types of errors are encountered, LocationIQ API responds the following error messages:
Error Message | Description |
---|---|
NO_TOKEN |
The request does not contain the user's token |
INVALID_TOKEN |
The user's token set is not valid |
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 an endpoint 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 |
Maps
LocationIQ Maps - an offering from Unwired Labs - offers beautiful and customizable map tiles to visualize location data on your websites and apps.
Endpoints
Depending on which Maps SDK you decide to use, you will need to use either the Style Specification URL
or Tile URLs
.
Style Specification URL:
For MapLibre-GL SDKs, use a Style Specification URL. A Style URL looks like this:
https://tiles.locationiq.com/v3/<theme>/<type>.json?key=<access_token>
Parameters
Name | Description |
---|---|
theme | streets . Complete list of available themes here. |
type | vector ,raster . vector renders the map on the client-side and is faster, has crisper text and consume less bandwidth. raster by nature is slower and consumes more bandwidth as images are rendered on the server-side and transferred to the client. |
access_token | Your LocationIQ public access token. We recommend that you generate a new access token on your User Dashboard and add HTTP Referrer Restrictions to avoid abuse. |
Tile URLs:
For LeafletJS and other mapping libraries, you need to specify Tile URLs instead:
https://{s}-tiles.locationiq.com/v3/<theme>/r/{z}/{x}/{y}.<format>?key=<access_token>
Parameters
Name | Description |
---|---|
theme | streets . Complete list of available themes here. |
format | tile-format for the chosen theme, as defined here. |
access_token | Your LocationIQ public access token. We recommend that you generate a new access token on your User Dashboard and add HTTP Referrer Restrictions to avoid abuse. |
Available Themes
Theme | Format | Sample |
---|---|---|
streets | png | |
dark | png | |
light | png |
Websites
Our map tiles can be rendered by most open-source libraries like OpenLayers, MapLibre GL JS or Leaflet JS to add a map to your website.
We've added demos & code-samples for most popular use-cases:
Maps using MapLibre GL JS(recommended)
Maps using OpenLayers
Maps using LeafletJS (for compatibility with older browsers)
Android
MapLibre-gl Native SDK
For your Android apps, we recommend you use the excellent and open-source MapLibre GL Native Android SDK. We've created a sample app showcasing popular use-cases among our users.
OSMDroid
In case you'd like to use OSMDroid, we've added sample code for you on the right:
For more info and documentation, please refer to osmdroid Wiki
iOS
For iOS apps, we recommend you use the excellent and open-source MapLibre GL Native iOS SDK. We've created a sample app showcasing popular use-cases among our users.
Errors
All errors - authentication, invalid tile URLs, etc - will return JSON along with a corresponding HTTP response code as specified below
{
"error": "Error message"
}
When the API encounters any errors it responds the following error messages in the body and corresponding HTTP codes in the header:
Error message | HTTP Response code | Description |
---|---|---|
Invalid Request | 400 | Required parameters are missing, or invalid |
Invalid key | 401 | An invalid API key was provided |
Key not active - Please write to hello@locationiq.com | 401 | API Key provided is invalid or inactive |
Service not enabled | 403 | The specific service is not enabled on your token. Write to hello@locationiq.com to enable this. |
Access restricted | 403 | The request has been made from an unauthorized domain. |
Imagery not found | 404 | No style or tile available for the specified url |
Unknown error - Please try again after some time | 500 | This is an error on the server's side, we monitor this 24x7 and you should try again. |
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.
You can simply embed static map image within an <img>
tag's src attribute.
Usage
Requests can be sent to the following endpoint
GET https://maps.locationiq.com/v3/staticmap
Query Parameters
curl -o mystaticmap.png 'https://maps.locationiq.com/v3/staticmap?key=<YOUR_ACCESS_TOKEN>¢er=<latitude>,<longitude>&zoom=<zoom>&size=<width>x<height>&format=<format>&maptype=<MapType>&markers=icon:<icon>|<latitude>,<longitude>&markers=icon:<icon>|<latitude>,<longitude>'
<img src='https://maps.locationiq.com/v3/staticmap?key=<YOUR_ACCESS_TOKEN>¢er=<latitude>,<longitude>&zoom=<zoom>&size=<width>x<height>&format=<format>&maptype=<MapType>&markers=icon:<icon>|<latitude>,<longitude>&markers=icon:<icon>|<latitude>,<longitude>'>
<img src='https://maps.locationiq.com/v3/staticmap?key=<YOUR_ACCESS_TOKEN>¢er=<latitude>,<longitude>&zoom=<zoom>&size=<width>x<height>&format=<format>&maptype=<MapType>&markers=icon:<icon>|<latitude>,<longitude>&markers=icon:<icon>|<latitude>,<longitude>'>
<img src='https://maps.locationiq.com/v3/staticmap?key=<YOUR_ACCESS_TOKEN>¢er=<latitude>,<longitude>&zoom=<zoom>&size=<width>x<height>&format=<format>&maptype=<MapType>&markers=icon:<icon>|<latitude>,<longitude>&markers=icon:<icon>|<latitude>,<longitude>'>
Name | Description | Required | Values |
---|---|---|---|
key | Authentication key. | Yes | Access token |
center | Defines the center of the map. It takes a comma seperated value of a latitude, longitude pair. This parameter is required if markers are not defined. |
Either | Latitude [-90 to 90 ], Longitude [-180 to 180 ] |
zoom | Set the zoom level for the map. Required if markers are not present. Defaults to 18 |
Yes | [0 to 18 ] |
scale | Affects the number of pixels that are returned. Defaults to 1 . |
No | [1 ,2 ]. |
size | Defines the rectangular dimensions of the map image. This parameter takes a string of the form {width}x{height} . Defaults to 300x300 . Maximum allowed size is 1280x1280 . The dimensions of the response image depends on size and scale values as {scale x width} x {scale x height} . For e.g. if scale=2 , and size=300x300 , the dimensions of the output image will be 600x600 . If you need larger image sizes, reach out to us! |
No | <string> |
format | Defines the format of the resulting image. Defaults to png . |
No | [jpeg | jpg | png ] |
maptype | Defines the type of the map to construct. Only roadmap is supported at the moment. |
No | <string> |
markers | Defines one or more markers to overlay on the map. Parameters are specified as key:value seperated by Pipe character. See below for the full list of parameters. Required if center is not set. |
Either | |
path | Defines one or more paths to draw on the map. Path parameters are seperated by Pipe character. See below for the full list of parameters | No |
Markers
Markers are a type of overlay used to identify locations on the map. The markers
parameter accepts a set of values in the following format:
markers=icon:
For using same icon-name for all markerLocations, you can send multiple markerLocations in the same markers parameter.
markers=icon:
curl -o mystaticmap.png 'https://maps.locationiq.com/v3/staticmap?key=<YOUR_ACCESS_TOKEN>&size=600x600&zoom=14&markers=45.5165,-122.6764|icon:large-blue-cutout&format=png'
Below are the list of values that are accepted by markers param :
icon
: Icon to use for the marker. Must choose one of the icons mentioned below. If an invalid icon is specified, the marker will not be rendered. Below are the available icon names :
large-red-cutout small-red-cutout tiny-red-cutout large-red-blank small-red-blank tiny-red-blank large-blue-cutout small-blue-cutout tiny-blue-cutout large-blue-blank small-blue-blank tiny-blue-blank large-gray-cutout small-gray-cutout tiny-gray-cutout large-gray-blank small-gray-blank tiny-gray-blank large-yellow-cutout small-yellow-cutout tiny-yellow-cutout large-yellow-blank small-yellow-blank tiny-yellow-blank large-purple-cutout small-purple-cutout tiny-purple-cutout large-purple-blank small-purple-blank tiny-purple-blank large-orange-cutout small-orange-cutout tiny-orange-cutout large-orange-blank small-orange-blank tiny-orange-blank large-green-cutout small-green-cutout tiny-green-cutout large-green-blank small-green-blank tiny-green-blank large-black-cutout small-black-cutout tiny-black-cutout large-black-blank small-black-blank tiny-black-blank markerLocation
: Each markerLocation param should contain latitude, longitude pair which defines the postion of the marker.- Example:
markers=icon:large-red-cutout|17.451377,78.379525|17.450419,78.381149
- Example:
markerStyles
: consists of visual attributes like size and color, which are used to display the markers on the map.-
size
: accepted values - [tiny, small, large]. Defaults to small. -
color
: accepted values - [blue, gray, red, yellow, orange, green, purple]. Defaults to red. - Example:
markers=size:small|color:red|17.451377,78.379525|17.450419,78.381149
-
Paths
The path parameter defines a set of one or more locations connected by a path to overlay on the map image. The path
parameter takes set of values in the following format:
path=pathStyles|pathLocation1|pathLocation2|... etc.
See note
Below are the list of values that are accepted by path parameter :
pathStyles
: consists of visual attributes to use when displaying the path.-
weight
: specifies the thickness of the path in pixels. -
color
: color of the path stroke (e.g. red, rgba(255,255,255,0.5), #0000ff) -
fillcolor
: color to use as the fill (e.g. red, rgba(255,255,255,0.5), #0000ff) - Example:
path=weight:2|color:blue|fillcolor:%23add8e6|17.452945,78.380055|17.452765,78.382026
-
pathLocation
:
- Using coordinates: Each pathLocation parameter contains latitude, longitude pair seperated by comma.
- Format:
path=lat1,lon1|lat2,lon2|
- Example:
https://maps.locationiq.com/v3/staticmap?key=<YOUR_ACCESS_TOKEN>¢er=17.450419,78.381149&size=600x600&zoom=14&path=fillcolor:%2390EE90|weight:2|color:blue|17.452945,78.380055|17.452765,78.382026|17.452020,78.381375|17.452045,78.380846|17.452945,78.380055
- Format:
- Using an encoded polyline: Prefix with
enc:
followed by the encoded polyline string- Format:
path=enc:<encoded_polyline
- Example:
https://maps.locationiq.com/v3/staticmap?key=<YOUR_ACCESS_TOKEN>¢er=17.450419,78.381149&size=600x600&zoom=14&path=fillcolor:%2390EE90|weight:2|color:blue|enc:}woiBkrk}Mb@iKtC`CEhBsD|C
- Format:
- Using coordinates: Each pathLocation parameter contains latitude, longitude pair seperated by comma.
Example
Below is the sample static map having two markers, polygonal area and is centered at 17.450419,78.381149
.
https://maps.locationiq.com/v3/staticmap?key=<YOUR_ACCESS_TOKEN>¢er=17.450419,78.381149&zoom=16&size=480x480&markers=icon:large-red-cutout|17.450419,78.381149&markers=icon:large-red-cutout|17.451377,78.379525&path=fillcolor:%23add8e6|weight:1|color:blue|17.452945,78.380055|17.452765,78.382026|17.452020,78.381375|17.452045,78.380846|17.452945,78.380055
Errors
For all errors except authentication errors, the Static Map API returns the following blank image in grey
to help preserve user experience. An error code is set in the HTTP Response code as specified below.
Authentication errors will return JSON in the format as specified below.
{
"error": "Error message"
}
Error message | HTTP Response code | Description |
---|---|---|
Invalid Request | 400 | Required parameters are missing, or invalid |
Invalid key | 401 | An invalid API key was provided |
Key not active - Please write to hello@locationiq.com | 401 | API Key provided is invalid or inactive |
Service not enabled | 403 | The specific service is not enabled on your token. Write to hello@locationiq.com to enable this. |
Access restricted | 403 | The request has been made from an unauthorized domain. |
Imagery not found | 404 | No style or tile available for the specified url |
Unknown error - Please try again after some time | 500 | This is an error on the server's side, we monitor this 24x7 and you should try again. |
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).
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 an endpoint 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": int,
"balance_geocoding": int
}
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 |
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 |
Client Libraries
This section lists Client libraries you can use to interact with our APIs.
Supported APIs
Currently the following APIs are supported
- Geolocation API
- Geocoding API
- Timezone API
- Balance API
Client libraries
Language | Tested by UnwiredLabs |
---|---|
clojure | no |
csharp | no |
dart | no |
go | no |
haskell | no |
java | yes |
kotlin | no |
objc | no |
perl | no |
php | yes |
python | yes |
qt5cpp | no |
r | no |
ruby | no |
rust | no |
scala | no |
swift4 | no |