eSMS AfricaeSMS Africa
Delivery

Message Status

Track the delivery status of your SMS messages.

Message lifecycle

Every message goes through a series of status changes from the moment it is submitted until delivery confirmation (or failure).

queuedsubmittedsentdeliveredfailed↺ auto-retry up to 2×
Message lifecycleTerminal states: delivered · failed

Status values

StatusDescription
queuedAccepted by the API and queued for dispatch
submittedSubmitted to the carrier gateway
sentAccepted by the carrier (en route to handset)
deliveredConfirmed delivered to the recipient's handset
failedDelivery failed. See error_code for reason
retryingFailed; system is automatically retrying

Check status of a single message

Endpoint
GET /api/messages/:message_id
Response 200
{
  "id": "msg-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "phone": "+256712345678",
  "text": "Hello from eSMS Africa!",
  "sender_id": "eSMSAfrica",
  "route": "ESMS_UG",
  "country": "UG",
  "segments": 1,
  "cost": 35.00,
  "currency": "UGX",
  "status": "delivered",
  "delivered_at": "2026-05-02T12:00:05Z",
  "timeline": [
    {
      "event": "accepted",
      "status": "queued",
      "detail": "API request received",
      "at": "2026-05-02T12:00:00Z"
    },
    {
      "event": "submitted",
      "status": "submitted",
      "detail": "Gateway accepted",
      "at": "2026-05-02T12:00:01Z",
      "metadata": { "gateway_message_id": "0005e27f-6c0c-49f1-bfa4" }
    },
    {
      "event": "delivered",
      "status": "delivered",
      "detail": "DLR: DELIVRD",
      "at": "2026-05-02T12:00:05Z"
    }
  ]
}

The timeline array shows every event for the message in chronological order.

List messages

Endpoint
GET /api/messages?page=0&limit=20&status=delivered
Query paramDescription
page0-indexed page number (default 0)
limitResults per page, 1–100 (default 20)
statusFilter by status: queued, submitted, sent, delivered, failed

Manual retry

If a message has status: "failed", you can manually retry it:

Endpoint
POST /api/messages/:message_id/retry

The retry is dispatched as a new send - the response contains a fresh message ID. The original message's retry_count is incremented.

Response 200
{
  "id": "9237c404-d73f-4fa6-813b-ab25bb8605d0",
  "status": "failed",
  "retry_count": 1
}

The system automatically retries failed messages up to 2 times before marking them permanently failed. Manual retry is available on top of that.

Real-time updates

Instead of polling, use:

  • Webhooks - receive DLR callbacks to your server
  • WebSocket - live updates in your browser/app

On this page