Cette page répertorie les événements IoT auxquels un webhook peut s’abonner, ainsi que le data que chacun transporte. L’enveloppe autour de data, les en-têtes et la signature sont décrits dans Webhooks. La liste des événements proposés à votre organisation est également disponible via GET /api/webhooks/events.
Règles générales :
- Les charges utiles ne contiennent que des identifiants et des champs sûrs. Un identifiant d’appareil, un jeton, un mot de passe, un certificat ou un lien de téléchargement n’est jamais envoyé.
- Les heures sont au format texte ISO 8601 en UTC, sauf les heures d’alarme, exprimées en millisecondes depuis l’époque.
- Les événements peuvent arriver dans le désordre et, rarement, en double. Dédupliquez sur
X-Webhook-Deliveryet ordonnez selon les heures contenues dans la charge utile. - Les exemples ne montrent que le
eventet ledatade l’enveloppe ; l’enveloppe complète contient aussiwebhookId,tenantIdetcreatedAt.
Appareils
| Événement | Envoyé lorsque |
|---|---|
device.created | Un appareil a été ajouté : manuellement, par import, par provisioning ou revendication, ou en tant qu’enfant d’une passerelle |
device.updated | Le nom, le libellé, le type, le profil, l’indicateur de passerelle, les informations supplémentaires ou le statut ont changé |
device.deleted | Un appareil a été supprimé (manuellement, par une libération, ou en annulant un import) |
device.credentials_rotated | Le identifiant a été roté, remplacé, renouvelé (X.509) ou révoqué |
device.connected | Un appareil s’est connecté et est resté connecté pendant la durée de maintien |
device.disconnected | Un appareil s’est déconnecté et est resté hors ligne pendant la durée de maintien |
{ "event": "device.created", "data": {
"deviceId": "6f1c…", "name": "pump-station-04", "serial": null, "profileId": "a1b2…",
"status": "ACTIVE", "isGateway": false, "createdAt": "2026-11-09T08:00:00.000Z" } }
L’enfant d’une passerelle porte aussi gatewayDeviceId.
{ "event": "device.updated", "data": {
"deviceId": "6f1c…", "name": "pump-station-04", "serial": null, "profileId": "a1b2…",
"status": "DISABLED", "isGateway": false, "changedFields": ["status"], "previousStatus": "ACTIVE",
"updatedAt": "2026-11-09T08:10:00.000Z" } }
changedFields ne nomme que les champs (triés : additionalInfo, isGateway, label, name, profileId, status, type), jamais leurs valeurs. previousStatus n’est présent que lorsque le statut a changé. Une modification qui ne change aucun de ces champs n’envoie rien.
{ "event": "device.deleted", "data": {
"deviceId": "6f1c…", "name": "pump-station-04", "serial": null, "profileId": "a1b2…",
"credentialRevoked": true, "deletedAt": "2026-11-09T08:20:00.000Z" } }
{ "event": "device.credentials_rotated", "data": {
"deviceId": "6f1c…", "name": "pump-station-04", "serial": null, "profileId": "a1b2…",
"change": "rotated", "credentialType": "ACCESS_TOKEN", "previousType": "ACCESS_TOKEN",
"changedAt": "2026-11-09T08:30:00.000Z" } }
change vaut rotated, replaced, renewed ou revoked ; après revoked, credentialType vaut null.
{ "event": "device.connected", "data": {
"deviceId": "6f1c…", "name": "router-17", "profileId": "a1b2…", "transport": "mqtts",
"connectedAt": "2026-11-03T10:00:00.000Z", "remoteIpPrefix": "203.0.113.0/24" } }
{ "event": "device.disconnected", "data": {
"deviceId": "6f1c…", "name": "router-17", "profileId": "a1b2…", "reason": "timeout",
"disconnectedAt": "2026-11-03T12:00:00.000Z", "lastSeenAt": "2026-11-03T11:59:40.000Z", "onlineSeconds": 7200 } }
remoteIpPrefix est le /24 d’une adresse IPv4 ou le /48 d’une adresse IPv6, jamais l’adresse complète. reason vaut clean (l’appareil s’est déconnecté), timeout (sa fenêtre de keep-alive ou de liaison montante a expiré), kicked (le serveur l’a fermée, par exemple après un changement d’identifiant) ou quota (il a atteint une limite).
Durée de maintien et volume. Un changement de connexion n’est envoyé qu’après avoir duré pendant la durée de maintien : Appareils > paramètres > Connection webhooks: hold time (seconds), par défaut 30, de 5 à 3 600. Un appareil qui se déconnecte puis se reconnecte dans ce délai n’envoie rien. Au maximum 600 événements de connexion et 600 événements de changement d’appareil sont envoyés par organisation et par minute par défaut ; le reste de la minute est abandonné et vos propriétaires et administrateurs reçoivent une notification. Les appareils restent consultables via l’API.
Alarmes
| Événement | Envoyé lorsque |
|---|---|
alarm.created | Une alarme s’est ouverte (une règle de profil, un bloc de flux ou un opérateur). Non envoyé lorsqu’une alarme déjà ouverte est déclenchée à nouveau. |
alarm.acknowledged | Un opérateur ou un flux a acquitté une alarme ouverte. Elle reste ouverte. |
alarm.cleared | Une alarme a été résolue : par sa règle ou son flux, par un opérateur, ou parce que son appareil a été supprimé |
{ "event": "alarm.created", "data": {
"alarmId": "9a7e…", "type": "high_temperature", "severity": "CRITICAL",
"originator": { "type": "DEVICE", "id": "6f1c…", "name": "cold-room-2" },
"deviceId": "6f1c…", "profileId": "a1b2…", "url": "/admin/iot/alarms/9a7e…",
"title": "Temperature too high", "startedAt": 1762678800000, "openedAt": 1762678800000,
"details": { "temperature": 9.4 }, "backfilled": false, "metadata": { "topic": null } } }
{ "event": "alarm.acknowledged", "data": {
"alarmId": "9a7e…", "type": "high_temperature", "severity": "CRITICAL", "originator": { "…": "…" },
"deviceId": "6f1c…", "profileId": "a1b2…", "url": "/admin/iot/alarms/9a7e…",
"ackBy": { "userId": "u-55…" }, "ackAt": 1762679100000 } }
{ "event": "alarm.cleared", "data": {
"alarmId": "9a7e…", "type": "high_temperature", "severity": "CRITICAL", "originator": { "…": "…" },
"deviceId": "6f1c…", "profileId": "a1b2…", "url": "/admin/iot/alarms/9a7e…",
"clearedBy": "rule", "reason": "clear", "clearedAt": 1762680000000, "durationSeconds": 1200,
"metadata": { "topic": null } } }
urlest la page de l’alarme dans l’application ; placez votre hôte et/tenant/<tenantId>devant elle.backfilled: truemarque une alarme ouverte par des mesures tardives (par exemple après le rejeu du tampon d’une passerelle). Personne n’est notifié pour celles-ci.clearedByvaut"rule"ou{ "userId": "…" };reasonvautclear,manualouoriginator_deleted.metadatavautnulllorsqu’une personne l’a résolue.- Un changement de gravité d’une alarme ouverte n’envoie aucun webhook. Les webhooks d’alarme ne sont pas limités en débit ; la limite de débit de votre endpoint s’applique néanmoins.
Commandes
| Événement | Envoyé lorsque |
|---|---|
rpc.completed | Une commande s’est terminée en SUCCESSFUL (avec réponse, ou une commande sans réponse a été livrée) |
rpc.failed | Une commande s’est terminée en FAILED, TIMEOUT (résultat inconnu) ou EXPIRED (n’a jamais atteint l’appareil) |
{ "event": "rpc.failed", "data": {
"rpcId": "c0de…", "deviceId": "6f1c…", "method": "pump.start", "status": "TIMEOUT",
"error": null, "source": "api", "completedAt": "2026-11-09T09:00:15.000Z" } }
La réponse elle-même ne figure pas dans la charge utile : lisez-la avec GET /api/iot/rpc/{rpcId}. Une commande annulée n’envoie rien.
Micrologiciel
| Événement | Envoyé lorsque |
|---|---|
ota.update.initiated | Un paquet de micrologiciel a été remis à un appareil pour installation |
ota.update.succeeded | Un appareil exécute la version cible |
ota.update.failed | La mise à jour a échoué, a expiré ou a été annulée par retour arrière |
ota.rollout.wave_completed | Une vague a franchi ses contrôles |
ota.rollout.paused | Un contrôle a échoué ou une personne a mis le déploiement en pause |
ota.rollout.resumed | Une personne l’a repris |
ota.rollout.completed | La dernière vague a franchi ses contrôles |
ota.rollout.aborted | Une personne l’a interrompu, son affectation a été supprimée ou remplacée, ou son paquet a été révoqué |
{ "event": "ota.update.failed", "data": {
"deviceId": "6f1c…", "packageId": "f00d…", "title": "router-fw", "version": "2.5.0", "fromVersion": "2.4.1",
"state": "FAILED", "attempts": 1, "at": "2026-11-09T10:00:00.000Z", "stage": "verify", "error": "…" } }
stage vaut download, verify, update ou rollback ; error est le code de l’appareil, ou un délai d’expiration.
{ "event": "ota.rollout.paused", "data": {
"rolloutId": "r-12…", "assignmentId": "as-3…", "packageId": "f00d…", "status": "PAUSED", "wave": 2, "waves": 3,
"at": "2026-11-09T11:00:00.000Z", "reason": "failure_gate", "failures": 4, "failurePct": 6.7, "successPct": 88.3 } }
Les charges utiles de déploiement contiennent rolloutId, assignmentId, packageId, status, wave (à partir de 1), waves et at, plus : updated, failures, successPct (vague terminée) ; reason et les compteurs (en pause ; reason vaut failure_gate, success_gate, no_result (aucun appareil n’a terminé) ou manual) ; pausedReason (repris) ; updated (terminé) ; reason (interrompu).
Provisioning
| Événement | Envoyé lorsque |
|---|---|
iot.device.claimed | Un appareil sous licence a été revendiqué dans votre organisation |
iot.device.released | Un appareil est retourné au pool d’usine : kind OWNER (vous l’avez libéré), FORCED (support de la plateforme) ou DEVICE (depuis la page propre de l’appareil) |
{ "event": "iot.device.claimed", "data": {
"deviceId": "6f1c…", "serial": "RT-0017", "model": "…", "claimedAt": "2026-11-09T07:00:00.000Z", "claimedByUserId": "u-55…" } }
{ "event": "iot.device.released", "data": {
"deviceId": "6f1c…", "serial": "RT-0017", "model": "…", "kind": "OWNER", "releasedAt": "2026-11-09T07:30:00.000Z" } }
Règles
| Événement | Envoyé lorsque |
|---|---|
rules.mode_changed | Un site a été passé en Manuel, est revenu en Auto, ou son mode Manuel s’est terminé de lui-même |
rules.needs_attention | Une règle a été désactivée parce qu’un appareil ou le site qu’elle désigne n’existe plus |
{ "event": "rules.mode_changed", "data": {
"placeType": "asset", "placeId": "77aa…", "placeName": "Greenhouse 2", "mode": "manual", "change": "manual",
"actorId": "u-55…", "until": 1762700000000, "reason": "Harvest" } }
change vaut manual, auto ou expired ; actorId vaut null lorsqu’un mode Manuel s’est terminé de lui-même. Un retour en Auto transporte aussi applyNow et rearmed.
{ "event": "rules.needs_attention", "data": {
"ruleId": "ru-9…", "name": "Close vents at night", "reason": "…",
"home": { "type": "asset", "id": "77aa…" } } }
Flux
automation.message n’est envoyé que par un bloc Webhook d’un flux, et uniquement vers le seul endpoint que le bloc désigne (qui doit être abonné à « Automation message »). Il contient topic, payload, originator, flowId, flowVersion, nodeId, actor et les clés de metadata listées par le bloc, avec X-Idempotency-Key. Voir Blocs d’action.
Autres événements
esim.operation.succeededetesim.operation.failedrelèvent de la gestion eSIM, qui est en cours de développement.- Les événements de clé API (
api_key.created,api_key.updated,api_key.rotated,api_key.deleted,api_key.expired) et les événements d’organisation (membres, invitations, abonnement) sont également proposés. Leurs charges utiles ne sont pas couvertes sur cette page.

