Combain CPS API

Here is the description of our JSON CPS API. See how it works

If you want to minimize transfered data, we still support our original HTTP GET CPS API. Here is the specification CPS Original API spec.

If you have already implemented any other geolocation API (Google, Mozilla Location Service, etc), we are also backward compatible with these.
Thus to switch to CPS just change to your CPS key and CPS url and it will work! However, you will not get all CPS features like fallback control etc.

API Endpoint
Method: POST
Content-Type: application/json

Enter your secret api key for trying CPS API below. If you do not have one, please click here to get one for free.




Request parameters

Mandatory URL Request Parameters

key – The unique key for the account, received from Combain. Mandatory parameter.

Optional URL Request Parameters

id – A unique device id. Recommended to be the IMEI number, but can be something else. Possible to submit to Combain a range of allowed device id’s. Important to be truly unique for the account, otherwise devices may not receive correct position. Max 20 characters in length.

nr – Request number set by the device. First request should have 1 and then value should be increased by 1 for each request. Helps to identify correct response to a request if a delay in network or lookup.

JSON Request Parameters

geoname – Request geoname of location. Disregarded if omitted or 0. If set to 1, the closest populated city in text form, country and country code is returned in the geoname parameter array in the response. If set to 1 and any indoor wifi submitted, the response will also include building, floor and room.

address – Request address of location. Disregarded if omitted or 0. If set to 1, the address information will be returned in the address parameter array in the response.

credit – Request number of credits left for prepaid keys. Disregarded if omitted or 0. If set to 1, the number of credits will be returned in the credit parameter in the response.

gps – Latest GPS information. Improves positioning requests with latest GPS position, for example indoor where latest GPS position is normally at the door of the building. If GPS position is older than 600s, it does not add any value and should be omitted. GPS object is also used for contributing to database if age=0 and there is at least one cell or one wifi included. Contributions are not calculated as succesful requests. GPS object consists of following parameters:

latitude – The GPS latitude.

longitude – The GPS longitude

accuracy – The GPS accuracy (horizontal).

age – The age of the GPS location (in seconds).

altitude – The altitude of the GPS location. (Optional).

altitudeAccuracy – The accuracy of the altitude for the GPS location (Optional).

heading – The direction (bearing) of movement for the GPS location. (Optional).

speed – The speed of the GPS location in m/s. (Optional).

pressure – The air pressure in hPa (millibar). (Optional).

cellTowers – An array of all cell towers. There is no limit on the number of towers, send as many as possible. Each one contains the following parameters:

radioType – The radio type of this cell tower. Can also be put directly in root JSON element if all cellTowers have same radioType.

mobileCountryCode – The Mobile Country Code (MCC).

mobileNetworkCode – The Mobile Network Code (MNC) for GSM,WCDMA and LTE. The SystemID (sid) for CDMA.

locationAreaCode – The Location Area Code (LAC) for GSM,WCDMA and LTE. The Network ID for CDMA

cellId – The Cell ID (CID) for GSM, WCDMA and LTE. The Basestation ID for CDMA.

signalStrength – The signal strength for this cell tower in dBm.

timingAdvance – The timing advance value for this cell tower when available. (Optional)

primaryScramblingCode – The primary scrambling code for WCDMA and physical CellId for LTE.

serving – Specify with 0/1 if the cell is serving or not. If not specified, the first cell is assumed to be serving.

wifiAccessPoints – An array of wifi access points. Each one of them containing the following parameters:

macAddress – The BSSID of the Wifi router.

ssid – The SSID of the Wifi router (optional).

signalStrength – The measured signal strength of the Wifi router in dBm.

NOTE: For privacy issues, at least 2 wifi access points must be submitted in a query to get a location.
bluetoothBeacons – An array of bluetooth beacons. Each one of them containing the following parameters:

macAddress – The address of the BLE beacon.

name – The name of the BLE beacon (optional).

signalStrength – The measured signal strength of the BLE beacon in dBm.

Parameters for using the IP Fallback.

ip – The IP to use for IP GeoLocation. If omitted – the IP of the client is used. Please note that you have to set the ipf flag to use this fallback (see IP Fallback).
sensors – An array of sensor parameters to improve positioning accuracy.

pressure – The ambient air pressure in hPa or mbar.

steps – The number of steps since last request. For best performance use effective number of steps (=distance). Thus if going 4 steps straight and then 3 steps to the right, the effective number of steps are 5.

heading – The heading in degrees. For best performance it should be the composite heading since last request.

activity – The detected activity in an Android device. Valid values are IN_VEHICLE, ON_BICYCLE, ON_FOOT, RUNNING, STILL, TILTING, UNKNOWN and WALKING.

fallbacks – Fallback solutions. The request will check different fallback solutions to create a position if none of the submitted cells or wifis are found. These parameters should be used with care since it could potentially return wrong coordinates. Associative array with values 1 for on and 0 for off. Parameters for turning individual fallbacks on or off:

all – Enable/disable all fallbacks for this request. (This does not include cidxf which has to be activated manually.)

