Send a single SMS, the same message to many numbers, or a different message to each number, and follow delivery. Everything is JSON over HTTPS.
X-API-Key header of every request.Content-Type: application/json) over HTTPS.https://telcomw.com/api/v3Send your API key in the X-API-Key header of every request. You find your key on your account page after you log in; register at https://telcomw.com if you do not have an account yet.
X-API-Key: YOUR_API_KEY
Authorization: Bearer YOUR_API_KEY.| Call | Request | What it does |
| Single SMS | POST /api/v3/sms/send |
Send one message to one phone number. |
| Broadcast SMS | POST /api/v3/sms/broadcast |
Send one message to many phone numbers in a single request. The message is written once. |
| Personalised Batch SMS | POST /api/v3/sms/batch |
Send a different message to each phone number in a single request, for example a name or a code in every message. |
| Delivery Reports | GET /api/v3/sms/delivery-reports |
List your messages and whether they were delivered. Filter by batch, status, period or number. |
| Message Status | GET /api/v3/sms/{message_id} |
The delivery status of one message, by the message_id you got when you sent it. |
| Account Balance | GET /api/v3/account/balance |
Your SMS balance, to check before a large send. |
| Sender IDs | GET /api/v3/sender-ids |
The sender IDs you can send from. Ask for new ones in the dashboard, under Account. |
curl -X POST https://telcomw.com/api/v3/sms/send \
-H 'X-API-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"to":"0999123456","message":"Hello from TelcoMW","sender_id":"WGIT"}'
Every answer is JSON and has a request_id. Quote it if you contact us about a request.
{
"success": true,
"request_id": "req_5f2c9a1d0e7b4a63",
"data": { ... }
}
{
"success": false,
"request_id": "req_5f2c9a1d0e7b4a63",
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "You do not have enough balance for these messages, please top up",
"details": { "required": 20, "balance": 5, "currency": "MWK" }
}
}
Use the HTTP status and the error.code in your program, they stay the same. The message is for people and can change. See the list of errors below.
202 and the status is pending. Read the delivery status later with Message Status or Delivery Reports.0999123456, 265999123456 or +265999123456. They are answered in international format. A number written twice in one send is sent once.scheduled_at, for example 2026-11-05T14:30:00+02:00. The status is then scheduled.pending (queued, not delivered yet), delivered, failed.If a request times out you do not know whether it was sent. Add an Idempotency-Key header with a unique value for each message or batch you mean to send:
Idempotency-Key: order-1042-confirmation
Send the same request again with the same key and you get the first answer back (with the header Idempotent-Replayed: true). You are not charged twice. A key is kept for 24 hours, and it cannot be used for a different request.
429 and a Retry-After header with the seconds to wait.| Code | HTTP | What it means |
API_KEY_REQUIRED | 401 | No API key was sent. Send it in the X-API-Key header. |
INVALID_API_KEY | 401 | The API key is not valid, or the account is not active. |
API_KEY_IN_URL | 400 | The API key was in the address. Keys belong in the header only. |
TOO_MANY_ATTEMPTS | 429 | Too many requests with a wrong key from your address. |
RATE_LIMITED | 429 | Too many requests. Wait the number of seconds in the Retry-After header. |
UNSUPPORTED_MEDIA_TYPE | 415 | The body is not sent as JSON (Content-Type: application/json). |
INVALID_JSON | 400 | The body is not valid JSON. |
REQUEST_TOO_LARGE | 413 | The body is too large. Send fewer messages at a time. |
INVALID_REQUEST | 400 | A field is missing or is not the right type. details.field says which. |
SENDER_ID_REQUIRED | 400 | sender_id was not sent. |
SENDER_ID_NOT_ALLOWED | 403 | The sender ID is not approved on your account. |
MESSAGE_REQUIRED | 400 | The message is empty. |
MESSAGE_TOO_LONG | 400 | The message is longer than the most pages allowed. |
NO_RECIPIENTS | 400 | There is no phone number to send to. |
TOO_MANY_RECIPIENTS | 400 | More recipients than one request can hold (10,000). |
INVALID_PHONE_NUMBERS | 400 | One or more phone numbers are not valid. details.invalid_numbers lists them. Nothing was sent or charged. |
INVALID_SCHEDULE | 400 | scheduled_at is not valid, is in the past, or is more than a year ahead. |
INSUFFICIENT_BALANCE | 402 | Your balance does not cover the send. details.required and details.balance say how much. |
SMS_UNAVAILABLE | 503 | Sending is switched off at the moment. Nothing was sent or charged. |
INVALID_IDEMPOTENCY_KEY | 400 | The Idempotency-Key is not 8 to 64 letters, digits, dots, dashes or underscores. |
REQUEST_IN_PROGRESS | 409 | A request with this Idempotency-Key is still being processed. Send the same request again in a moment. |
IDEMPOTENCY_KEY_REUSED | 422 | The Idempotency-Key was used for a different request. |
MESSAGE_NOT_FOUND | 404 | No message with this id on your account. |
PERIOD_TOO_LONG | 400 | The delivery report period is longer than a year. |
NOT_FOUND | 404 | There is no such endpoint. |
INTERNAL_ERROR | 500 | A problem on our side. Quote the request_id if you contact us. |
Need help? Contact us on WhatsApp.