Send SMS
Send an SMS message to one or more recipients using the SMS API.
Endpoint
POST {{BASE_URL}}/api/v1/sms
Headers
Every request must include the following headers:
X-API-KEY: your-api-key
X-API-SECRET: your-api-secret
Idempotency-Key: unique-request-key
Content-Type: application/json
See Authentication for more information about API credentials.
Request body
{
"msisdns": [
"254701234567",
"254701234568"
],
"message": "Hello, this is a test message.",
"sender_name": "TEST_SENDER"
}
Parameters
msisdns
An array containing the mobile numbers that should receive the message.
{
"msisdns": [
"254701234567",
"254701234568"
]
}
Requirements:
- At least 1 recipient is required.
- A maximum of 10000 recipients can be included in one request.
- Mobile numbers must be valid.
- Use the international format without the
+sign.
For example:
254701234567
message
The SMS message to send.
{
"message": "Hello, this is a test message."
}
A message can contain a maximum of 6 SMS parts.
If the message exceeds 6 SMS parts, the request is rejected.
How parts are counted
A message is split into parts, and you are charged per part. How many characters fit in one part depends on the route your sender name is registered on:
| Sender route | Characters per part |
|---|---|
| Promotional | 145 |
| Transactional | 160 |
Promotional routes carry fewer characters because an opt-out notice is appended to them.
The part count is ceil(characters / limit). So a 150-character message is 2 parts on a promotional sender and 1 part on a transactional one.
Characters are counted against the GSM-7 alphabet. Most characters count as one; the extended set — ^ { } [ ] ~ | € — counts as two each. A message containing a character outside GSM-7 is rejected rather than being sent as unicode.
Tips
The sms_count in the response is the number of parts you were charged for. Check it if you need to reconcile usage.
If you are not sure which route your sender name uses, ask your account manager — it affects what each message costs.
sender_name
The sender name to use when sending the SMS.
{
"sender_name": "TEST_SENDER"
}
The sender name must:
- Exist on the account.
- Be allowed for use by the account.
If the sender name does not exist, the API returns:
SENDER_NOT_FOUND
If the sender name exists but is not allowed for the account, the API returns:
SENDER_NOT_ALLOWED
Complete request
POST {{BASE_URL}}/api/v1/sms
X-API-KEY: your-api-key
X-API-SECRET: your-api-secret
Idempotency-Key: 7f8e2d91-5c34-4a21-b876-19d5e4f20381
Content-Type: application/json
{
"msisdns": [
"254701234567",
"254701234569"
],
"message": "Hello, this is a test message.",
"sender_name": "TEST_SENDER"
}
Successful response
When the request passes validation and the SMS is queued successfully, the API returns:
{
"success": true,
"message": "SMS queued successfully.",
"error": null,
"data": {
"batch_id": "20bc680b-974d-4f33-affa-273414ebb77f",
"sms_count": 1,
"total_recipients": 2,
"cost_cents": 200,
"status": "queued"
}
}
Response fields
| Field | Description |
|---|---|
batch_id | Unique ID for the SMS request. |
sms_count | Number of SMS parts in the message. |
total_recipients | Number of recipients in the request. |
cost_cents | Total cost of the request in cents. |
status | Current request status. |
The batch_id can be used to associate delivery reports with the original request.
Balance validation
The account must have sufficient balance to send the requested SMS.
The total SMS units are calculated using:
SMS parts × number of recipients
For example, a message containing 2 SMS parts sent to 10 recipients requires:
2 × 10 = 20 SMS units
If the account does not have sufficient balance, the request is rejected with:
INSUFFICIENT_BALANCE
Validation
The API validates the entire request before queuing any messages.
If one recipient is invalid, the request is rejected rather than partially processing the valid recipients.