Webhooks
Recibe notificaciones en tiempo real cuando ocurren eventos en Holded.
Descripción general
Los webhooks te permiten recibir notificaciones HTTP POST cuando ocurren eventos en tu cuenta de Holded, como la creación de una nueva factura o la recepción de un pago.
Configurar webhooks
Configura los webhooks en tu panel de Holded en Ajustes > Webhooks. Necesitarás proporcionar:
- Una URL HTTPS accesible públicamente
- Los eventos a los que quieres suscribirte
Cabeceras comunes
Cada petición de webhook incluye estas cabeceras:
x-holded-webhook-eventstringNombre del evento, p. ej. invoice.create
x-holded-webhook-datestring · ISO 8601Momento del envío, p. ej. 2026-06-18T11:10:35Z
x-holded-webhook-signaturestringFirma HMAC-SHA256 con prefijo sha256= (ver abajo)
x-holded-webhook-idstringIdentificador único del evento; úsalo como clave de idempotencia
x-holded-webhook-account-idstringIdentificador de la cuenta de Holded que origina el evento
x-holded-webhook-versionstringVersión del sistema de webhooks (p. ej. v1)
Eventos disponibles
Los webhooks están disponibles para los siguientes grupos de eventos. Haz clic en un grupo para ver sus eventos y detalles del payload.
Facturas
4 eventosinvoice.createinvoice.updateinvoice.deleteinvoice.approveFacturas rectificativas
4 eventoscreditnote.createcreditnote.updatecreditnote.deletecreditnote.approveFacturas proforma
3 eventosproform.createproform.updateproform.deleteRecibos de venta
4 eventossalesreceipt.createsalesreceipt.updatesalesreceipt.deletesalesreceipt.approveCotizaciones
3 eventosestimate.createestimate.updateestimate.deletePedidos de venta
3 eventossalesorder.createsalesorder.updatesalesorder.deleteNotas de entrega
3 eventoswaybill.createwaybill.updatewaybill.deleteServicios
3 eventosservice.createservice.updateservice.deleteCompras
4 eventospurchase.createpurchase.updatepurchase.deletepurchase.approveReembolsos de compra
4 eventospurchaserefund.createpurchaserefund.updatepurchaserefund.deletepurchaserefund.approveRecibos
3 eventosreceipt.createreceipt.updatereceipt.deletePedidos de compra
3 eventospurchaseorder.createpurchaseorder.updatepurchaseorder.deleteNotas de recepción
4 eventosreceiptnote.createreceiptnote.updatereceiptnote.deletereceiptnote.approvePagos
3 eventospayment.createpayment.updatepayment.deleteContactos
3 eventoscontact.createcontact.updatecontact.deleteProductos
3 eventosproduct.createproduct.updateproduct.deleteStock
1 eventosstock.updateAlmacenes
3 eventoswarehouse.createwarehouse.updatewarehouse.deleteVerificar webhooks
Cada petición de webhook incluye una cabecera de firma (x-holded-webhook-signature) que deberías verificar para confirmar que la petición proviene de Holded. La firma es un resumen hexadecimal HMAC-SHA256 del cuerpo en bruto de la petición, firmado con tu secreto de webhook y con el prefijo sha256=.
const crypto = require('crypto');
// Use the raw request body, not the parsed JSON object
app.post('/holded-webhook', express.raw({ type: 'application/json' }), (req, res) => {
const secret = process.env.HOLDED_WEBHOOK_SECRET; // whsec_...
// The header arrives with a "sha256=" prefix; strip it before comparing
const received = (req.header('x-holded-webhook-signature') || '').replace(/^sha256=/, '');
const expected = crypto.createHmac('sha256', secret).update(req.body).digest('hex');
const valid = received.length === expected.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
if (!valid) return res.status(401).send('Invalid signature');
const event = req.header('x-holded-webhook-event');
const data = JSON.parse(req.body.toString('utf8'));
// ... process the event and acknowledge
res.sendStatus(200);
});Respuesta esperada
Tu endpoint debe devolver cualquier código de estado 2xx para confirmar la recepción. Si no recibimos una respuesta 2xx, reintentaremos la entrega con backoff exponencial.