Send a message
One message to one recipient. The workhorse for OTPs, alerts and confirmations.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| senderID | string | Yes | An approved sender ID on your account (case-sensitive). |
| phone | string | Yes | The recipient. 07…, 2547… and +2547… formats all accepted. |
| message | string | Yes | The text. Long messages are split into parts automatically (billed per part). |
# Paste your token once (it starts with mbs_):
export MOBILESASA_TOKEN="mbs_your_token_here"
curl -X POST https://api.mobilesasa.com/v1/send/message \
-H "Authorization: Bearer $MOBILESASA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"senderID": "MOBILESASA",
"phone": "0712345678",
"message": "Your verification code is 482913. Valid for 10 minutes."
}'Response
{
"status": true,
"responseCode": "0200",
"message": "Accepted",
"messageId": "3c51beb1-a674-41d0-9e45-f5581418fb56"
}Keep messageId. It is the only handle you have on the send. Pass it to delivery reports to find out what actually happened to the message.
{
"status": false,
"responseCode": "0422",
"message": "The phone is not a valid phone number."
}Sending the fields as a form
JSON is what these examples use, but the endpoint takes form-encoded and multipart bodies too — which is how most of the older SDKs post it. The field names are the same, and the token can travel in the form alongside them instead of in a header:
# Paste your token once (it starts with mbs_):
export MOBILESASA_TOKEN="mbs_your_token_here"
curl -X POST "https://api.mobilesasa.com/v1/send/message" \
-d "api_token=$MOBILESASA_TOKEN" \
-d "senderID=MOBILESASA" \
-d "phone=0712345678" \
-d "message=Your verification code is 482913."Escape quotes in JSON
\". An unescaped one makes the whole body unparseable and the send is rejected with 0422 — send the fields as a form if escaping is awkward.GET variant, for ERPs and legacy systems
Many ERPs, accounting packages and older systems can only fire a plain URL, no request body, sometimes not even a header. This endpoint accepts the exact same fields as the POST, but as query-string parameters, with the token passed as api_token:
https://api.mobilesasa.com/v1/send/messageget?api_token=PASTE_YOUR_mbs_TOKEN_HERE&senderID=MOBILESASA&phone=0712345678&message=Invoice+INV-2041+of+KES+12%2C400+is+ready.# Paste your token once (it starts with mbs_):
export MOBILESASA_TOKEN="mbs_your_token_here"
curl -G "https://api.mobilesasa.com/v1/send/messageget" \
--data-urlencode "api_token=$MOBILESASA_TOKEN" \
--data-urlencode "senderID=MOBILESASA" \
--data-urlencode "phone=0712345678" \
--data-urlencode "message=Invoice INV-2041 of KES 12,400 is ready."The response envelope is identical to the POST. If your system can set headers, Authorization: Bearer still works here and is preferred over api_token in the URL.
URL-encode the message
--data-urlencode). Also remember URLs (query string included) end up in proxy and server logs; keep GET sends for systems that genuinely cannot POST.Things worth knowing
- Accepted ≠ delivered. 0200 means queued with the carrier. Confirm delivery via delivery reports.
- Duplicates are blocked (0409). The same sender + text + number delivers at most once per day, unless the sender allows repeats. See Responses.
- Balance is checked first. An 0402 response bills nothing.
- Need your own reference on the send, or the cost back? Use v2.
OTP senders