Receive events by webhook

Subscribe to catalog events, verify the signature and reply in time.

GuideWith approvalSecret key
Before you start. Creating webhooks needs a secret key with the webhooks:write permission, which support approves: request it from Settings › API Keys.

Create the subscription

The response includes the secret used to sign deliveries. It’s shown only once: store it.

cURL
curl -X POST https://api.bydomu.com/v1/webhooks \
  -H "X-API-Key: $BYDOMU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://tu-servidor.com/webhooks/bydomu",
    "eventTypes": ["deal.won", "contact.*"],
    "description": "Negocios ganados y contactos"
  }'
Response · 201 · example
{
  "data": { "id": "clx1whk001", "secret": "whsec_…" }
}

Verify the signature

Every delivery carries X-Domu-Signature: t=…,v1=…: the HMAC-SHA256 of “timestamp.body” with your secret. Use the raw body, compare in constant time and reject old timestamps.

Node.js
import { createHmac, timingSafeEqual } from "node:crypto";

// header = X-Domu-Signature: t=<timestamp>,v1=<hmac>
function verifyWebhook(rawBody, header, secret, toleranceSec = 300) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const timestamp = Number(parts.t);
  if (!timestamp || !parts.v1) return false;
  if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSec) return false;
  const expected = createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(parts.v1);
  return a.length === b.length && timingSafeEqual(a, b);
}

Reply in time

Up to 5 attempts (0 s, 5 s, 30 s, 2 min and 10 min) on network errors, 429 or 5xx. Reply 2xx in under 10 s.

Each delivery’s id is stable: use it to drop duplicates.

Delivery · example
{
  "id": "5f3a0c1e-7d2b-4f7e-9a51-0b6c1d2e3f40",
  "type": "deal.won",
  "timestamp": "2026-09-22T14:30:00.000Z",
  "organizationId": "clx1org001",
  "actor": { "kind": "API", "userId": null },
  "data": { … }
}