Skip to content

Data Streams Setup

Data Streams help with monitoring for presence of items represented by Bluetooth beacons as well as collecting sensor data that beacons might gather. They allow you to take advantage of beacons without relying on mobile apps installed on devices you don't control.

Prerequisites

Data Streams depend on several components:

  • Kontakt.io Gateway GW16-2 - it's a scanner that detects presence of BLE devices, like Kontakt.io beacons, through monitoring their Bluetooth Advertising Packets.
  • Beacons - they usually represent different types of items that are relevant to your use case, e.g. you can use Tough Beacons attached to tools and machinery in factories, to monitor their location, or distribute Card Beacons among office employees to use as employee badges and track their work time.
  • Kontakt.io Panel account - it's a place from where you can manage your Kontakt.io devices and set up an infrastructure for your beacon deployment.

Gateways GW16-2 are available for order in Kontakt.io Web Store. Additionally, we're working in cooperation with major WiFi access point vendors like Ruckus and Cassia to integrate their devices with Data Streams. Please stay tune for future announcements regarding these integrations.

You need Kontakt.io Panel account to get the API Key and set up your Data Streams infrastructure. Instructions for setting up a new Web Panel account and finding your API Key are available in our Support Center.

Subscription

In order to take advantage of Kontakt.io Data Streams, beacons assigned to your account have to have Data Streams subscription. Without this subscription they won't contain any data.

Setup

As of Spring 2018 Data Streams do not require any specific operations to make them work. As long as you have a Gateway GW16-2 assigned to your account together with Kontakt.io beacons with Data Streams subscription, you are ready to start monitoring the data collected by Gateways.

Info

Originally we instructed here to use ovs.kontakt.io as the host for both MQTT and WebSocket streams. As of April 2019 we recommend switching to dedicated hosts for each stream type, as described in the documentation below. For now we don't have any plans to turn off ovs.kontakt.io, nonetheless we recommend switching to the new addresses when possible.

MQTT

In order to receive information about detected devices or their Telemetry data, your MQTT client needs to connect to our server:

  • Host: mqtt.kontakt.io
  • Port: 8083
  • Protocol: MQTTS (TLS 1.2)
  • User: (this value can't be empty, but you can use anything here)
  • Password: You API Key
  • Client ID: (can be random)

Available topics

Below is the list of topics that you can subscribe to. For more information about streams' content please refer to this document: Data streams

Recommended:

  • /stream/:uniqueId/all - for all telemetry data available from a single beacon. Please keep in mind that in some cases telemetry data from a beacon can be sent in more than one Telemetry Packet, resulting in a stream containing messages with various structures.
  • telemetry/:companyId - for all telemetry data from all beacons belonging to users from the same Company. Please note this topic does not start with a slash (/).
  • /stream/:uniqueId/location - for information from Location Packets broadcasted by a given beacon.

Legacy - these topics are no longer recommended for new projects since they do not provide all possible data available from beacons with latest firmwares and/or require a lot of processing to get valuable information:

  • /presence/stream/:sourceId – for data from a single Gateway
  • /stream/:venueId/presence – for data from all Gateways assigned to a Location (Venue)
  • /stream/:uniqueId/health - for live information about battery life of a given beacon
  • /stream/:uniqueId/accelerometer - for raw accelerometer data and information about an event detection
  • /stream/:uniqueId/sensor - for data from other sensors available on a beacon
  • /stream/:uniqueId/button - for data about button events from button-equipped beacons

MQTT over WebSocket

If you want to have an access to Data Streams in a browser environment, we also provide our MQTT streams over the secure WebSocket protocol:

  • Host: mqtt.kontakt.io/mqtt
  • Port: 443
  • Protocol: WSS
  • User: (this value can't be empty, but you can use anything here)
  • Password: You API Key
  • Client ID: (can be random)

Then you can subscribe to the same topics as with standard MQTT streams.

Webhooks

Webhooks can be used to notify a registered URL on a 3rd party server about BLE events. Just like WebSocket or MQTT Data Streams, they give access to real-time data collected by Gateways.

Warning

Webhooks are no longer being developed and should be considered deprecated. They will work for the foreseeable future, but please do not base your new projects on this feature.

Setup

Configuring a new webhook starts with calling the POST /webhook/subscribe endpoint and providing two required parameters as an URL-encoded form:

  • url - URL where a webhook should send data (it has to use HTTPS)
  • sourceId - Unique ID of a Gateway that should provide data

Additionally, you can provide a number of parameters that can represent headers that our servers will use when calling your webhook URL. This can be useful e.g. for authorization. These optional parameters' names should follow this pattern: headers[<yourHeadersName>]

The full HTTP call should look like this:

POST /webhook/subscribe HTTP/1.1
Accept: application/vnd.com.kontakt+json;version=10
Api-Key: yourSuperSecretAPIKey
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: ovs.kontakt.io
Connection: close
User-Agent: Paw/3.0.16 (Macintosh; OS X/10.12.3) GCDHTTPRequest
Content-Length: 130

url=https%3A%2F%2Fyour.server.com%2Fyour%endpoint&sourceId=abcde&headers%5ByourCustomHeader1%5D=valueForHeader1&headers%5ByourCustomHeader2%5D=valueForHeader1

Confirmation

When our backend receives this request it will make a POST request to the specified URL. This request will have two important headers: Type and X-Request-ID. The former's value will be SUBSCRIPTION_CONFIRMATION and the latter's an UUID generated by our server for your subscription request. It will look similarly to this:

POST /your/endpoint HTTP/1.1
type: SUBSCRIPTION_CONFIRMATION
X-Request-ID: a50ad921-652a-4051-9826-81d067a6c420
content-type: application/json
yourCustomHeader1: valueForHeader1
yourCustomHeader2: valueForHeader2
Content-Length: 0
Host: your.server.com
User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_91)
Accept-Encoding: gzip,deflate

The webhook client has to respond with HTTP code 200 OK and a JSON-encoded body containing your managerId and requestId with value from the X-Request-ID header. It should be similar to this:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 103
ETag: W/"67-/DMbwqz4/hmBFCNOKPV1Uw"
Date: Wed, 08 Mar 2017 12:54:08 GMT
Connection: keep-alive

{"managerId":"5d96e777-0a55-4969-8e64-496f3f943a46","requestId":"a50ad921-652a-4051-9826-81d067a6c420"}

Receiving data

If your server's confirmation response is valid, your webhook will start sending POST requests containing JSON with Presence data every 5 seconds (future adjustments of this value are possible). Type header of these requests will be set to DATA.

You backend has to respond to each POST with HTTP code 202 Accepted. If a response is either 502 Bad Gateway, 503 Service Unavailable or 504 Gateway Timeout, the webhook will try to send data after 5 minutes. If it gets the same response once again, it will retry once more after another 5 minutes. If the second attempt is also unsuccessful, the webhook will be unsubscribed. Similarly with all other possible HTTP codes, although in these cases a webhook tries three times without waiting and closes the itself if it don't get 202 Accepted.

Additional informations

At a given moment a single manager can have up to 10 active webhooks. You can check what webhooks are active by calling GET /webhook endpoint.

If you want to unsubscribe from a webhook, call POST /webhook/unsubscribe and provide webhookId parameter with the ID of a webhook in the body of your request.