eSMSAfrica
تقارير التنفيذ

How to receive SMS delivery reports (DLR)

Know exactly what happened to every SMS. eSMS Africa calls your webhook with each status change - sent, delivered, failed - in real time.

javascript
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
});

1. Set your webhook URL

Add a webhook in the dashboard (or over the API) and subscribe to delivery events. It must be a public HTTPS URL.

2. Receive the callback

eSMS POSTs a JSON body when a message status changes. Match it to the message id you stored when you sent.

javascript
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
});

3. Verify the signature

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.

javascript
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));
}
FAQ

Questions, answered

What statuses can a message have?

Typically queued, sent, delivered and failed. "sent" means the relay accepted it; "delivered" is confirmed by the operator; "failed" includes bounces.

Why verify the signature?

So an attacker cannot POST fake delivery events to your endpoint. Always check the HMAC before trusting the payload.