Outbound webhooks

Receive signed events when something happens in Vicero.

Register an endpoint and Vicero will POST to it when things happen — a message arrives, a conversation closes, a document finishes ingesting, a visitor asks for a human.

Registering

Settings → Webhooks, or POST /v1/webhooks. You give a URL and choose which events you want. Vicero gives you a signing secret, shown once.

The event catalog

EventFires when
message.createdAny message is added to a conversation — visitor, agent or operator
conversation.createdA new conversation starts
conversation.closedA conversation is closed
handoff.requestedA conversation needs a human
handoff.resolvedA human handed it back
document.readyA knowledge-base document finished ingesting and is searchable
document.failedIngestion failed
tool.runA tool was called
usage.thresholdUsage crossed a configured threshold

GET /v1/webhooks/events returns this list from the live API.

Verifying the signature

Every delivery carries X-Vicero-Signature, an HMAC-SHA256 over the request body using your endpoint secret.

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

function verify(rawBody, signature, secret) {
  const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(signature);
  // Length-check first: timingSafeEqual throws on a mismatch rather than returning false.
  return a.length === b.length && timingSafeEqual(a, b);
}

Two things that are easy to get wrong:

  • Verify against the raw body, before any JSON parsing. Re-serializing changes whitespace and key order, and the signature will never match.
  • Compare in constant time. A plain === on a signature leaks, one byte at a time, how much of a guess was right.

Retries

A delivery is considered successful on any 2xx. Anything else is retried with exponential backoff, and a periodic sweep re-enqueues deliveries lost to downtime — so an endpoint that was down for an hour receives what it missed rather than nothing.

Because of that, handle duplicates. At-least-once delivery means you will eventually receive the same event twice; key on the event's id and make your handler idempotent.

Delivery history, including the response you returned, is visible per endpoint in the dashboard and at GET /v1/webhooks/{endpoint_id}/deliveries.

Testing

POST /v1/webhooks/{endpoint_id}/test sends a sample delivery, signed the same way as a real one — the fastest way to check your verification code before you depend on it.