Send a Single SMS

SMS V3 APIs - SMS Applications

Send one message to one phone number.

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

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 The phone number, for example 0999123456, 265999123456 or +265999123456.
message body YES The text of the 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.
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/send' \
  --header 'X-API-Key: YOUR_APPLICATION_KEY' \
  --header 'X-Duplicate-Guard: order-1042-confirmation' \
  --header 'Content-Type: application/json' \
  --data '{
  "to": "0999123456",
  "message": "Your order 1042 is ready for pickup.",
  "sender_id": "WGIT"
}'
curl --location --request POST "https://telcomw.com/api/v3/sms/send" ^
  --header "X-API-Key: YOUR_APPLICATION_KEY" ^
  --header "X-Duplicate-Guard: order-1042-confirmation" ^
  --header "Content-Type: application/json" ^
  --data "{\"to\":\"0999123456\",\"message\":\"Your order 1042 is ready for pickup.\",\"sender_id\":\"WGIT\"}"
<?php

$headers = [
    'X-API-Key: YOUR_APPLICATION_KEY',
    'X-Duplicate-Guard: order-1042-confirmation',
    'Content-Type: application/json',
];

$data = [
    'to' => '0999123456',
    'message' => 'Your order 1042 is ready for pickup.',
    'sender_id' => 'WGIT'
];

$ch = curl_init('https://telcomw.com/api/v3/sms/send');
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/send',
  headers: {
    'X-API-Key': 'YOUR_APPLICATION_KEY',
    'X-Duplicate-Guard': 'order-1042-confirmation',
    'Content-Type': 'application/json'
  },
  data: {
    "to": "0999123456",
    "message": "Your order 1042 is ready for pickup.",
    "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': 'order-1042-confirmation',
    'Content-Type': 'application/json'
}
payload = {
    'to': '0999123456',
    'message': 'Your order 1042 is ready for pickup.',
    'sender_id': 'WGIT'
}

response = requests.request('POST', 'https://telcomw.com/api/v3/sms/send', 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": 1,
    "pages": 1,
    "cost": 20,
    "balance": 980,
    "currency": "MWK",
    "scheduled_at": null,
    "message_id": "ke4wz6fydbtj",
    "to": "265999123456",
    "application_id": "482913"
  }
}

The application has no more balance (402)

{
  "success": false,
  "request_id": "req_5f2c9a1d0e7b4a63",
  "error": {
    "code": "INSUFFICIENT_APPLICATION_BALANCE",
    "message": "This application does not have enough balance for these messages, please fund the application",
    "details": {
      "required": 20,
      "balance": 5,
      "currency": "MWK",
      "application_id": "482913"
    }
  }
}

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.message_idThe id of the message. Use it in Message Status.
data.toThe phone number in international format.
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.