Skip to content

Outbound webhooks ​

Abaco can notify your system when business events occur (documents, products, partners, payments). Configure the URL under Settings → Integrations → Webhooks; Abaco sends a HMAC-SHA256 signed POST.

The payload is compact: use your API key to hydrate details (GET /documents/:id, etc.).

Setup ​

  1. Sign in to abaco.
  2. Go to Settings → Integrations → Webhooks.
  3. Create a webhook with a name, HTTPS URL, and subscribed events.
  4. Save the signing secret (shown once). Use it to verify X-Abaco-Signature.

In non-production environments, http:// URLs are allowed for local testing.

Events ​

EventWhen
document.createdDocument created
document.confirmedDocument confirmed (or auto-confirmed on create)
document.dte_acceptedEl Salvador DTE accepted by Hacienda
document.cancelledDocument cancelled
product.created / product.updatedProduct created or updated
business_partner.created / business_partner.updatedBusiness partner created or updated
payment.created / payment.confirmedPayment registered or confirmed
webhook.testOnly via Test in the UI

Payload ​

json
{
  "event": "document.created",
  "companyId": 42,
  "resourceType": "document",
  "resourceId": 1001,
  "occurredAt": "2026-09-24T18:00:00.000Z",
  "data": {
    "IdFactura": 1001,
    "type": "01",
    "number": "00000123",
    "total": 150.5,
    "businessPartnerId": 77,
    "isConfirmed": false,
    "codigoGeneracion": null
  }
}

For documents, data.IdFactura is the same as Document.id / resourceId.

Headers ​

HeaderDescription
Content-Typeapplication/json
User-AgentAbaco-Webhooks/1.0
X-Abaco-EventEvent name
X-Abaco-Delivery-IdDelivery attempt id
X-Abaco-Signaturesha256=<hex> HMAC of the exact body

Verify the signature ​

Compute HMAC-SHA256 of the raw body (UTF-8 bytes of the JSON received) with the signing secret and compare to the value after sha256= in X-Abaco-Signature (constant-time compare).

js
const crypto = require('crypto');

function verifyAbacoSignature(rawBody, signatureHeader, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(rawBody, 'utf8')
    .digest('hex');
  const a = Buffer.from(expected);
  const b = Buffer.from(String(signatureHeader || ''));
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Delivery and retries ​

  • Timeout: 10 seconds.
  • Success: HTTP 2xx.
  • Retries: up to 3 with exponential backoff (BullMQ).
  • View history under Deliveries in the UI.

Security ​

  • Always use HTTPS in production.
  • Treat the secret like a password; rotate if leaked.
  • Respond quickly (2xx) and process asynchronously if work is heavy.
  • Idempotency: use X-Abaco-Delivery-Id or (event, resourceId, occurredAt).