LanguageENES
Destinations

Outgoing webhooks

Receive events in your own systems, and verify that they really came from us.

Updated 2026-09-05

The events

  • lead.created — a visitor left their details.
  • conversation.completed — someone marked a conversation closed or escalated.
  • document.indexed — a document finished indexing and can be answered from.
  • document.failed — a document could not be indexed.
  • sync.completed — a connected source finished a sync run.

Adding an endpoint

In Destinations → Webhooks, add a public https URL and tick the events you want. We show the signing secret once, when the endpoint is created and whenever you rotate it. Store it then; we only keep a hash of it afterwards.

Use Send a test to fire a real delivery with sample data: same signature, same retries, same log.

The envelope

We POST JSON with two headers that matter:

X-WelcomeAI-Signature: t=1788639323,v1=6f3a...
X-WelcomeAI-Event: lead.created

The body looks like this:

{
  "id": "evt_2b91Ha0Kd3fQ",
  "type": "lead.created",
  "created_at": "2026-09-05T20:15:23.201Z",
  "org_id": "org_UWzIf5jv8lW2",
  "data": { "lead_id": "ld_GSTPfNF6SEkE", "email": "grace@example.com" }
}

Verifying a delivery

Take t and v1 from the signature header. Compute HMAC-SHA256 over the timestamp, a dot, and the raw request body, using your signing secret. Compare it with v1 using a constant-time comparison, and reject anything where t is more than five minutes old.

const [t, v1] = header.split(",").map((p) => p.split("=")[1]);
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));

Use the raw body, not a re-serialized object: any difference in whitespace or key order changes the digest.

Retries

We try six times: after 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours and 24 hours. Every attempt is signed again, so a retry never arrives with a stale timestamp.

Anything in the 2xx range means delivered. 410 Gone means stop sending and we do not retry. Everything else is retried, including 4xx, because a receiver that deploys badly should not lose events.

An endpoint that fails twenty times in a row is switched off, and you can turn it back on once the receiver is fixed.

Duplicates

The same event id can arrive more than once, for example if your acknowledgement was lost. Treat id as the deduplication key.

Put your knowledge to work today

Free for 14 days. No card, and nothing to install on your site.