w4f – Used to support mobile units only able to read a 4 CID Hex digits of a WCDMA CID (normally 8 CID Hex digits). Search the CID but just compare the 4 less significant hex digits.

lac01f – If the cell is not found, look for LAC = 0 and same CID. No other LACs to choose from.

lac0xf – If the cell is not found, look for LAC = 0 and same CID. Several other LACs to choose from. Select the one with best accuracy.

lacf – If the CID is not found, return the center and accuracy for the LAC.

cid1f – If the cell is not found, look for another LAC != 0 and same CID. No other LACs to choose from.

cidxf – If the cell is not found, look for another LAC != 0 and same CID. Several other LACs to choose from. Select the one with best accuracy.

nbcidf – Neighbouring CID. If the cells is not found, it will search for a slightly similar CID.

rncidf – If the cell is not found, search with MCC, MNC, RNCID (first part of CellId).

mncf – If the MNC is not found, search for just MCC, LAC and CID.

ipf – Enable fallback to IP GeoLocation. If no cells or wifis are found, make geolocation based on IP address. Either the remote IP address from requesting server or the IP address in the IP request parameter.

Response parameters

The response will be a JSON object.
location – The estimated location of the device.

lat – The latitude of the estimated location.

lng – The longitude of the estimated location.

accuracy – The accuracy is the median error in meters, i.e. the radius in a circle with 50% confidence level.

geoname – Geoname data for the estimated location if available and requested.

address – Address data for the estimated location if available and requested.

fallback – If this field is included no direct match was found. It shows which fallback was used.

error – Error element.

errors – All the errors that occurred.

domain – The domain of this error.

reason – The type of error.

message – The message for this error.

code – Error code. 400 = Parse Error / Invalid key. 403 = Out of credits. 404 = Not found

message – The error message.

Example scripts

curl \
    -X POST                                \
    -H "Content-Type: application/json"    \
    -d '{
    "radioType": "gsm",
    "cellTowers": [{
        "mobileCountryCode": 240,
        "mobileNetworkCode": 1,
        "locationAreaCode": 3012,
        "cellId": 11950

$apiKey = "YOUR_API_KEY";
$data = array(
	"radioType" => "gsm",
	"cellTowers" => array(
			"mobileCountryCode" => 240,
			"mobileNetworkCode" => 1,
			"locationAreaCode" => 3012,
			"cellId" => 11950

// Make request to server
$c = curl_init("$apiKey");
curl_setopt_array($c, array(
    CURLOPT_HTTPHEADER => array('Content-Type: application/json'),
    CURLOPT_POSTFIELDS => json_encode($data)
$response = curl_exec($c);
if ($response === FALSE) {

// Decode result
$result = json_decode($response, true);
if (isset($result['location'])) {
	print "Returned location: ".$result['location']['lat'].", ".$result['location']['lng'];
} else {
	print "The following error occurred: ".$result['error']['message'];


from httplib import HTTPSConnection
import json

apiKey = "YOUR_API_KEY"

data = {
	"radioType": "gsm",
	"cellTowers": [{
		"mobileCountryCode": 240,
		"mobileNetworkCode": 1,
		"locationAreaCode": 3012,
		"cellId": 11950
headers = { "Content-Type" : "text/json" }
conn = HTTPSConnection("",443)
conn.request("POST", "/?key="+apiKey, json.dumps(data), headers)
response = conn.getresponse()
result = json.load(response)

if ("location" in result):
	print("Returned location: "+str(result['location']['lat'])+", "+str(result['location']['lng']))
	print("The following error occurred: "+result['error']['message'])

Integration – Best Practices

Avoid unnecessary requests – If you not receive a successful result, you receive message “notFound”, then the cell or wifi does not exist in our database. It makes no sense to send the exact same query directly again. We suggest you wait at least 24h hours before trying the exact same query again. The database grows with around 3 million observations per day.

Avoid unnecessary costs – to avoid unnecessary costs (normally charged per successful request) you are allowed to cache the result from a successful request in your devices and on your own servers, for up to normally seven days. Check your license agreement for how long caching period you are allowed to have. But note, multi cell requests are hard to cache since neighboring cells and signal strength is never the same, and you will always have better quality of data if you request the API since locations and accuracy figures are continuously updated in the online database.

Avoid infinite loops – to avoid unnecessary load on your own servers and on our servers, make sure your code do not end up in an infinite loop if you not receive a successful result from the Combain server.

Be flexible – never hardcode an URL to in any devices you ship to end-customers. The recommendation is that you setup your own subdomain that redirects to by using proper DNS settings or by using a relaying server. If you for some reason need to modify your requests to us, and you do not have access to the software in the shipped devices, you can then do that on your own server before sending the requests to us.

Improve accuracy – for best results, make sure you always send all your data, including neighboring cells and WiFis and Bluetooth beacons in same request.

Sharing is caring – contribute to build up the database. If you have access to active GPS coordinates as well you are welcome to submit these as well and then the request is counted as a contribution and not deducted from your request quota. See the GPS Object in the spec.
Hi there!

Would you like to get in touch with us? Please send us a message and we'll get back to you.