Incoming messages, reactions, and delivery events arrive as signed HTTPS
POSTs to a URL you control. You write the handler once and it runs
unchanged in dev and in production.
1. Handle the event
import { verifyWebhook } from "@messages-dev/sdk";
app.post("/webhooks", async (req, res) => {
const event = await verifyWebhook(
req.body,
req.headers["x-webhook-signature"],
process.env.WEBHOOK_SECRET!,
);
if (event.event === "message.received") {
console.log(`${event.data.sender}: ${event.data.text}`);
}
res.sendStatus(200);
});
verifyWebhook handles HMAC-SHA256 verification, timing-safe comparison,
and replay protection, then returns a typed discriminated-union event. If
you’re not using the SDK, see the manual verification snippets in
Webhooks › Verifying signatures.
2. Stream events to your handler (local dev)
The fastest way to drive your handler while you’re building is the
messages-dev CLI. It POSTs each real account event to a local
URL with the same headers a registered webhook would, so you don’t need a
public URL or a webhook registration.
Install the CLI and authenticate, then:
messages-dev listen --forward-to http://localhost:3000/webhooks
The CLI prints a per-session HMAC secret on first run. Set it as
WEBHOOK_SECRET in your handler, or pin one with
MESSAGES_LISTEN_SECRET=… so it doesn’t rotate between runs.
Without --forward-to, messages-dev listen prints events to your
terminal as they happen. Useful for tailing a line while you debug.
3. Register a webhook (production)
When you’re ready to deploy, go to the Webhooks page in your
dashboard, click Add Webhook, enter your
public HTTPS endpoint, and copy the signing secret into your environment as
WEBHOOK_SECRET. The handler from step 1 is unchanged.
You can also create webhooks via the API
if you need to provision them programmatically.
Next steps
- Webhooks — full event list, payload shapes, and
replay-protection rules.
- CLI reference —
listen filtering flags, output modes, and
other recipes.
Prefer to use ngrok, Cloudflare Tunnel, or another
tunnel for local dev? Expose your local server on a public URL and
register a regular webhook pointing at it. Same payload, same handler
code — see Webhooks for setup.