Referencia de endpoints

Catálogo completo del API. Todas las rutas están bajo el prefijo https://www.rud1.es/api/v1/public.

Resumen

MétodoRutaScopeDescripción
GET/devicesdevices:readListar dispositivos
GET/devices/{id}devices:readDetalle de un dispositivo
GET/devices/{id}/metricsmetrics:readSeries temporales de métricas
GET/devices/{id}/eventslogs:readEventos del dispositivo
GET/devices/{id}/serialdevices:readEstado y configuración de la E/S industrial
PATCH/devices/{id}/serialdevices:writeModo de uso y reenvío de señales
GET/devices/{id}/serial/telemetrydevices:readÚltimas señales recibidas
GET/devices/{id}/serial/channels/{channelId}devices:readDetalle de un canal
PUT/devices/{id}/serial/channels/{channelId}devices:writeConfigurar un canal (incluye envío periódico)
GET/alertsalerts:readListar alertas
POST/alerts/{id}/acknowledgealerts:writeReconocer una alerta
POST/alerts/{id}/resolvealerts:writeResolver una alerta

💡 Todas las respuestas incluyen los headers X-RateLimit-*. Las listas son cursor-paginadas: usa el campo nextCursor de la respuesta como valor de ?cursor=… para la siguiente página.

Dispositivos

GET /devices

Lista los dispositivos de la organización de la clave API.

ParámetroTipoDescripción
limit1..100 (default 25)Tamaño de página
cursorcuidCursor opaco para paginar
statusDeviceStatusONLINE / OFFLINE / CONNECTING / ERROR / PROVISIONING / REBOOTING / UPDATING
ejemplo
GET /api/v1/public/devices?status=ONLINE&limit=10
Authorization: Bearer rud1_sk_...

200 OK
{
  "data": [
    {
      "id": "clxxxxxxxxxxxxxxxxxxxxxxx",
      "name": "PLC línea 3",
      "serialNumber": "RUD1-000123",
      "status": "ONLINE",
      "model": "Rud1 Mini",
      "firmwareVersion": "1.4.2",
      "lastSeen": "2026-05-05T22:11:38.512Z",
      "ipAddress": "192.168.1.42",
      "location": "Planta 2 - Norte",
      "createdAt": "2026-04-12T10:00:00.000Z"
    }
  ],
  "pagination": { "nextCursor": null, "hasMore": false }
}

GET /devices/{id}

Devuelve el detalle de un dispositivo. Si el ID no pertenece a tu organización responde 404 not_found (no revelamos la existencia de recursos de otras organizaciones).

ejemplo
GET /api/v1/public/devices/clxxxxxxxxxxxxxxxxxxxxxxx
Authorization: Bearer rud1_sk_...

200 OK
{
  "data": {
    "id": "clxxxxxxxxxxxxxxxxxxxxxxx",
    "name": "PLC línea 3",
    "serialNumber": "RUD1-000123",
    "status": "ONLINE",
    "model": "Rud1 Mini",
    "firmwareVersion": "1.4.2",
    "lastSeen": "2026-05-05T22:11:38.512Z",
    "ipAddress": "192.168.1.42",
    "location": "Planta 2 - Norte",
    "notes": null,
    "agentDeviceName": "rud1-planta2",
    "agentDeviceLocation": "Planta 2 - Norte",
    "agentTimezone": "Europe/Madrid",
    "createdAt": "2026-04-12T10:00:00.000Z"
  }
}

GET /devices/{id}/metrics

Series temporales de métricas de sistema (CPU, memoria, disco, temperatura, carga). El agente captura una muestra cada ~5 minutos.

ParámetroTipoDescripción
fromISO 8601Inicio del rango (default: hace 1 hora)
toISO 8601Fin del rango (default: ahora)
limit1..1000 (default 200)Máximo de muestras
ejemplo
GET /api/v1/public/devices/clxx.../metrics?from=2026-05-05T20:00:00Z
Authorization: Bearer rud1_sk_...

200 OK
{
  "data": [
    {
      "capturedAt": "2026-05-05T22:10:00.000Z",
      "cpuPct": 18.4,
      "memPct": 41.2,
      "diskUsedPct": 32.8,
      "tempCpu": 48.1,
      "loadAvg1": 0.42
    }
  ],
  "window": {
    "from": "2026-05-05T20:00:00.000Z",
    "to": "2026-05-05T22:11:38.512Z"
  }
}

GET /devices/{id}/events

Stream de eventos del dispositivo: heartbeats, alertas que se abren y se resuelven, ciclo de vida del agente, USB, etc.

