Know exactly what happened to every SMS. eSMS Africa calls your webhook with each status change - sent, delivered, failed - in real time.
import express from "express";
const app = express();
app.use(express.json());
app.post("/webhooks/sms", (req, res) => {
const { message_id, status, phone } = req.body;
// status: "delivered" | "failed" | ...
updateMessageStatus(message_id, status);
res.sendStatus(200); // ack quickly
});Add a webhook in the dashboard (or over the API) and subscribe to delivery events. It must be a public HTTPS URL.
eSMS POSTs a JSON body when a message status changes. Match it to the message id you stored when you sent.
import express from "express";
const app = express();
app.use(express.json());
app.post("/webhooks/sms", (req, res) => {
const { message_id, status, phone } = req.body;
// status: "delivered" | "failed" | ...
updateMessageStatus(message_id, status);
res.sendStatus(200); // ack quickly
});Each webhook is signed with HMAC-SHA256 in the X-Webhook-Signature header. Recompute it with your signing secret and reject anything that does not match.
import crypto from "crypto";
function verify(rawBody, signature, secret) {
const expected = "sha256=" +
crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}Typically queued, sent, delivered and failed. "sent" means the relay accepted it; "delivered" is confirmed by the operator; "failed" includes bounces.
So an attacker cannot POST fake delivery events to your endpoint. Always check the HMAC before trusting the payload.