Docs
DocumentationExamplesDashboard →

Getting Started

  • Introduction
  • Authentication
  • Base URL

API Reference

  • Sending SMS
  • Scheduled SMS
  • Sender IDs

Resources

  • Error Responses
  • Code Examples

Webhooks

Webhooks allow you to receive real-time notifications about message delivery status.

Overview

When the status of your SMS changes (delivered, failed, etc.), we send an HTTP POST request to your configured webhook URL.

Setting Up Webhooks

  1. Log in to your dashboard
  2. Navigate to Settings → Webhooks
  3. Enter your webhook URL
  4. Select the events you want to receive
  5. Save your configuration

Webhook Events

EventDescription
message.sentMessage accepted by carrier
message.deliveredMessage delivered to recipient
message.failedMessage delivery failed
message.expiredMessage expired before delivery

Webhook Payload

All webhook requests are POST requests with JSON body:

{
  "event": "message.delivered",
  "timestamp": "2026-03-09T15:30:00Z",
  "data": {
    "messageId": "msg_abc123xyz789",
    "recipient": "233200000000",
    "senderId": "MyBusiness",
    "status": "delivered",
    "deliveredAt": "2026-03-09T15:30:00Z"
  }
}

Event Examples

Message Delivered

{
  "event": "message.delivered",
  "timestamp": "2026-03-09T15:30:00Z",
  "data": {
    "messageId": "msg_abc123",
    "recipient": "233200000000",
    "status": "delivered",
    "deliveredAt": "2026-03-09T15:30:00Z"
  }
}

Message Failed

{
  "event": "message.failed",
  "timestamp": "2026-03-09T15:30:00Z",
  "data": {
    "messageId": "msg_abc123",
    "recipient": "233200000000",
    "status": "failed",
    "error": "Invalid phone number",
    "errorCode": "INVALID_RECIPIENT"
  }
}

Verifying Webhooks

All webhook requests include a signature header for verification:

X-Webhook-Signature: sha256=abc123...

Verification Example (Node.js)

const crypto = require("crypto");
 
function verifyWebhook(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("hex");
 
  return `sha256=${expectedSignature}` === signature;
}
 
// In your webhook handler
app.post("/webhook", (req, res) => {
  const signature = req.headers["x-webhook-signature"];
  const isValid = verifyWebhook(
    JSON.stringify(req.body),
    signature,
    process.env.WEBHOOK_SECRET,
  );
 
  if (!isValid) {
    return res.status(401).send("Invalid signature");
  }
 
  // Process the webhook
  const { event, data } = req.body;
  console.log(`Received ${event}:`, data);
 
  res.status(200).send("OK");
});

Retry Policy

If your webhook endpoint returns an error (non-2xx status), we retry:

AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
5th retry24 hours

After 5 failed attempts, the webhook is marked as failed and no further retries are made.

Response Requirements

Your webhook endpoint should:

  • Return a 2xx status code within 30 seconds
  • Respond with any body (body content is ignored)
  • Be idempotent (handle duplicate deliveries gracefully)