When a TaqtOne device emits valid data, Ubiqod calls your destination URL with an HTTP POST. The request body (the payload) is a JSON object describing the event.
There are three payload families (see connector configuration):
By default, only DATA payloads are sent. The others can be enabled in the connector's advanced options.
In the connector's Advanced options tab, the "Select the event types to send" menu determines what flows through this webhook. The available combinations are:
Two architecture approaches are possible depending on your preference:
eventType to dispatch each message.DATA, one for ALERT, one for KEEP_ALIVE + WAKE_UP. Splitting is cleaner for debugging and separation of concerns, at the cost of maintaining several endpoints.There is no universal right answer: the choice depends on your system's architecture.
All payloads share the same envelope. Only the data block changes depending on the device type and the action.
{
"eventType": "DATA", // "DATA" | "KEEP_ALIVE" | "WAKE_UP" | "ALERT"
"timestamp": "2026-06-12T11:00:05.000Z", // ISO 8601, UTC
"account": { "name": "EP_1" }, // your Ubiqod organization
"tracker": { // the physical device that emitted the event
"id": "65413734-a5c6-4165-b445-af6475602586", // stable Ubiqod UUID
"slug": "865456056209578", // hardware identifier (IMEI/serial number)
"type": "IOT",
"model": "TAQTONE",
"label": "Aéroport | P2 Sous sol H", // name given to the device
"batteryLevel": 49, // battery % (0–100)
"externalReferences": {} // your business keys (ERP/CRM mapping)
},
"site": { /* … or null */ }, // linked site (see §6)
"location": "43.6668227,7.2098445", // "lat,lng" or "" if not geolocated
"alert": null, // alert block (non-null only for ALERT)
"data": { /* … or null */ }, // action details (non-null for DATA eventType only)
"ubiqodValidity": { /* … */ } // validity flags (see §5)
}
| Field |
Recommended usage |
|---|---|
tracker.id |
Stable identification key of the device. Use it as the technical identifier. |
tracker.slug |
Unique hardware number (IMEI). Human-readable. |
tracker.label |
Simple name given to the device to find it more easily in the field (often its location) |
tracker.externalReferences |
Carry your own business identifier here to avoid a lookup table. |
data.reference |
The physical button number pressed. This is the key of your business mapping (see §4). |
timestamp |
Event timestamp, in UTC. Remember to convert to local time. |
A DATA event from a TaqtOne boils down to two signals, which can be combined:
data.reference (button number) + data.label (configured label).data.code block (badge) + ubiqodValidity.badgeSwiped = true.It is the combination of these two signals, and above all the button number (data.reference), that gives the business meaning.
The payload does not contain a "device type" field: the type (Satisfaction, Time Tracking, Traceability, Service Request, Custom) results from the device configuration, which you translate through the button mapping.
data block — field reference| Field |
Type |
Presence |
Description |
Note |
|
|---|---|---|---|---|---|
interfaceType |
string | always | Equals "TAQTONE" for these devices. |
||
reference |
string | always | Physical button number pressed, between 1 and 6 (e.g. "3", "6"). Mapping key. |
||
label |
string | always | Label configured for this button (e.g. "Check-in", "Excellent"). |
Customized by the user in the "interface" module | |
pressCount |
number | always | Number of presses recorded for the event. | ||
rate |
number | Satisfaction only | Normalized rating (see §4.1). Absent otherwise. | ||
email |
string | Satisfaction | E-mail entered, for QR Code interfaces only | Always null or "" for TaqtOne devices | |
code |
object \ | null | if badge | Badge block (see below). null if no badge. |
|
photo |
string \ | null | optional | URL of an attached photo, or null. |
data.code block (the badge), present only if a badge was swiped:
| Field |
Description |
|---|---|
code.reference |
Hardware UID of the badge (hexadecimal, e.g. "04453D9A251391"). Stable badge identifier. |
code.label |
Badge label. If the badge is known (registered in a list), it is the person's name; otherwise, it is the UID repeated. |
code.externalReferences |
Your business keys associated with the badge (e.g. employee ID). |
💡 Key rule about the badge. The
ubiqodValidity.codeValidflag indicates whether the badge is recognized:
codeValid = true→code.label= person's name (badge registered in a badge list).
codeValid = false→code.label= UID (unregistered badge). The badge still works, but remains anonymous.
The only structurally distinguishable type is Satisfaction. All other types (Time Tracking, Traceability, Service Request, Custom) share the same "button + badge" structure and differ only through the button mapping you configure.
┌─────────────────────────────────────────────┐
│ Is data.rate a number? │
└───────────────┬───────────────┬─────────────┘
YES │ │ NO
▼ ▼
┌────────────────┐ ┌──────────────────────────────┐
│ SATISFACTION │ │ "Button + badge" event │
│ (code = null, │ │ → meaning given by │
│ badgeSwiped │ │ data.reference (button) │
│ = false) │ │ + badgeSwiped / code │
└────────────────┘ └──────────────────────────────┘
data.reference is the stable key: a physical button keeps its number. data.label reflects your configuration and can be renamed — use it for display, but base your logic on reference.
A satisfaction device emits a rating, without a badge.
Signature: data.rate present · data.code = null · ubiqodValidity.badgeSwiped = false.
The rate field is normalized (scale of 1 to 5, 5 being the best possible satisfaction rating), regardless of the number of physical smileys. The label gives the associated text.
Note: Satisfaction devices are also commonly used in addition for traceability (badging). See section 4.3.
Observed examples (3-smiley configuration):
rate |
label |
reference (button) |
|---|---|---|
| 1 | Mauvais |
"3" |
| 3 | Satisfaisant |
"4" |
| 5 | Excellent |
"5" |
// Satisfaction — "Excellent" rating
{
"eventType": "DATA",
"timestamp": "2026-06-12T10:40:01.000Z",
"account": { "name": "EP_1" },
"tracker": { "model": "TAQTONE", "label": "Aeroport Hall 2", "batteryLevel": 46 },
"site": { "label": "AEROPORT | DR | NICE" },
"data": {
"interfaceType": "TAQTONE",
"reference": "5", // "green smiley" button
"label": "Excellent", // Customizable field in "interface"
"rate": 5, // ← normalized rating 1–5 (present = satisfaction)
"email": "",
"code": null, // ← no badge
"pressCount": 4, // 4 presses received on this button
"photo": null
},
"ubiqodValidity": { "badgeSwiped": false, "codeValid": false, "onSite": true }
}
An agent swipes a badge then presses a "Check-in" or "Check-out" button. The event combines button + badge.
Signature: data.code present · badgeSwiped = true · no rate · the button's label/reference carries the check-in/check-out semantics.
// Time tracking — departure from site (clock-out)
{
"eventType": "DATA",
"timestamp": "2026-06-12T12:12:44.000Z",
"account": { "name": "Test_DOC" },
"tracker": { "model": "TAQTONE", "label": " National Opéra", "batteryLevel": 74 },
"data": {
"interfaceType": "TAQTONE",
"reference": "5", // ← "Check-out" button
"label": "Departure from site",
"code": {
"reference": "045C723A521E90", // badge UID
"label": "Damaris Rubeta" // name (known badge → codeValid:true)
},
"pressCount": 1,
"photo": null
},
"ubiqodValidity": { "badgeSwiped": true, "codeValid": true, "onSite": true }
}
The "check-in" or "check-out" meaning depends on the button (reference/label): there is no dedicated time-tracking field. Base your logic on the device's button mapping.
As a general rule, button "3" is dedicated to check-in and button "5" to check-out.
The traceability device has no button: you simply swipe a badge to prove a visit. The determining signal is therefore the badge.
Signature: data.code present · badgeSwiped = true. The button (reference/label) corresponds to the default configured passage.
// Traceability / badged passage (unregistered badge → label = UID)
{
"eventType": "DATA",
"timestamp": "2026-06-12T04:51:26.000Z",
"account": { "name": "EP_1" },
"tracker": { "model": "TAQTONE", "label": "865456059667008 - EP_2", "batteryLevel": 99 },
"data": {
"interfaceType": "TAQTONE",
"reference": "6",
"label": "Inter. de nettoyage (sortie)",
"code": {
"reference": "04549102C31B90", // badge UID
"label": "04549102C31B90" // = UID because unknown badge (codeValid:false)
},
"pressCount": 1,
"photo": null
},
"ubiqodValidity": { "badgeSwiped": true, "codeValid": false, "onSite": true }
}
One or more buttons trigger an intervention request (e.g. "consumable replacement", "cleaning"). The meaning comes from the button (reference/label).
The badge is optional: a request can be made by a simple press (without a badge), and an agent can later close the intervention by pressing the same button with their badge (see the two-step case below).
Signature: no rate; the label/reference identifies the request type; code / badgeSwiped present when a badge accompanies the press (typically closure by a service agent).
// Service request — service entry
{
"eventType": "DATA",
"timestamp": "2026-06-10T10:28:36.000Z",
"account": { "name": "EP_1" },
"tracker": { "model": "TAQTONE", "label": "Altas", "batteryLevel": 100 },
"site": { "label": "Altas - Toulouse", "location": "43.6108617,1.4347106" },
"data": {
"interfaceType": "TAQTONE",
"reference": "3", // ← "intervention request" button
"label": "Demande intervention",
"code": { "reference": "26167181000000", "label": "26167181000000" },
"pressCount": 1,
"photo": null
},
"ubiqodValidity": { "badgeSwiped": true, "codeValid": false, "onSite": true }
}
Two-step case: request then closure on the same button
The same Service Request button can be used both to open a request and then to close it. The only element distinguishing the two events is the presence of the badge (code / badgeSwiped).
1. Opening the request — a user reports a need (here a consumable replacement, button 4), without badging:
// Service Request — opening a request (press only, no badge)
{
"eventType": "DATA",
"timestamp": "2026-06-26T13:38:21.000Z",
"account": { "name": "Test_Grupo" },
"tracker": { "model": "TAQTONE", "label": "UCA SALA 2651J C", "batteryLevel": 50 },
"data": {
"interfaceType": "TAQTONE",
"reference": "4", // ← "consumable replacement" button
"label": "Savon", // configured label ("soap")
"code": null, // ← no badge: this is a REQUEST
"pressCount": 1,
"photo": null
},
"ubiqodValidity": { "badgeSwiped": false, "codeValid": false, "onSite": true }
}
2. Closure / completion — later, an agent performs the intervention and presses the same button 4 + badge; the badge identifies the agent:
// Service Request — closure (same button + agent's badge)
{
"eventType": "DATA",
"timestamp": "2026-06-26T14:02:02.000Z",
"account": { "name": "Test_Grupo" },
"tracker": { "model": "TAQTONE", "label": "UCA SALA 2651J C", "batteryLevel": 50 },
"data": {
"interfaceType": "TAQTONE",
"reference": "4", // ← same button
"label": "Savon",
"code": {
"reference": "04405902C31B90",
"label": "Marin Fecha", // agent (known badge → codeValid:true)
"externalReferences": { "Category": "Cleaning" }
},
"pressCount": 1,
"photo": null
},
"ubiqodValidity": { "badgeSwiped": true, "codeValid": true, "onSite": true }
}
💡 Integration side: for this scenario, track the state of a request per button (
reference). An event without a badge = opening/request; an event with a badge on the same button = closure, with the agent incode.
A Custom device combines several functions on distinct buttons (e.g. 2 smiley buttons + 3 service request buttons + badging). There is nothing special to detect in the payload: each press produces a standard event, and it is your reference → meaning mapping table that distinguishes the functions.
Practical routing rule in code:
if data.rate is present → treat as SATISFACTION (rating = data.rate)
otherwise, based on data.reference (button):
└─ apply the mapping configured for this device
(Check-in / Check-out / Intervention X / Passage …)
and in all cases, if data.code != null and badgeSwiped == true:
└─ attach the event to a badge / a person
(name if codeValid, otherwise anonymous UID)
ubiqodValidity block (validity flags)These booleans qualify the event. The two most useful for your logic are badgeSwiped and codeValid.
| Flag |
Meaning |
|---|---|
badgeSwiped |
true if a badge was swiped during the event. Distinguishes a simple press from a badged press. |
codeValid |
true if the swiped badge is recognized (present in a badge list). Determines code.label (name vs UID). |
onSite |
true if the event was emitted at the expected site. |
withPhoto |
true if a photo is attached (see data.photo). |
scanToken |
Related to secure scans (QR/SafeQod); always false for TaqtOne presses. |
codeFromCookie |
Indicates a code retrieved via cookie (web journey); always false for device usage. |
site and account blocksaccount.name: the name of your Ubiqod organization. Constant for a given account.site: the site linked to the device. Can be null if the device is not linked to a site. When present:"site": {
"id": "2f5442a7-a532-4bf8-bb11-38b5b9e9de60", // stable site UUID
"label": "NICE AEROPORT | DR NICE | NICE",
"location": "43.6668227,7.2098445", // "lat,lng"
"contacts": [ // site contacts
{ "type": "CUSTOMER", "fullName": "", "email": "", "phone": "" },
{ "type": "MANAGER", "fullName": "", "email": "", "phone": "" }
],
"externalReferences": {}
}
Never assume that
siteis present: handle thenullcase. To link a site reliably on the integration side, prefersite.id(orsite.externalReferences) oversite.label.
Periodic life signal. data is null and eventType = "KEEP_ALIVE". Useful for monitoring the health/battery of a device without usage.
{
"eventType": "KEEP_ALIVE",
"timestamp": "2026-06-12T08:37:34.000Z",
"account": { "name": "EP_1" },
"tracker": { "model": "TAQTONE", "slug": "867280060944991", "batteryLevel": 64 },
"data": null, // ← no business data
"site": null,
"alert": null,
"ubiqodValidity": { "onSite": true, "badgeSwiped": false, "codeValid": false }
}
The WAKE_UP is the first data sent when the device is powered on or after a restart (reboot). Like the KEEP_ALIVE, it carries data: null and contains no business data: it lets you know that a device has just started (useful for fleet monitoring, for example after a battery change or a reinstallation).
{
"eventType": "WAKE_UP",
"timestamp": "2026-06-03T14:09:40.000Z",
"account": { "name": "Taqt" },
"tracker": {
"id": "c62c17ce-b163-4c11-ad52-5ff3a1b90945",
"label": "TaqtOne Satisfaction",
"slug": "867280060944991",
"type": "IOT",
"model": "TAQTONE",
"batteryLevel": 75,
"externalReferences": {}
},
"site": null,
"location": "",
"data": null, // ← no business data
"alert": null,
"ubiqodValidity": { "onSite": true, "badgeSwiped": false, "codeValid": false, "codeFromCookie": false, "scanToken": false, "withPhoto": false }
}
Note:
KEEP_ALIVEandWAKE_UPare grouped under the same connector option (see §1) and share the same structure (data: null). Distinguish them viaeventType:KEEP_ALIVE= periodic signal,WAKE_UP= startup/restart.
If your connector is not configured for KEEP_ALIVE events, the platform marks them status: "filtered" and does not transmit them. Enable them in the connector's advanced options if you want to receive them.
For each delivery, Ubiqod displays two tabs in the traceability view: Payload (what was sent, described in the previous sections) and Server response (what your endpoint returned to Ubiqod). This tab is a debugging tool: it lets you check that Ubiqod actually reached your system and how it responded.
The response is a JSON object containing the HTTP status code returned by your server, and sometimes a response body:
{
"statusCode": 200, // HTTP code returned by YOUR endpoint
"body": "..." // response body (optional, depending on your server)
}
body → free text returned by your system. Purely informative for debugging; it is not meant to be interpreted automatically and its content depends entirely on the destination system.💡 Recommendation. Always return a 2XX code as soon as the webhook is received, and defer your business processing (validation, storage) to the background. This avoids unnecessary retries and false errors in the Ubiqod traceability view.
data.reference (button number), not on data.label (which is renamable text).data.rate as the exclusive marker of Satisfaction: present ⇒ rating, absent ⇒ button/badge event.null values: data (KEEP_ALIVE), site, data.code (no badge), data.photo.data.reference/data.label = the button; data.code = the person/badge.codeValid to interpret code.label (name if true, UID if false).tracker.id (stable UUID) rather than by label or slug.timestamp from UTC to the user's time zone.| Device type |
data.rate |
data.code |
badgeSwiped |
Interpretation key |
|---|---|---|---|---|
| Satisfaction | number (1–5) | null |
false |
rate = the rating |
| Time Tracking | absent | present | true |
reference/label = Check-in/Check-out + badge |
| Traceability | absent | present | true |
badge = passage |
| Service Request | absent | present* | true* |
reference/label = intervention type |
| Custom | depends on button | depends on button | depends on button | reference → function mapping |
*Depending on configuration: a badge may or may not accompany the press.