ParámetroTipoDescripción
limit1..200 (default 50)Tamaño de página
cursorcuidCursor de paginación
severitystringFiltrar por INFO, WARNING, ERROR o CRITICAL
typestringFiltrar por tipo (ej. 'alert.high_cpu')
ejemplo
GET /api/v1/public/devices/clxx.../events?severity=ERROR&limit=10
Authorization: Bearer rud1_sk_...

200 OK
{
  "data": [
    {
      "id": "clyyyyyyyyyyyyyyyyyyyyyyy",
      "type": "alert.vpn_down",
      "severity": "ERROR",
      "message": "Secure tunnel 'wg0' is disconnected",
      "data": {
        "interfaceName": "wg0",
        "endpoint": "203.0.113.1:51820",
        "peerCount": 2
      },
      "createdAt": "2026-05-05T22:09:14.000Z"
    }
  ],
  "pagination": { "nextCursor": "clzzz...", "hasMore": true }
}

E/S industrial (serial)

Configuración y lectura del puerto industrial: UART, RS485, CAN-FD y GPIO. Sólo responde en dispositivos cuyo modelo tenga la capability serial.io; si no, devuelve 409 capability_unavailable.

GET /devices/{id}/serial

Estado completo: modo de uso, reenvío, y cada canal del conector con su configuración y su último valor recibido.

ejemplo
GET /api/v1/public/devices/clxx.../serial
Authorization: Bearer rud1_sk_...

200 OK
{
  "data": {
    "deviceId": "clxxxxxxxxxxxxxxxxxxxxxxx",
    "enabled": true,
    "mode": "managed",
    "forwarding": {
      "webhookUrl": "https://tu-servidor/rud1/serial",
      "webhookEnabled": true
    },
    "channels": [
      {
        "id": "rs485-0",
        "group": "rs485",
        "label": "RS485 · 1",
        "terminals": ["a1", "b1"],
        "configurable": true,
        "available": true,
        "config": {
          "kind": "rs485",
          "baudRate": 9600,
          "dataBits": 8,
          "parity": "none",
          "stopBits": 1,
          "mode": "modbus-rtu-master",
          "slaveId": 1,
          "tx": { "enabled": false, "intervalMs": 1000, "register": 0, "value": 1 }
        },
        "telemetry": { "live": "0x0012", "txOn": false, "error": "" }
      }
    ],
    "telemetryAt": "2026-05-05T22:11:38.512Z"
  }
}

PATCH /devices/{id}/serial

Cambia el modo de uso y/o el reenvío de señales. Envía al menos uno de mode, webhookUrl o webhookEnabled.

CampoTipoDescripción
modemanaged | passthrough | bothGestionado desde el panel, expuesto en crudo por VPN, o ambos
webhookUrlhttps URL | nullDestino del reenvío. null lo borra. Sin credenciales en la URL
webhookEnabledbooleanActiva o pausa el reenvío
ejemplo
PATCH /api/v1/public/devices/clxx.../serial
Authorization: Bearer rud1_sk_...
Content-Type: application/json

{ "mode": "managed", "webhookUrl": "https://tu-servidor/rud1/serial", "webhookEnabled": true }

200 OK
{
  "data": {
    "deviceId": "clxxxxxxxxxxxxxxxxxxxxxxx",
    "mode": "managed",
    "forwarding": {
      "webhookUrl": "https://tu-servidor/rud1/serial",
      "webhookEnabled": true
    }
  }
}

PUT /devices/{id}/serial/channels/{channelId}

Configura un canal. El kind del cuerpo debe coincidir con el grupo del canal (400 kind_mismatch si no). El bloque tx es el envío de señales: con enabled: true el dispositivo transmite el valor cada intervalMs (0 = envío único).

ejemplo
PUT /api/v1/public/devices/clxx.../serial/channels/canfd-0
Authorization: Bearer rud1_sk_...
Content-Type: application/json

{
  "kind": "canfd",
  "nominalBitrate": 500000,
  "dataBitrate": 2000000,
  "samplePoint": 0.75,
  "listenOnly": false,
  "tx": { "enabled": true, "intervalMs": 1000, "canId": "100", "dataHex": "00 01" }
}

200 OK
{
  "data": {
    "deviceId": "clxxxxxxxxxxxxxxxxxxxxxxx",
    "channelId": "canfd-0",
    "config": { "kind": "canfd", "nominalBitrate": 500000, "...": "..." }
  }
}

GET /devices/{id}/serial/telemetry

Recepción de señales por sondeo: último valor que el dispositivo reportó en su heartbeat. at es null si aún no ha reportado ninguno.

ejemplo
GET /api/v1/public/devices/clxx.../serial/telemetry
Authorization: Bearer rud1_sk_...

