Webhooks
VisitorFlow signs every webhook payload with HMAC-SHA256 and retries with exponential backoff for 24 hours. Subscribe per event to keep payloads tight.
Subscribe to an endpoint
From the dashboard, go to Settings → API & webhooks → Endpoints. Add the URL, pick events, and copy the signing secret — you cannot recover it later.
Headers
Every delivery carries three headers:
x-vf-signature—sha256=<hex>, the HMAC-SHA256 of the exact raw request body.x-vf-event— the event type (e.g.visitor.checked_in).x-vf-delivery— the unique delivery id (matchesidin the body).
Verify signatures
Sign the exact bytes you received — do not re-serialize the JSON, or key ordering will break the comparison. There is no timestamp in the signed string.
import crypto from 'node:crypto';
function verify(req, secret) {
// Header format: "x-vf-signature: sha256=<hex>"
const header = req.headers['x-vf-signature'] ?? '';
const body = req.rawBody; // raw string/Buffer, NOT JSON.parse'd
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
const got = header.replace(/^sha256=/, '');
if (got.length !== expected.length) return false;
return crypto.timingSafeEqual(
Buffer.from(got, 'hex'),
Buffer.from(expected, 'hex'),
);
}Event payload
{
"id": "evt_2YZ4...",
"event": "visitor.checked_in",
"tenantId": "tnt_01",
"sentAt": "2026-04-30T14:21:09Z",
"data": {
"visit_id": "vis_2YZ4...",
"visitor": { "name": "Marisol Cruz", "company": "Acme" },
"host_id": "h_98412",
"location_id": "loc_mty_01"
}
}Retries & replay
We retry on any non-2xx response with exponential backoff (up to 24 hours). Failed deliveries appear in Webhooks → Deliveries with the response body and you can replay any of them with one click.
Available events
visitor.checked_invisitor.checked_outvisitor.no_showdriver.cargo_selecteddriver.dock_assignedhost.notifiedprereg.createdprereg.scannedwatchlist.matchincident.createdincident.resolvednda.acceptedbadge.printedlead.captured