API Reference
Complete reference for the four SMS Developer API operations.
Base URL And Authentication
https://api.notify.africaAuthorization: Bearer ntfy_your_api_keyThe key must have SMS access. Every operation is scoped to the customer that owns the key.
Endpoint Inventory
| Method | Path | Success | Reference |
|---|---|---|---|
POST | /api/v1/api/messages/send | 202 wrapped | Send one SMS |
POST | /api/v1/api/messages/batch | 200 wrapped | Send same-content batch |
POST | /api/v1/api/messages/send-bulk | 202 wrapped | Send personalized bulk |
GET | /api/v1/api/messages/status/{messageId} | 200 wrapped | Get message status |
No SMS Developer API endpoint is paginated.
Success Envelope
{
"status": 200,
"message": "Success",
"timestamp": "2026-09-09T13:00:00.000Z",
"path": "/api/v1/api/messages/example",
"data": {}
}status is the HTTP response status. message can contain an operation-specific success message.
Send One SMS
POST /api/v1/api/messages/send
Headers
Authorization: Bearer ntfy_...required.Content-Type: application/jsonrequired.
Request Body
| Field | Type | Required | Validation |
|---|---|---|---|
phone_number | string | Yes | International number; leading + optional |
message | string | Yes | 1-918 characters |
sender_id | string or number | Yes | Approved current sender, name, or mapped legacy identifier |
{
"phone_number": "255712345678",
"message": "Your order has shipped",
"sender_id": "MYBRAND"
}Canonical aliases recipient, content, and senderId are also accepted. Canonical recipient requires leading +; optional scheduledAt accepts an ISO date-time.
Success
HTTP 202 with data.messageId and uppercase data.status.
Errors
400: recipient or content validation, unsupported destination, or insufficient service input.401: missing, malformed, invalid, expired, revoked, or non-SMS key.403: customer boundary failure.404: sender not found or not approved for the customer.409: sender usage limit reached.422: sender exists but is not approved.- dependency or provider failures can surface as server errors.
Next: retrieve delivery status using the returned UUID.
Send Same-Content Batch
POST /api/v1/api/messages/batch
Request Body
| Field | Type | Required | Validation |
|---|---|---|---|
phone_numbers | string[] | Yes | At least one item; leading + optional |
message | string | Yes | 1-918 characters |
sender_id | string or number | Yes | Approved current sender, name, or mapped legacy identifier |
{
"phone_numbers": ["255712345678", "255713456789"],
"message": "Maintenance starts at 22:00",
"sender_id": "MYBRAND"
}Success
HTTP 200 with:
{
"status": 200,
"message": "Batch messages sent successfully",
"timestamp": "2026-09-09T13:10:00.000Z",
"path": "/api/v1/api/messages/batch",
"data": {
"messageCount": 2,
"creditsDeducted": 2,
"remainingBalance": 498
}
}This response does not return per-message UUIDs or rejected-recipient details. Errors follow the single-send categories.
Next: use personalized bulk when per-message results are required.
Send Personalized Bulk
POST /api/v1/api/messages/send-bulk
Request Body
| Field | Type | Required | Validation |
|---|---|---|---|
senderId | string | Yes | Approved UUID, sender name, or mapped legacy identifier |
messages | object[] | Yes | At least one item |
messages[].recipient | string | Yes | E.164 with leading + |
messages[].content | string | Yes | 1-918 characters |
scheduledAt | ISO date-time | No | One schedule for the complete batch |
{
"senderId": "MYBRAND",
"messages": [
{
"recipient": "+255712345678",
"content": "Hello Asha"
}
],
"scheduledAt": "2026-09-10T08:00:00.000Z"
}Success
HTTP 202. The standard envelope's data contains:
{
"acceptedCount": 1,
"rejectedCount": 0,
"results": [
{
"messageId": "d9b54c80-8a63-4f8b-83c8-71f2439f5429",
"status": "scheduled",
"estimatedSegments": 1,
"debitApplied": true
}
],
"creditsDeducted": 1,
"remainingBalance": 499
}The results[].status values are lowercase in this operation. A mixed recipient set can return both accepted and rejected counts.
Next: store each results[].messageId and retrieve status.
Get Message Status
GET /api/v1/api/messages/status/{messageId}
Path Parameter
| Parameter | Type | Required | Validation |
|---|---|---|---|
messageId | UUID | Yes | Must identify a message owned by the API-key customer |
curl --request GET \
"$NOTIFY_API_BASE_URL/api/v1/api/messages/status/d9b54c80-8a63-4f8b-83c8-71f2439f5429" \
--header "Authorization: Bearer $NOTIFY_SMS_API_KEY"Success
HTTP 200 with data.messageId, uppercase data.status, nullable data.sentAt, and nullable data.deliveredAt.
Errors
401: API-key authentication failure.403: malformed UUID, unknown message, or message outside the authenticated customer.
Next: continue polling until DELIVERED or FAILED, subject to an application deadline.
Error Envelope
{
"status": 400,
"message": "Only Tanzanian phone numbers are supported",
"code": "BAD_REQUEST",
"timestamp": "2026-09-09T13:20:00.000Z",
"path": "/api/v1/api/messages/send",
"error": "Only Tanzanian phone numbers are supported"
}error can be a string, array, or object. Development environments can include a stack trace; integrations must not depend on it.