200 OK
{
  "data": {
    "deviceId": "clxxxxxxxxxxxxxxxxxxxxxxx",
    "at": "2026-05-05T22:11:38.512Z",
    "channels": [
      { "id": "rs485-0", "live": "0x0012", "txOn": false, "error": "" },
      { "id": "canfd-0", "live": "100#0001", "txOn": true, "error": "" }
    ]
  }
}

Reenvío por webhook

Con el reenvío activo, cada heartbeat que traiga un cambio en una señal genera un POST a tu URL con los canales que cambiaron. Se reintenta con backoff hasta 5 veces y va firmado con X-Rud1-Signature (HMAC-SHA256 del cuerpo), igual que los webhooks de alertas.

cuerpo entregado
POST https://tu-servidor/rud1/serial
X-Rud1-Signature: sha256=...
X-Rud1-Delivery-Id: cldddddddddddddddddddddd
X-Rud1-Attempt: 1

{
  "event": "serial.signal",
  "deviceId": "clxxxxxxxxxxxxxxxxxxxxxxx",
  "at": "2026-05-05T22:11:38.512Z",
  "channels": [
    { "id": "rs485-0", "live": "0x0012", "txOn": false, "error": "" }
  ]
}

💡 Responde 2xx para confirmar la entrega. Cualquier 5xx, 408, 425 o 429 se reintenta; el resto se descarta sin reintento.

Alertas

GET /alerts

Lista las alertas de tu organización. Por defecto solo devuelve las que están en estado ACTIVE.

ParámetroTipoDescripción
stateACTIVE | ACKNOWLEDGED | RESOLVEDEstado a filtrar (default ACTIVE)
severitystringINFO / WARNING / ERROR / CRITICAL
deviceIdcuidFiltrar por un dispositivo concreto
limit1..100 (default 25)Tamaño de página
cursorcuidCursor de paginación
ejemplo
GET /api/v1/public/alerts?state=ACTIVE&severity=CRITICAL
Authorization: Bearer rud1_sk_...

200 OK
{
  "data": [
    {
      "id": "claaaaaaaaaaaaaaaaaaaaaaa",
      "state": "ACTIVE",
      "severity": "CRITICAL",
      "message": "CPU usage 96.4% exceeds 90%",
      "payload": { "cpuUsage": 96.4, "threshold": 90 },
      "deviceId": "clxxxxxxxxxxxxxxxxxxxxxxx",
      "ruleId": "clrrrrrrrrrrrrrrrrrrrrrrrrr",
      "acknowledgedAt": null,
      "resolvedAt": null,
      "createdAt": "2026-05-05T22:08:01.123Z"
    }
  ],
  "pagination": { "nextCursor": null, "hasMore": false }
}

POST /alerts/{id}/acknowledge

Marca una alerta como reconocida. Idempotente: si ya está reconocida, devuelve la fila sin cambios. Si la alerta ya está RESOLVED responde 409 alert_already_resolved.

ejemplo
POST /api/v1/public/alerts/claaa.../acknowledge
Authorization: Bearer rud1_sk_...

200 OK
{
  "data": {
    "id": "claaaaaaaaaaaaaaaaaaaaaaa",
    "state": "ACKNOWLEDGED",
    "severity": "CRITICAL",
    "message": "CPU usage 96.4% exceeds 90%",
    "acknowledgedAt": "2026-05-05T22:12:00.000Z",
    "resolvedAt": null,
    "createdAt": "2026-05-05T22:08:01.123Z"
  }
}

POST /alerts/{id}/resolve

Marca la alerta como resuelta. Idempotente: si ya estaba resuelta no cambia el resolvedAt original — el timestamp se preserva como evidencia del primer cierre.

ejemplo
POST /api/v1/public/alerts/claaa.../resolve
Authorization: Bearer rud1_sk_...

200 OK
{
  "data": {
    "id": "claaaaaaaaaaaaaaaaaaaaaaa",
    "state": "RESOLVED",
    "severity": "CRITICAL",
    "message": "CPU usage 96.4% exceeds 90%",
    "acknowledgedAt": "2026-05-05T22:12:00.000Z",
    "resolvedAt": "2026-05-05T22:14:33.000Z",
    "createdAt": "2026-05-05T22:08:01.123Z"
  }
}

ℹ️ Reconocer ≠ resolver. ACKNOWLEDGED indica que alguien ha visto la alerta y está actuando sobre ella; RESOLVED indica que la condición se ha corregido. Una alerta puede pasar directamente de ACTIVE a RESOLVED sin pasar por ACKNOWLEDGED.