Broadcast the Same SMS to Many Numbers

SMS V3 APIs - SMS Applications

Send one message to many phone numbers in a single request. The message is written once.

POSThttps://telcomw.com/api/v3/sms/broadcast

Send a JSON body with the header Content-Type: application/json. The API key of the SMS application goes in the X-API-Key header.

Parameters

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.
to body YES A list of phone numbers. Up to 10,000 in one request.
message body YES The text sent to every number.
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.

Example request

curl --location --request POST 'https://telcomw.com/api/v3/sms/broadcast' \
  --header 'X-API-Key: YOUR_APPLICATION_KEY' \
  --header 'X-Duplicate-Guard: newsletter-2026-11' \
  --header 'Content-Type: application/json' \
  --data '{
  "to": [
    "0999123456",
    "0888123456",
    "0991234567"
  ],
  "message": "Our sale starts today. Visit us!",
  "sender_id": "WGIT"
}'
curl --location --request POST "https://telcomw.com/api/v3/sms/broadcast" ^
  --header "X-API-Key: YOUR_APPLICATION_KEY" ^
  --header "X-Duplicate-Guard: newsletter-2026-11" ^
  --header "Content-Type: application/json" ^
  --data "{\"to\":[\"0999123456\",\"0888123456\",\"0991234567\"],\"message\":\"Our sale starts today. Visit us!\",\"sender_id\":\"WGIT\"}"
<?php

$headers = [
    'X-API-Key: YOUR_APPLICATION_KEY',
    'X-Duplicate-Guard: newsletter-2026-11',
    'Content-Type: application/json',
];

$data = [
    'to' => [
        '0999123456',
        '0888123456',
        '0991234567'
    ],
    'message' => 'Our sale starts today. Visit us!',
    'sender_id' => 'WGIT'
];

$ch = curl_init('https://telcomw.com/api/v3/sms/broadcast');
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/broadcast',
  headers: {
    'X-API-Key': 'YOUR_APPLICATION_KEY',
    'X-Duplicate-Guard': 'newsletter-2026-11',
    'Content-Type': 'application/json'
  },
  data: {
    "to": [
      "0999123456",
      "0888123456",
      "0991234567"
    ],
    "message": "Our sale starts today. Visit us!",
    "sender_id": "WGIT"
  }
}).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': 'newsletter-2026-11',
    'Content-Type': 'application/json'
}
payload = {
    'to': [
        '0999123456',
        '0888123456',
        '0991234567'
    ],
    'message': 'Our sale starts today. Visit us!',
    'sender_id': 'WGIT'
}

response = requests.request('POST', 'https://telcomw.com/api/v3/sms/broadcast', headers=headers, json=payload)
print(response.json())

Response

The response is JSON.

Accepted (202)

{
  "success": true,
  "request_id": "req_5f2c9a1d0e7b4a63",
  "data": {
    "batch_id": "k3m9x2p7q1ab",
    "status": "pending",
    "sender_id": "WGIT",
    "recipients": 3,
    "pages": 3,
    "cost": 60,
    "balance": 920,
    "currency": "MWK",
    "scheduled_at": null,
    "messages": [
      {
        "message_id": "ke4wz6fydbtj",
        "to": "265999123456",
        "pages": 1,
        "cost": 20
      },
      {
        "message_id": "p8d2ncs0q3vx",
        "to": "265888123456",
        "pages": 1,
        "cost": 20
      },
      {
        "message_id": "z1h7lw5b9yrm",
        "to": "265991234567",
        "pages": 1,
        "cost": 20
      }
    ],
    "application_id": "482913"
  }
}

A number is not valid (400)

{
  "success": false,
  "request_id": "req_5f2c9a1d0e7b4a63",
  "error": {
    "code": "INVALID_PHONE_NUMBERS",
    "message": "1 number is not valid",
    "details": {
      "invalid_numbers": [
        "0999"
      ],
      "invalid_count": 1
    }
  }
}

Fields explained

FieldDescription
successtrue when the request was accepted.
request_idThe number of this request. Quote it if you contact us.
data.batch_idThe id of the whole send. Use it in Delivery Reports to follow every message of it.
data.statuspending: queued for delivery. scheduled: waiting for scheduled_at.
data.recipientsHow many messages were queued.
data.pagesHow many SMS pages were charged. A page is 160 characters.
data.costWhat the send cost, in MWK.
data.balanceThe balance of the SMS application after the send, in MWK.
data.rejected.invalid_numbersThe numbers that were left out because they are not valid (with skip_invalid).
data.rejected.duplicatesHow 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.messages_omitted is true): read them with Delivery Reports using the batch_id.
data.application_idThe number of the SMS application that paid for the send.

Good to know

  • Messages sent with this key are paid from the balance of the SMS application.