Send template messages

One call sends an approved template to one recipient or a list, with the same values for everyone or a set per person.

POSThttps://api.mobilesasa.com/api/v1/whatsapp/send

Parameters

FieldTypeRequiredDescription
account_uuiduuidYesWhich number to send from (your own or the Mobile Sasa number). The Account ID under WhatsApp, My numbers in the portal, or uuid from GET /api/v1/whatsapp/accounts.
template_uuiduuidYesAn APPROVED template on that account. The Template ID on its card under WhatsApp, Templates, or uuid from the account's template list.
recipientsstring[]NoPhone numbers of opted-in recipients (Kenyan formats accepted, E.164 for everyone else). Use with params for the same values to all.
paramsstring[]NoValues for the template's {{1}}, {{2}}… blanks, in order, applied to every number in recipients. For a passcode template this is the code.
personalizedobject[]NoInstead of recipients: [{ "to": "0712…", "params": ["Jane", "KES 1,200"] }, …], one set of values per person. Both forms may be combined in one call.
media_idstringNoMeta media ID for templates with an image, video or document header. Upload with POST /api/v1/whatsapp/accounts/{uuid}/media (multipart file).
# Paste your token once (it starts with mbs_):
export MOBILESASA_TOKEN="mbs_your_token_here"

curl -X POST https://api.mobilesasa.com/api/v1/whatsapp/send \
  -H "Authorization: Bearer $MOBILESASA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "account_uuid": "ACCOUNT_UUID",
    "template_uuid": "TEMPLATE_UUID",
    "personalized": [
      {
        "to": "0712345678",
        "params": [
          "Jane",
          "February",
          "KES 128,400"
        ]
      },
      {
        "to": "0733000002",
        "params": [
          "Otieno",
          "February",
          "KES 4,050"
        ]
      }
    ]
  }'
Response
{
  "success": true,
  "data": {
    "accepted": 2,
    "rejected": 0,
    "cost": 5.00,
    "rate": 2.50
  }
}

accepted messages are queued and billed at rate each; rejected counts numbers that could not be parsed, listed in invalid. Duplicated numbers in one call are sent once.

Quote before you send

POSThttps://api.mobilesasa.com/api/v1/whatsapp/quote

Same body as send. Nothing is sent or charged; you get the rate, the number of recipients after de-duplication, the total and your wallet balance.

# Paste your token once (it starts with mbs_):
export MOBILESASA_TOKEN="mbs_your_token_here"

curl -X POST https://api.mobilesasa.com/api/v1/whatsapp/quote \
  -H "Authorization: Bearer $MOBILESASA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "account_uuid": "ACCOUNT_UUID",
    "template_uuid": "TEMPLATE_UUID",
    "recipients": [
      "0712345678",
      "0733000002"
    ]
  }'
Response
{
  "success": true,
  "data": { "rate": 2.50, "recipients": 2, "total": 5.00, "balance": 56048.50, "mode": "managed" }
}

What a message costs

  • Managed numbers (the Mobile Sasa number, or one we set up for you): the template category's rate per message.
  • Your own Meta app: the flat platform fee per message. Meta bills the conversation to your Meta account separately.

The wallet is charged when the message is accepted. If Meta refuses it (not a WhatsApp number, policy block, template paused) the message is marked failed and the charge is refunded to your wallet automatically; refunded_at on the message says when.

Only the blanks are yours

Meta approved the template's wording. Values may not add line breaks, more than four consecutive spaces or Markdown; Meta rejects those at send time and the message fails (and is refunded).

Requirements and failure modes

  • The template must be APPROVED; pending, rejected or paused templates fail the whole call with a validation error.
  • Insufficient wallet balance fails the call before anything sends, with the amount needed in the error.
  • Recipients must have opted in to WhatsApp messages from you. Meta scores every number on blocks and reports; a poor rating limits how many new people you can message per day.
  • Marketing templates can only reach a person who has not received marketing from your number in the last day or so; Meta drops the extra ones (status failed, refunded).

Track outcomes in message history; statuses move through queued → sent → delivered → read, with failed carrying the reason.