Nouveau : le pare-feu IA surveille chaque module et explique chaque incident en termes simples. Découvrez comment ça marche

Référence des événements webhook

Chaque événement webhook IoT – appareils, connexions, alarmes, commandes, micrologiciel, provisioning, règles et flux – avec le moment de son envoi et un exemple de charge utile.

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-Delivery et ordonnez selon les heures contenues dans la charge utile.
  • Les exemples ne montrent que le event et le data de l’enveloppe ; l’enveloppe complète contient aussi webhookId, tenantId et createdAt.

Appareils

ÉvénementEnvoyé lorsque
device.createdUn appareil a été ajouté : manuellement, par import, par provisioning ou revendication, ou en tant qu’enfant d’une passerelle
device.updatedLe nom, le libellé, le type, le profil, l’indicateur de passerelle, les informations supplémentaires ou le statut ont changé
device.deletedUn appareil a été supprimé (manuellement, par une libération, ou en annulant un import)
device.credentials_rotatedLe identifiant a été roté, remplacé, renouvelé (X.509) ou révoqué
device.connectedUn appareil s’est connecté et est resté connecté pendant la durée de maintien
device.disconnectedUn 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énementEnvoyé lorsque
alarm.createdUne 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.acknowledgedUn opérateur ou un flux a acquitté une alarme ouverte. Elle reste ouverte.
alarm.clearedUne 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 } } }
  • url est la page de l’alarme dans l’application ; placez votre hôte et /tenant/<tenantId> devant elle.
  • backfilled: true marque 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.
  • clearedBy vaut "rule" ou { "userId": "…" } ; reason vaut clear, manual ou originator_deleted. metadata vaut null lorsqu’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énementEnvoyé lorsque
rpc.completedUne commande s’est terminée en SUCCESSFUL (avec réponse, ou une commande sans réponse a été livrée)
rpc.failedUne 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énementEnvoyé lorsque
ota.update.initiatedUn paquet de micrologiciel a été remis à un appareil pour installation
ota.update.succeededUn appareil exécute la version cible
ota.update.failedLa mise à jour a échoué, a expiré ou a été annulée par retour arrière
ota.rollout.wave_completedUne vague a franchi ses contrôles
ota.rollout.pausedUn contrôle a échoué ou une personne a mis le déploiement en pause
ota.rollout.resumedUne personne l’a repris
ota.rollout.completedLa dernière vague a franchi ses contrôles
ota.rollout.abortedUne 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énementEnvoyé lorsque
iot.device.claimedUn appareil sous licence a été revendiqué dans votre organisation
iot.device.releasedUn 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énementEnvoyé lorsque
rules.mode_changedUn site a été passé en Manuel, est revenu en Auto, ou son mode Manuel s’est terminé de lui-même
rules.needs_attentionUne 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.succeeded et esim.operation.failed relè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.