Ir al contenido

Webhooks

Keirost permite registrar endpoints HTTP que reciben notificaciones cuando ocurren eventos en el sistema. Así puedes integrar Keirost con sistemas externos (ERP externo, CRM, sistemas de contabilidad, etc.) en tiempo real.


interface Webhook {
id: string;
name: string; // "Mi integracion CRM"
url: string; // "https://mi-crm.com/webhook/keirost"
method: 'POST' | 'GET';
events: WebhookEvent[];
headers?: Record<string, string>;
secret?: string; // Para generar firma HMAC
status: 'active' | 'inactive';
retry_policy: RetryPolicy;
created_by: string;
created_at: string;
}
interface RetryPolicy {
max_attempts: number;
retry_delay_seconds: number[];
}
type WebhookEvent =
| 'document.created' | 'document.updated' | 'document.deleted'
| 'document.sent' | 'document.locked' | 'document.cancelled'
| 'payment.received' | 'payment.made'
| 'stock.movement' | 'stock.low'
| 'plugin.installed' | 'plugin.error'
| 'user.created' | 'user.deleted'
| 'automation.triggered' | 'notification.created'
| '*'; // wildcard = todos los eventos

Método Ruta Descripción
GET /api/webhooks Listar webhooks
POST /api/webhooks Crear webhook
GET /api/webhooks/:id Ver webhook
PATCH /api/webhooks/:id Actualizar webhook
DELETE /api/webhooks/:id Eliminar webhook
POST /api/webhooks/:id/test Enviar evento de prueba
GET /api/webhooks/:id/logs Ver logs de envíos
POST /api/webhooks
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "Integracion miERP",
"url": "https://mierp.com/webhook/keirost",
"method": "POST",
"events": ["document.created", "document.sent", "payment.received"],
"headers": {
"Authorization": "Bearer mi_api_key",
"Content-Type": "application/json"
},
"secret": "mi_webhook_secret_123",
"retry_policy": {
"max_attempts": 3,
"retry_delay_seconds": [60, 300, 900]
}
}
Evento Descripción
document.created Nuevo documento creado
document.updated Documento modificado
document.deleted Documento eliminado
document.sent Documento enviado por email
document.locked Documento asentado/bloqueado
document.cancelled Documento anulado
payment.received Pago recibido de cliente
payment.made Pago realizado a proveedor
stock.movement Movimiento de stock
stock.low Stock bajo el mínimo
user.created Nuevo usuario creado
user.deleted Usuario eliminado
automation.triggered Automatización ejecutada
notification.created Nueva notificación creada
plugin.installed Plugin instalado
plugin.error Error en plugin
* Todos los eventos

{
"id": "evt_001",
"event": "document.created",
"timestamp": "2026-05-08T10:00:00Z",
"tenant_id": "tenant_demo",
"data": { ... }
}
{
"id": "evt_001",
"event": "document.created",
"timestamp": "2026-05-08T10:00:00Z",
"tenant_id": "tenant_demo",
"data": {
"document_type": "sales_invoice",
"document_id": "inv_2026_0012",
"series": "F",
"number": 12,
"partner_id": "bp_cliente1",
"partner_name": "Acme S.L.",
"total": 1210.00,
"currency": "EUR",
"status": "draft",
"created_by": "user_admin",
"created_at": "2026-05-08T10:00:00Z"
}
}
{
"id": "evt_002",
"event": "payment.received",
"timestamp": "2026-05-08T10:00:00Z",
"tenant_id": "tenant_demo",
"data": {
"payment_id": "pay_in_001",
"partner_id": "bp_cliente1",
"amount": 1210.00,
"payment_date": "2026-05-08",
"payment_method": "transfer",
"linked_document": {
"type": "sales_invoice",
"id": "inv_2026_0012",
"new_status": "paid"
}
}
}

Si configuras un secret, Keirost firma cada petición con HMAC-SHA256:

X-Keirost-Signature: sha256=<hmac_hex>
X-Keirost-Timestamp: <unix_timestamp>
X-Keirost-Event: <event_name>
import crypto from 'crypto';
function verifyWebhookSignature(
payload: string,
signature: string,
timestamp: string,
secret: string
): boolean {
const body = `${timestamp}.${payload}`;
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return `sha256=${expected}` === signature;
}

También verifica que el timestamp no sea mayor de 5 minutos para evitar replay attacks.


GET /api/webhooks/:id/logs?from=2026-05-01&to=2026-05-08
{
"data": [
{
"id": "wlog_001",
"event": "document.created",
"document_id": "inv_2026_0012",
"attempt": 1,
"status": "success",
"http_status": 200,
"response_body": "OK",
"response_time_ms": 145,
"sent_at": "2026-05-08T10:00:00Z"
},
{
"id": "wlog_002",
"event": "document.created",
"document_id": "inv_2026_0013",
"attempt": 3,
"status": "failed",
"http_status": 503,
"error": "Service unavailable",
"sent_at": "2026-05-08T10:05:00Z"
}
]
}

Método Ruta Descripción
GET /api/webhooks Listar webhooks
POST /api/webhooks Crear webhook
GET /api/webhooks/:id Ver webhook
PATCH /api/webhooks/:id Actualizar webhook
DELETE /api/webhooks/:id Eliminar webhook
POST /api/webhooks/:id/test Enviar evento de prueba
GET /api/webhooks/:id/logs Ver logs de envíos