Send a different message to each phone number in a single request, for example a name or a code in every message.
https://telcomw.com/api/v3/sms/batchSend a JSON body with the header Content-Type: application/json. The API key of the SMS application goes in the X-API-Key header.
| Parameter | Sent in | Required | Description |
X-API-Key |
header | YES | The API key of the SMS application, sent as a header. It starts with tmwapp_ and is made in the dashboard, under SMS Applications. It is not your account API key. |
X-Duplicate-Guard |
header | NO | Stops the same request from being done twice. Put in a value of your own that is unique for this message, for example the order number (order-1042-confirmation): 8 to 64 letters, digits, dots, dashes, colons or underscores. If your program sends the same request again with the same value, for example after a timeout, nothing is sent or charged a second time and you get the first answer back. A value is remembered for 24 hours. It is also accepted under its standard name, Idempotency-Key. Leave it out if you never retry. |
messages |
body | YES | A list of { "to", "message" }. Up to 10,000 in one request. |
messages[].to |
body | YES | The phone number of this message. |
messages[].message |
body | YES | The text of this message. |
sender_id |
body | YES | The sender ID the message shows as, for example WGIT. It must be approved on your account, see Sender IDs. |
skip_invalid |
body | NO | true to leave out the phone numbers that are not valid and send to the rest. By default one invalid number rejects the whole request, and nothing is sent or charged. |
scheduled_at |
body | NO | Send later: a date and time with its time zone, like 2026-11-05T14:30:00+02:00. It cannot be in the past or more than a year ahead. Leave it out to send now. |
curl --location --request POST 'https://telcomw.com/api/v3/sms/batch' \
--header 'X-API-Key: YOUR_APPLICATION_KEY' \
--header 'X-Duplicate-Guard: otp-batch-20261105-01' \
--header 'Content-Type: application/json' \
--data '{
"sender_id": "WGIT",
"messages": [
{
"to": "0999123456",
"message": "Hi Mary, your code is 4821"
},
{
"to": "0888123456",
"message": "Hi John, your code is 7305"
}
]
}'
curl --location --request POST "https://telcomw.com/api/v3/sms/batch" ^
--header "X-API-Key: YOUR_APPLICATION_KEY" ^
--header "X-Duplicate-Guard: otp-batch-20261105-01" ^
--header "Content-Type: application/json" ^
--data "{\"sender_id\":\"WGIT\",\"messages\":[{\"to\":\"0999123456\",\"message\":\"Hi Mary, your code is 4821\"},{\"to\":\"0888123456\",\"message\":\"Hi John, your code is 7305\"}]}"
<?php
$headers = [
'X-API-Key: YOUR_APPLICATION_KEY',
'X-Duplicate-Guard: otp-batch-20261105-01',
'Content-Type: application/json',
];
$data = [
'sender_id' => 'WGIT',
'messages' => [
[
'to' => '0999123456',
'message' => 'Hi Mary, your code is 4821'
],
[
'to' => '0888123456',
'message' => 'Hi John, your code is 7305'
]
]
];
$ch = curl_init('https://telcomw.com/api/v3/sms/batch');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
const axios = require('axios');
axios.request({
method: 'post',
url: 'https://telcomw.com/api/v3/sms/batch',
headers: {
'X-API-Key': 'YOUR_APPLICATION_KEY',
'X-Duplicate-Guard': 'otp-batch-20261105-01',
'Content-Type': 'application/json'
},
data: {
"sender_id": "WGIT",
"messages": [
{
"to": "0999123456",
"message": "Hi Mary, your code is 4821"
},
{
"to": "0888123456",
"message": "Hi John, your code is 7305"
}
]
}
}).then((res) => console.log(res.data))
.catch((err) => console.error(err.response ? err.response.data : err.message));
import requests
headers = {
'X-API-Key': 'YOUR_APPLICATION_KEY',
'X-Duplicate-Guard': 'otp-batch-20261105-01',
'Content-Type': 'application/json'
}
payload = {
'sender_id': 'WGIT',
'messages': [
{
'to': '0999123456',
'message': 'Hi Mary, your code is 4821'
},
{
'to': '0888123456',
'message': 'Hi John, your code is 7305'
}
]
}
response = requests.request('POST', 'https://telcomw.com/api/v3/sms/batch', headers=headers, json=payload)
print(response.json())
The response is JSON.
{
"success": true,
"request_id": "req_5f2c9a1d0e7b4a63",
"data": {
"batch_id": "k3m9x2p7q1ab",
"status": "pending",
"sender_id": "WGIT",
"recipients": 2,
"pages": 2,
"cost": 40,
"balance": 940,
"currency": "MWK",
"scheduled_at": null,
"messages": [
{
"message_id": "ke4wz6fydbtj",
"to": "265999123456",
"pages": 1,
"cost": 20
},
{
"message_id": "p8d2ncs0q3vx",
"to": "265888123456",
"pages": 1,
"cost": 20
}
],
"application_id": "482913"
}
}
| Field | Description |
success | true when the request was accepted. |
request_id | The number of this request. Quote it if you contact us. |
data.batch_id | The id of the whole send. Use it in Delivery Reports to follow every message of it. |
data.status | pending: queued for delivery. scheduled: waiting for scheduled_at. |
data.recipients | How many messages were queued. |
data.pages | How many SMS pages were charged. A page is 160 characters. |
data.cost | What the send cost, in MWK. |
data.balance | The balance of the SMS application after the send, in MWK. |
data.rejected.invalid_numbers | The numbers that were left out because they are not valid (with skip_invalid). |
data.rejected.duplicates | How many repeated numbers were left out. A number is sent once. |
data.messages[] | The id, number, pages and cost of each message. Left out when the send has more than 500 messages. |
data.application_id | The number of the SMS application that paid for the send. |