Novedad: el cortafuegos de IA supervisa cada módulo y explica cada incidente con palabras sencillas. Vea cómo funciona

Referencia de eventos de webhook

Cada evento de webhook de IoT (dispositivos, conexiones, alarmas, comandos, firmware, aprovisionamiento, reglas y flujos), con el momento en que se envía y un payload de ejemplo.

Esta página enumera los eventos de IoT a los que puede suscribirse un webhook y los data que transporta cada uno. El envoltorio alrededor de data, las cabeceras y la firma se describen en Webhooks. La lista de eventos disponibles para su organización también está disponible en GET /api/webhooks/events.

Reglas generales:

  • Los payloads solo contienen identificadores y campos seguros. Nunca se envía una credencial de dispositivo, token, contraseña, certificado ni enlace de descarga.
  • Las horas son texto ISO 8601 en UTC, excepto las horas de alarma, que son milisegundos desde la época.
  • Los eventos pueden llegar desordenados y, en raras ocasiones, dos veces. Deduplique por X-Webhook-Delivery y ordene por las horas del payload.
  • Los ejemplos muestran solo el event y el data del envoltorio; el envoltorio completo también incluye webhookId, tenantId y createdAt.

Dispositivos

EventoSe envía cuando
device.createdSe añadió un dispositivo: manualmente, desde una importación, por aprovisionamiento o reclamación, o como hijo de una pasarela
device.updatedCambiaron el nombre, la etiqueta, el tipo, el perfil, la marca de pasarela, la información adicional o el estado
device.deletedSe eliminó un dispositivo (manualmente, por una liberación o al deshacer una importación)
device.credentials_rotatedLa credencial fue rotada, reemplazada, renovada (X.509) o revocada
device.connectedUn dispositivo se conectó y permaneció conectado durante el tiempo de retención
device.disconnectedUn dispositivo se desconectó y permaneció desconectado durante el tiempo de retención
{ "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" } }

Un hijo de una pasarela también incluye 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 indica solo los nombres de los campos (ordenados: additionalInfo, isGateway, label, name, profileId, status, type), nunca sus valores. previousStatus está presente solo cuando cambió el estado. Una edición que no cambia ninguno de estos campos no envía nada.

{ "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 es rotated, replaced, renewed o revoked; tras revoked, credentialType es 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 es el /24 de una dirección IPv4 o el /48 de una dirección IPv6, nunca la dirección completa. reason es clean (el dispositivo se desconectó), timeout (se agotó su ventana de keep-alive o de uplink), kicked (el servidor lo cerró, por ejemplo tras un cambio de credencial) o quota (alcanzó un límite).

Tiempo de retención y volumen. Un cambio de conexión solo se envía después de mantenerse durante el tiempo de retención: Dispositivos > ajustes > Connection webhooks: hold time (seconds), por defecto 30, de 5 a 3.600. Un dispositivo que se cae y vuelve dentro de ese tiempo no envía nada. Por defecto se envían como máximo 600 eventos de conexión y 600 eventos de cambio de dispositivo por organización y minuto; el resto de ese minuto se descarta y sus propietarios y administradores reciben un aviso. Los dispositivos siguen siendo legibles a través de la API.

Alarmas

EventoSe envía cuando
alarm.createdSe abrió una alarma (una regla de perfil, un bloque de flujo o un operador). No se envía cuando una alarma abierta vuelve a activarse.
alarm.acknowledgedUn operador o un flujo reconoció una alarma abierta. Permanece abierta.
alarm.clearedUna alarma se resolvió: por su regla o flujo, por un operador, o porque se eliminó su dispositivo
{ "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 es la página de la alarma en la aplicación; anteponga su host y /tenant/<tenantId>.
  • backfilled: true marca una alarma abierta por lecturas tardías (por ejemplo, tras reproducir el buffer de una pasarela). Para estas no se notifica a nadie.
  • clearedBy es "rule" o { "userId": "…" }; reason es clear, manual o originator_deleted. metadata es null cuando una persona la resolvió.
  • Un cambio de severidad de una alarma abierta no envía webhook. Los webhooks de alarmas no tienen límite de volumen; el límite de tasa de su endpoint sigue aplicando.

Comandos

EventoSe envía cuando
rpc.completedUn comando terminó SUCCESSFUL (respondido, o un comando unidireccional fue entregado)
rpc.failedUn comando terminó FAILED, TIMEOUT (resultado desconocido) o EXPIRED (nunca llegó al dispositivo)
{ "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 respuesta en sí no está en el payload: léala con GET /api/iot/rpc/{rpcId}. Un comando cancelado no envía nada.

Firmware

EventoSe envía cuando
ota.update.initiatedSe entregó a un dispositivo un paquete de firmware para instalar
ota.update.succeededUn dispositivo ejecuta la versión objetivo
ota.update.failedLa actualización falló, agotó el tiempo o se revirtió
ota.rollout.wave_completedUna oleada superó sus controles
ota.rollout.pausedUn control falló o una persona pausó el despliegue
ota.rollout.resumedUna persona reanudó el despliegue
ota.rollout.completedLa última oleada superó sus controles
ota.rollout.abortedUna persona lo canceló, su asignación fue eliminada o reemplazada, o su paquete fue revocado
{ "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 es download, verify, update o rollback; error es el código del dispositivo, o un tiempo agotado.

{ "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 } }

Los payloads de despliegue incluyen rolloutId, assignmentId, packageId, status, wave (desde 1), waves y at, además de: updated, failures, successPct (oleada completada); reason y los recuentos (pausado; reason es failure_gate, success_gate, no_result (ningún dispositivo terminó) o manual); pausedReason (reanudado); updated (completado); reason (cancelado).

Aprovisionamiento

EventoSe envía cuando
iot.device.claimedUn dispositivo licenciado fue reclamado para su organización
iot.device.releasedUn dispositivo volvió al pool de fábrica: kind OWNER (usted lo liberó), FORCED (soporte de la plataforma) o DEVICE (desde la página propia del dispositivo)
{ "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" } }

Reglas

EventoSe envía cuando
rules.mode_changedUn lugar pasó a Manual, volvió a Auto, o su Manual terminó por sí solo
rules.needs_attentionUna regla se desactivó porque un dispositivo o el lugar que menciona ya no existe
{ "event": "rules.mode_changed", "data": {
  "placeType": "asset", "placeId": "77aa…", "placeName": "Greenhouse 2", "mode": "manual", "change": "manual",
  "actorId": "u-55…", "until": 1762700000000, "reason": "Harvest" } }

change es manual, auto o expired; actorId es null cuando un Manual terminó por sí solo. Un cambio de vuelta a Auto también incluye applyNow y rearmed.

{ "event": "rules.needs_attention", "data": {
  "ruleId": "ru-9…", "name": "Close vents at night", "reason": "…",
  "home": { "type": "asset", "id": "77aa…" } } }

Flujos

automation.message solo lo envía el bloque Webhook de un flujo, y únicamente al endpoint que indica el bloque (que debe suscribirse a «Automation message»). Incluye topic, payload, originator, flowId, flowVersion, nodeId, actor y las claves de metadata que lista el bloque, con X-Idempotency-Key. Véase Bloques de acción.

Otros eventos

  • esim.operation.succeeded y esim.operation.failed pertenecen a la gestión de eSIM, que está en desarrollo.
  • También se ofrecen eventos de claves de API (api_key.created, api_key.updated, api_key.rotated, api_key.deleted, api_key.expired) y de organización (miembros, invitaciones, suscripción). Sus payloads no se detallan en esta página.