Send a Single SMS

SMS V3 APIs

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. Your API key goes in the X-API-Key header.

Parameters

Parameter Sent in Required Description
X-API-Key header YES Your API key, sent as a header. You can also send it as Authorization: Bearer YOUR_API_KEY.
Idempotency-Key header NO A unique value you make for this request (8 to 64 letters, digits, dots, dashes or underscores). If you send the same request again with the same key, for example after a timeout, you get the first answer back and are not charged twice. Keys are kept for 24 hours.
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_API_KEY' \
  --header 'Idempotency-Key: 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_API_KEY" ^
  --header "Idempotency-Key: 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_API_KEY',
    'Idempotency-Key: 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_API_KEY',
    'Idempotency-Key': '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_API_KEY',
    'Idempotency-Key': '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"
  }
}

Not enough balance (402)

{
  "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"
    }
  }
}

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.balanceYour balance 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.

Good to know

  • The message is queued for delivery, so the answer says pending. Read the delivery status with Message Status or Delivery Reports.
  • The cost is taken from your balance when the message is queued.