Webhooks
Webhooks push Loopwave events to a URL you control, in real time. Because Loopwave can deliver any event to any HTTPS endpoint, you can connect Loopwave to virtually any tool — a CRM, a spreadsheet automation, a workflow builder, or your own backend — without per-vendor connectors. If a system can receive an HTTP POST, it can react to Loopwave.
Events
Subscribe a webhook to one or more of these events:
| Event | Fires when |
|---|---|
message.created | A message is sent or received. |
chats.updated | A chat changes (status, assignment, new activity). |
session.status | A connected number changes connection state. |
session.removed | A number is unlinked. |
broadcast.progress | A broadcast advances (sent/failed counts update). |
Payload format
Every delivery is a JSON POST with a consistent envelope:
{
"event": "message.created",
"data": { },
"timestamp": "2026-06-29T10:15:00.000Z"
}data carries the event-specific payload; timestamp is the ISO-8601 send time.
Verifying signatures
Each delivery includes an HMAC signature so you can confirm it genuinely came from your Loopwave instance and wasn’t tampered with.
- Header:
X-Loopwave-Signature - Format:
sha256=<hex> - Computation: HMAC-SHA256 of the exact JSON body using your webhook’s secret.
Always verify the signature before trusting a payload, and compare using a constant-time comparison. Compute the HMAC over the raw request body bytes.
import crypto from 'node:crypto';
function verify(rawBody, signatureHeader, secret) {
const expected =
'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const a = Buffer.from(signatureHeader || '');
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
// Express: capture the raw body so the bytes match exactly.
// app.use(express.json({ verify: (req, _res, buf) => { req.rawBody = buf; } }));
app.post('/loopwave-webhook', (req, res) => {
if (!verify(req.rawBody, req.header('X-Loopwave-Signature'), process.env.LOOPWAVE_SECRET)) {
return res.status(401).end();
}
const { event, data } = req.body;
// ...handle event...
res.status(200).end();
});import hmac, hashlib
def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature_header or "")
@app.post("/loopwave-webhook")
def hook():
if not verify(request.get_data(), request.headers.get("X-Loopwave-Signature"), SECRET):
return ("", 401)
payload = request.get_json()
# ...handle payload["event"]...
return ("", 200)Setting up a webhook
- Create the webhook (admin)
In the dashboard, add a webhook with a name, your endpoint URL, and the events to subscribe to. Set a secret (8+ characters) so deliveries are signed.
- Send a test delivery
Use the test action to POST a sample
testevent to your URL and confirm your endpoint receives and verifies it. - Go live
Once verified, your endpoint will receive real events as they happen.
The test delivery looks like:
{
"event": "test",
"data": { "message": "Test delivery from Loopwave", "webhook": "My CRM sync" },
"timestamp": "2026-06-29T10:15:00.000Z"
}Delivery, retries & timeouts
| Behavior | Value |
|---|---|
| Request timeout | 5 seconds |
| Retries | Up to 2 additional attempts after the first |
| Backoff | Linear (attempt number x 300ms) |
| Recorded per webhook | Last delivery time, last status, last error |
Respond with a 2xx status quickly to acknowledge receipt. If your endpoint times out
or errors, Loopwave retries with a short backoff, then records the failure (HTTP status,
or timeout/error) on the webhook so you can diagnose it.
Make your handler idempotent. A retry can deliver the same event more than once, so key on the event content (or your own dedupe id) rather than assuming exactly-once delivery.
Managing webhooks
Webhook management is admin-only: create, update, send a test, and delete. Each webhook can be enabled or disabled without deleting it.
Drive Loopwave from your code→Pair outbound webhooks with the REST API to build full integrations.