Presence Analytics
Presence analytics, also known as location analytics or WiFi analytics, refers to the location data of WiFi clients detected by WiFi Access Points (APs) in the proximity.
Whenever an active WiFi client enters a new location, it probes its surroundings for WiFi networks to connect to. These probe request packets containing its MAC address are then used by the AP to recognize the WiFi client. The location of a specific WiFi client is determined with high accuracy whenever many APs from the same network are deployed in the area.
This location data can be used by presence analytics service providers to provide further analysis, such as studying customer behavior in shopping malls for marketing purposes.

Kaiwoo is able to provide captured WiFi probe requests via the CMX Scanning API developed by Cisco-Meraki and to communicate them to presence analytics service providers.
CMX Scanning API
The CMX Scanning API is a Push API. It takes care of sending captured WiFi probe requests in JSON format from the Kaiwoo server to the Destination URL. The Destination URL must be specified by the presence analytics service provider through the Provisioning API. It must be a secure HTTPS receiver to ensure data is protected.
The following graphic gives an overview of the communication flow between Kaiwoo and the presence analytics service provider.
Security
The identity of both the sending and receiving server needs to be validated for security reasons. This is done in two ways:
- The Kaiwoo server sends an HTTP GET request to the presence analytics service provider’s Destination URL and is returned a validator token. This is how Kaiwoo can confirm that the provided Destination URL is correct.
- For every HTTP POST the Kaiwoo server sends to the Destination URL with captured WiFi probe requests, the HTTP secret is forwarded as well. This way the presence analytics service provider is able to easily verify the identity of the sender, making sure the data is actually coming from Kaiwoo.
Both HTTP secret and validator are random strings which can be configured via the Provisioning API.
Examples
First, Kaiwoo confirms that the provided Destination URL is correct.
Validating Destination URL
The Kaiwoo server sends an HTTP GET request to validate the Destination URL.
Sample Request:
[GET] https://destination_url/
Response Parameters
The presence analytics service provider returns the validator string in the response body.
Name | Type | Sample Response |
---|---|---|
validator | string | 91473297842319492749273285409854 |
Sample Flow:
request: GET https://destination_url/
response: 91473298742319492749273285409845
If a matching validator string is returned, Kaiwoo starts posting JSON data.
Posting JSON Data
Kaiwoo sends an HTTP POST request to the validated Destination URL, including both the captured WiFi probe requests in JSON format and the provided HTTP secret.
Sample Request:
[POST] https://destination_url/
Response Parameters
The following parameters are posted by Kaiwoo:
Name | Format | Description |
---|---|---|
secret | string | The HTTP secret forwarded with every POST request. The presence analytics service provider uses it to easily verify the identity of the sender, making sure the data is actually coming from Kaiwoo. |
version | string | The CMX Scanning API version; currently 2.0. |
type | string | Always shows the string “DevicesSeen”. |
frequency | integer | The WiFi channel converted to frequency. Sent only if triangulation is disabled. |
hash | string | A checksum computed over the captured WiFi probe request which makes it easy to identify duplicates. Sent only if triangulation is disabled. |
rssi | integer | The client RSSI as seen by AP. |
location | location | The client geolocation; null if triangulation is disabled. |
lat | decimal | The client latitude in degrees N of the equator; null if triangulation is disabled. |
lng | decimal | The client longitude in degrees E of the prime meridian; null if triangulation is disabled. |
unc | decimal | The client location uncertainty in meters; 0 if triangulation is disabled. |
x | decimal | The JSON array of x offsets (in meters) from lower-left corner of each floorplan; 0.0 if triangulation is disabled. |
y | decimal | The JSON array of y offsets (in meteres) from lower-left corner of each floorplan; 0.0 if triangulation is disabled. |
apMac | string | The MAC address of the observing AP. Sent only if triangulation is disabled. Format: six hex bytes separated by colons (“:”). |
clientMac | string | The MAC address of the WiFi client. Format: six hex bytes separated by colons (“:”). Please note: the API sends the raw client MAC address. It is up to the receiving service to hash or modify the data before storage if data privacy is desired. |
seenTime | ISO 8601 date string | The observation time in UTC. Format: “1970-01-01T00:00:00Z”. |
seenEpoch | integer | The observation time in seconds since the UNIX epoch. |
probeTime | ISO 8601 date string | The observation time in UTC. Format: “1970-01-01T00:00:00Z”. |
probeEpoch | integer | The observation time in seconds since the UNIX epoch. |
Example JSON Data for WiFi Clients (triangulation disabled)
{
"secret": "myhttpsecret",
"version": "2.0",
"type": "DevicesSeen",
"data": {
"apMac": "11:22:33:44:55:66",
"apTags": [],
"apFloors": [],
"observations": [{
"frequency": 2432,
"hash": "33c802cf84566b9e5e6bd03d7f8ce7345b60426271ed7a861bded06e4ea6a84c",
"rssi": 9,
"location": {
"lat": null,
"lng": null,
"unc": 0,
"x": [0.0],
"y": [0.0]
},
"clientMac": "aa:a1:11:a1:1a:1a",
"seenTime": "2020-10-23T09:07:43Z",
"seenEpoch": 1600074463,
"probeTime": "2020-10-23T09:07:43Z",
"probeEpoch": 1600074463
},
{
"frequency": 5220,
"hash": "047978ac41da2e738452acde33284826b44fcc86c629b0bcd5e7e1c4aed8fcbf",
"rssi": 5,
"location": {
"lat": null,
"lng": null,
"unc": 0,
"x": [0.0],
"y": [0.0]
},
"clientMac": "0c:2c:22:22:2c:c2",
"seenTime": "2020-10-23T09:07:43Z",
"seenEpoch": 1600074463,
"probeTime": "2020-10-23T09:07:43Z",
"probeEpoch": 1600074463
}
]
}
}