Overview
Webhooks push events to your server as they happen, no polling required.
Register a URL, choose which events you care about, and Messages.dev will POST
to it in real time.
Events
| Event | Description |
|---|
message.received | A new incoming message on the line |
message.sent | An outgoing message was delivered |
reaction.added | A reaction was added to a message |
reaction.removed | A reaction was removed |
typing.started | Someone started typing in a chat |
typing.stopped | Someone stopped typing |
receipt.read | A read receipt was received |
Creating a webhook
The easiest way to create a webhook is from the Webhooks page in your
dashboard. Click Add Webhook, enter your URL,
select the events you care about, and copy the signing secret.
The dashboard is the recommended way to manage webhooks. It shows the signing
secret once on creation and makes it easy to enable, disable, or delete
webhooks without writing code.
You can also create webhooks via the API:
import { createClient } from "@messages-dev/sdk";
const client = createClient();
const webhook = await client.createWebhook({
from: "+15551234567",
url: "https://your-server.com/webhooks",
events: ["message.received", "message.sent"],
});
Each webhook is scoped to a single line. Create one per line if you have
multiple lines.
POST /webhooks HTTP/1.1
Content-Type: application/json
X-Webhook-Signature: a1b2c3d4e5f6...
{
"event": "message.received",
"data": {
"object": "message",
"id": "msg_abc123",
"chat_id": "cht_def456",
"sender": "+15559876543",
"text": "Hey there!",
"is_from_me": false,
"sent_at": 1710000000000
},
"timestamp": 1710000000123
}
Verifying signatures
Every webhook delivery is signed with HMAC-SHA256. The SDK handles this automatically:
import { verifyWebhook } from "@messages-dev/sdk";
app.post("/webhooks", async (req, res) => {
const event = await verifyWebhook(
req.body,
req.headers["x-webhook-signature"],
"your_webhook_secret",
);
console.log(event.event, event.data);
res.sendStatus(200);
});
If the signature is invalid, verifyWebhook throws a SignatureVerificationError.
If you’re not using the SDK, verify manually:
import { createHmac } from "crypto";
function verifyWebhook(body, signature, secret) {
const expected = createHmac("sha256", secret)
.update(body)
.digest("hex");
return expected === signature;
}
Always verify the signature before processing a webhook payload. This
prevents attackers from sending forged events to your endpoint.
Deleting a webhook
You can delete webhooks from the Webhooks page in your dashboard, or in code:
await client.deleteWebhook({ id: "wh_abc123" });
When using the REST API directly, the webhook ID is passed in the request body, not in the URL path.