POST
/public/sms/sendSend an SMS
Sends one message to one recipient, either as raw text or by resolving a saved template with variables. Requires the sms.send scope.
Request body
| Field | Type | Description |
|---|---|---|
| to* | string | Destination MSISDN. South African local (071...) or E.164 (+2771...) formats are both normalised. |
| body | string | Raw message text, up to 1600 characters. Required unless templateId is given. |
| templateId | string | ID of a saved message template to resolve instead of body. |
| variables | object | Key/value map used to fill {{variables}} in the template. Ignored if body is used instead. |
* required
Exactly one of body or templateId is required.
Example request
curl
curl -X POST https://app.simplisend.co.za/api/v1/public/sms/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+27821234567",
"body": "Hi Thabo, your order has shipped!"
}'JavaScript (fetch)
const res = await fetch("https://app.simplisend.co.za/api/v1/public/sms/send", {
method: "POST",
headers: {
"X-API-Key": process.env.SIMPLISEND_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
to: "+27821234567",
templateId: "tpl_order_shipped",
variables: { firstName: "Thabo", orderNumber: "SO-1042" },
}),
});
const result = await res.json();Python
import os, requests
res = requests.post(
"https://app.simplisend.co.za/api/v1/public/sms/send",
headers={"X-API-Key": os.environ["SIMPLISEND_API_KEY"]},
json={"to": "+27821234567", "body": "Hi Thabo, your order has shipped!"},
)
result = res.json()Response - 201 Created
{
"id": "cl9x...",
"status": "SENT",
"deliveryStatus": null
}| Field | Type | Description |
|---|---|---|
| id | string | The message ID - use this with Get message status. |
| status | string | QUEUED, SENDING, SENT, DELIVERED, FAILED, or BLOCKED. |
| deliveryStatus | string | null | Provider or failure detail text, when available. |
* required
Error responses
400- invalid phone number, or neitherbodynortemplateIdgiven402- insufficient SMS balance403- API key missing thesms.sendscope404-templateIddoesn't exist on your account503- the SMS vendor integration isn't configured yet on this account
See Errors for the full error envelope shape.
A message can come back BLOCKED
Every message - from this endpoint or the dashboard - passes through automated content moderation before sending. A high-severity flag (hate speech, abuse, racism) blocks the send and returns status: "BLOCKED" rather than an error - the request itself succeeded, the message just didn't go out. This essentially never triggers on legitimate transactional or marketing content.