Delivery reports
Register a webhook and we post every delivery event the moment a network confirms it. No polling.
Register a webhook
curl https://api.sms.pesarails.com/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/hooks/sms",
"events": ["message.delivered", "message.undelivered"]
}'The response includes a signing secret, shown once. Store it to verify incoming events.
Events
| Event | When |
|---|---|
message.sent | Handed to the network. |
message.delivered | Confirmed on the handset. |
message.undelivered | The network could not deliver it. |
message.failed | Rejected before sending. Credit refunded. |
Leave events empty to receive all of them.
The payload
We POST JSON to your URL with the event, the message data, and a timestamp.
{
"event": "message.delivered",
"data": {
"messageId": "a1b2c3",
"to": "254712345678",
"description": "DeliveredToTerminal"
},
"timestamp": "2026-10-29T10:16:10.000Z"
}Verify the signature
Every request carries an x-rsms-signature header: an HMAC-SHA256 of the raw body, keyed
with your webhook secret. Verify it before trusting the payload.
import crypto from "node:crypto";
function verify(rawBody: string, signature: string, secret: string) {
const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}Tip
Respond 200 quickly and do your work afterwards. We retry on non-2xx responses, so make your handler idempotent.