Webhooks
Beamvia POSTs events to your URL as they happen. Respond with any 2xx within 10 seconds.
| event | When |
|---|---|
| MESSAGE_CREATED | A message was received or sent |
| MESSAGE_UPDATED | A message status changed (sent, delivered, read, failed) |
| CONVERSATION_UPDATED | Status, handler, priority or tags changed |
| CONTACT_UPDATED | A contact's profile or identities changed |
Payload
{
"id": "3b0b8f2e-6a1c-4f7e-9d0e-0b1c2d3e4f50",
"createdAt": "2026-10-20T08:00:00.000Z",
"workspaceId": "6650f0c2a1b2c3d4e5f60000",
"event": {
"type": "MESSAGE_CREATED",
"message": {
"id": "6650f0c2a1b2c3d4e5f60718",
"conversationId": "6650f0c2a1b2c3d4e5f60700",
"direction": "INBOUND",
"author": {
"type": "CONTACT",
"contactId": "6650f0c2a1b2c3d4e5f60690"
},
"content": {
"type": "TEXT",
"text": "Is my order shipped?"
},
"status": "SENT"
}
}
}Verify the signature
Each delivery carries X-Beamvia-Timestamp and X-Beamvia-Signature. The signature is sha256= + HMAC-SHA256 of timestamp.body with your webhook secret. Reject old timestamps.
Retries
Non-2xx responses and timeouts are retried 5 times with backoff. After 50 consecutive failures the webhook is switched off.
Verify
import crypto from "crypto";
// ** Express: use the raw body, not the parsed JSON
app.post("/beamvia", express.raw({ type: "application/json" }), (req, res) => {
const timestamp = req.header("X-Beamvia-Timestamp");
const signature = req.header("X-Beamvia-Signature");
const expected = "sha256=" + crypto.createHmac("sha256", process.env.BEAMVIA_WEBHOOK_SECRET).update(`${timestamp}.${req.body}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) < 300;
if (!fresh || !crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) return res.sendStatus(401);
const { event } = JSON.parse(req.body);
// ** handle event.type …
res.sendStatus(200);
});Create a webhook
Requires the webhook:manage scope. The response contains the signing secret.
Scope
webhook:manageurlstringrequiredHTTPS URL that receives the events.
eventsstring[]requiredEvents to deliver, e.g.
["MESSAGE_CREATED"].POSThttps://www.beamvia.com/api/v1/webhook
Create
curl -X POST "https://www.beamvia.com/api/v1/webhook" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/beamvia",
"events": [
"MESSAGE_CREATED",
"MESSAGE_UPDATED"
]
}'201 Created
{
"status": true,
"message": "OK",
"data": {
"webhook": {
"id": "6650f0c2a1b2c3d4e5f60900",
"url": "https://example.com/beamvia",
"secret": "whsec_…",
"events": [
"MESSAGE_CREATED",
"MESSAGE_UPDATED"
],
"isActive": true,
"failures": 0,
"delivery": {
"last": null
}
}
}
}Delete a webhook
Stops deliveries immediately.
Scope
webhook:manageDELETEhttps://www.beamvia.com/api/v1/webhook?id=:webhookId
Delete
curl -X DELETE "https://www.beamvia.com/api/v1/webhook?id=6650f0c2a1b2c3d4e5f60900" \
-H "Authorization: Bearer YOUR_API_KEY"200 OK
{
"status": true,
"message": "Deleted",
"data": null
}