Documentación pública

08 · Webhooks

MAG-08-HOOK · Webhooks

La mejor API responde cuando se le consulta. Una gran plataforma también sabe avisar cuando algo ocurre.

Toda la operación. Una sola plataforma.


Objetivo del capítulo

Definir el estándar oficial de Webhooks Roustix — el mecanismo mediante el cual la plataforma notifica eventos a sistemas externos en tiempo real.

Mientras la API REST (MAG-04) funciona bajo request → response, los Webhooks permiten que Roustix inicie la comunicación cuando ocurre un evento de negocio.

Los Webhooks forman parte del contrato público y utilizan el mismo modelo de autenticación, versionado y nomenclatura definido en MAG.


1 · Filosofía

REST responde. Webhooks notifican.

Cliente                    Roustix
   │                          │
   │  GET /assets             │
   │ ───────────────────────► │
   │ ◄─────────────────────── │
   │     response             │

vs

Orden creada
      │
      ▼
  Roustix
      │
 POST Webhook
      │
      ▼
Sistema externo

El objetivo es eliminar consultas periódicas (polling) innecesarias.


2 · Arquitectura

Evento de negocio
        │
        ▼
Módulo Roustix
        │
        ▼
Event Dispatcher
        │
        ▼
Firma HMAC
        │
        ▼
HTTP POST
        │
        ▼
Endpoint del cliente

Los eventos son generados por los módulos de negocio y enviados por un único servicio de Webhooks.


3 · Registro de Webhooks

Cada tenant puede registrar uno o varios endpoints.

POST /api/v1/admin/webhooks
Authorization: Bearer <token>
Content-Type: application/json
{
  "url": "https://empresa.com/webhooks/roustix",
  "events": [
    "work_order.created",
    "stock.low"
  ]
}

Respuesta:

{
  "data": {
    "id": 18,
    "status": "active"
  },
  "meta": {
    "api_version": "v1"
  }
}

El secret para HMAC se genera en el registro y se muestra una sola vez (roadmap: rotación en panel admin).


4 · Eventos oficiales

Todos los nombres siguen MAG-05:

  • inglés
  • snake_case en payload
  • eventos en dot notation (resource.action)

Maintenance

EventoEstado
asset.created📋
asset.updated📋
work_order.created📋
work_order.updated📋
work_order.closed📋

Inventory

EventoEstado
product.created📋
product.updated📋
stock.updated📋
stock.low📋
movement.created📋

Platform

EventoEstado
tenant.created📋
user.created📋
subscription.updated📋
plan.changed📋

Nuevos eventos → documentar aquí antes de implementar.


5 · Payload estándar

Todo webhook utiliza exactamente la misma estructura:

{
  "event": "work_order.created",
  "timestamp": "2026-07-10T18:30:00Z",
  "tenant": {
    "id": 4,
    "slug": "empresa-xyz"
  },
  "data": {
    "work_order_id": 128,
    "asset_id": 15,
    "status": "open"
  }
}
CampoDescripción
eventTipo de evento (dot notation)
timestampISO 8601 UTC
tenantTenant origen (id, slug)
dataInformación del recurso afectado

Claves en inglés — envelope alineado con MAG-04/MAG-05.


6 · Firma de seguridad

Cada entrega incluye:

X-Roustix-Timestamp: 1784664930
X-Roustix-Signature: v1=6f9c...
AspectoValor
AlgoritmoHMAC-SHA256
SecretoCompartido en registro del webhook
Inputtimestamp + "." + raw body JSON
Payload JSON
        │
        ▼
HMAC(secret)
        │
        ▼
SHA256
        │
        ▼
Header Signature

El receptor debe validar la firma en tiempo constante y rechazar timestamps

con más de cinco minutos de diferencia antes de procesar el evento.


7 · Reintentos

Respuesta clienteAcción
2xxEntregado · no reintentar
5xx · timeout · network errorReintento automático
408, 425, 429Reintentar; respetar Retry-After acotado
Otros 4xxNo reintentar · marcar fallo
IntentoEspera
1Inmediato
21 minuto
35 minutos
415 minutos
51 hora

Tras el intento 5 → estado FAILED · registrado · notificación al admin del tenant (roadmap).


8 · Idempotencia

Cada evento posee un identificador único:

X-Roustix-Event-Id: 6a1d92b4-8c3e-4f1a-9d2b-1e7f8a9b0c1d

El cliente debe almacenar ese ID para no procesar dos veces el mismo evento. Esto permite reintentos seguros.


9 · Versionado

Los Webhooks siguen la versión de la API: v1.

No incluyen versión en el nombre del evento.

✅ Correcto❌ Incorrecto
work_order.createdv1.work_order.created

Cambios incompatibles de payload → política MAG-07.


10 · Ejemplo completo

Evento: OT creada

POST https://empresa.com/webhooks/roustix
Content-Type: application/json
X-Roustix-Signature: sha256=...
X-Roustix-Timestamp: 1784664930
X-Roustix-Event-Id: 89fd...
{
  "event": "work_order.created",
  "timestamp": "2026-07-10T18:30:00Z",
  "tenant": {
    "id": 4,
    "slug": "empresa-xyz"
  },
  "data": {
    "work_order_id": 128,
    "status": "open"
  }
}

Respuesta esperada del cliente: HTTP 200 OK (≤ 5 s)

Errores de validación del endpoint receptor → fuera de alcance MAG; Roustix solo registra HTTP status.


11 · Auditoría

Todos los envíos quedan registrados.

Información almacenada:

  • evento
  • tenant
  • endpoint URL
  • fecha
  • respuesta HTTP
  • tiempo de respuesta
  • cantidad de reintentos
  • X-Roustix-Event-Id

No se almacena información sensible del payload cuando el plan de retención lo prohíba.

Alineado con MAG-06 · Auditoría de errores y MPA-07.


12 · Buenas prácticas

#Regla
1Validar siempre X-Roustix-Signature
2Responder rápidamente (≤ 5 s)
3Procesar de forma asíncrona cuando sea posible
4Implementar idempotencia usando X-Roustix-Event-Id
5No depender del orden de llegada de los eventos
6Responder 2xx únicamente cuando el evento haya sido aceptado
7Registrar errores para facilitar soporte

13 · Roadmap

Implementaciones futuras:

  • reenvío manual desde el panel
  • historial de entregas
  • filtros avanzados por módulo
  • firma rotativa de secretos
  • múltiples endpoints por entorno (test / production)
  • cola de eventos distribuida

Filosofía del capítulo

Una integración moderna no espera a que el cliente pregunte qué ocurrió. La plataforma informa los cambios en el momento en que suceden, de forma segura, verificable y predecible.

MAG-08 convierte a Roustix en una plataforma orientada a eventos, preparada para integrarse con ERP, CRM, Power BI, plataformas de mensajería y futuros servicios distribuidos.