Need Help?

Send your support request at:

Table of Contents
< All Topics

What is the format of the data pushed by Skiply (primary API)?

This article applies only for customers using the Skiply primary API (, and therefore the Skiply Push API (SPA) format. Customers using Ubiqod will receive data on the Ubiqod format.


How it works?

Smilio Data Format with push API

Each LPWAN operator sends data with different formats and/or protocols (REST, MQTT, Pub/Sub…): the SPA delivers a standard json payload to your server. It always remains the same, independently from the Network Operator (Sigfox or LoRaWAN). Therefore, it acts as a high level roaming system.

The SPA decodes the data whatever the Running mode / frame is (pulse, count, code, battery level), taking into consideration the version of your device’s firmware.

The SPA does the annoying job for you: calculation of the increments, checking the data consistency, and eliminating “bad frames”.

We POST data to the URL of your choice (you can include API key as parameter or custom header). See the Skiply API documentation to know how to manage this parameters.

Buttons numbering

Smilio A numbering

Button 1: top left
Button 2: top right
Button 3: middle
Button 4: bottom left
Button 5: bottom right

Payload contents

Normal data sample


“device”: “SA000272”,

“groupId”: 5, “time”: “2018-06-21T20:14:31.394Z”, // ISO 8601 date

“sq_num”: 98,

“frameType”: “02”,

“data”: {

“index”: [1,0,16,1,2],

“increment”: [0,0,0,0,2],

“button_1”: 0,

“button_2”: 0,

“button_3”: 0,

“button_4”: 0,

“button_5”: 2,

“ack”: 0


“negativeValue”: 0,




device = serial number of the product

groupId = group of the device. Can be usefull to facilitate to consolidate device data, for instance in the context of live visualisation

time = timestamp from the network

sq_num = frame sequence number, to identify if a frame has been missed

frameType = “02” or “03” (with ack)

ack = 1 if the frame has been send due to a magnetic detection instead of normal operation (badge)

index = state of the internal counters : [button1, button2, … , button5]

increment = variation of the index between to frames received by our servers : [button1, button2, … , button5]
code = type of frame

negativeValue = return 1 if a negative increment has been detected (reset). Increment is [0,0,0,0,0] in this case to avoid bad counts

rawPayload = payload receive before decoding

Code data sample



“groupId”: 5,

“time”:“2022-06-21T20:14:31.394Z”, // ISO 8601 Date

“dc_delay”: 0,

“sq_num”: 98,

“frameType”: “11”,

“data”: {

“code”: “021214”,

“increment”: [2,2,0,1,0],

“button_1”: 2,

“button_2”: 2,

“button_3”: 0,

button_4″: 1,

“button_5”: 2,

“ack”: 0


“previous”: {

“code”: “012334”,

“increment”: [1,1,2,1,0],

“button_1”: 1,

“button_2”: 1,

“button_3”: 2,

“button_4”: 1,

“button_5”: 0,


“previous_time”: 13,







frameType = “11” or “13” or “31” for code mode

dc_delay: potential delay from the Duty Cycle protection in minutes

data: code entered by the user

> code: value of the code (1 to 5, max. 6 digits)

> increment (button 1 to 5, number of presses per button)

> ack = 1 if the code has been validated by magnetic detection (badge)

previous: code entered previously by the user

> previous_time: time since last code what entered (in minutes)

> missed: returns yes if we detect that this previous frame was not received by our server (for instance due to bad network conditions)

> estimated_time: estimated time of the previous frame

Keep alive format


“device”: “SA000272”,

“groupId”: 5,

“time”: “2018-06-21T20:14:31.394Z”, // ISO 8601 Date

“sq_num”: 99,

“frameType”: “01”,

“data”: {

“battery_level”: 3.35





device = serial number of the product

time = timestamp from the network

sq_num = frame sequence number, to identify if a frame has been missed

frameType = “01”

ack = always 0 for this frame type

battery_level = in volts

code = type of frame


The Push API will send data to the endpoint defined in the group configuration, and wait for a 200 code in return. If the system doesn’t receive a 200 response, a new try will be done after 60 seconds. If the retry fails, an error is logged with the missed data and error code returned.