Send messages
Send SMS and WhatsApp messages, one to each person, up to 100 at a time.
Send one message to each person, by SMS or WhatsApp, now or at a time you choose. Send up to 100 in one request: they're queued all or none.
Requirements
- An API key with the
messages.sendpermission. - For SMS, enough SMS on your account. For WhatsApp, your number connected.
Requests
POST /v1/messagesRequest syntax
{
"messages": [
{
"to": "<PHONE_NUMBER>",
"customerId": "<CUSTOMER_ID>",
"channel": "<CHANNEL>",
"from": "<SENDER>",
"content": { "text": "<TEXT>" },
"template": "<TEMPLATE_NAME>",
"variables": { "<KEY>": "<VALUE>" },
"sendAt": "<TIME>",
"replyTo": "<RECEIVED_MESSAGE_ID>"
}
]
}| Placeholder | Description | Sample value |
|---|---|---|
<PHONE_NUMBER> | String. Who it's to, with the country code. Use to or customerId, not both. | +255712345678 |
<CUSTOMER_ID> | String. One of your customers. Their phone is used. | cus_4hq2v9n1c8x0t6pk |
<CHANNEL> | String. sms or whatsapp. Optional with a template, which has its own. | sms |
<SENDER> | String. Optional. An SMS sender ID from GET /v1/messaging/senders. Left out, yours or the shared one. | DUKA AMINA |
<TEXT> | String. What it says. SMS: up to 6 parts. WhatsApp: up to 4,096 characters. Leave out with a template. | Your order is ready. |
<TEMPLATE_NAME> | String. A saved template's name or id. See Send templates. | auth_1 |
<KEY>, <VALUE> | Object of strings. The template's {{data.x}} and {{secret.x}} values. | { "code": "482913" } |
<TIME> | String. Optional. When to send it, within a year. Left out, now. WhatsApp text always goes now. | 2026-11-13T07:00:00Z |
<RECEIVED_MESSAGE_ID> | String. Optional. WhatsApp only: a message the customer sent, which this reply quotes. | rcv_8f2k1m0p9x3a7q2z |
Example request
curl https://api.goomzo.africa/v1/messages \
-H "Authorization: Bearer $GOOMZO_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1042-ready" \
-d '{
"messages": [
{ "to": "+255712345678", "channel": "sms", "content": { "text": "Amina, order #1042 is ready." } }
]
}'Responses
The answer is 201 with the messages, in the order you sent them.
{
"items": [
{
"id": "msg_7c1x9v2b4n6m8q0w",
"customerId": "cus_4hq2v9n1c8x0t6pk",
"to": { "name": "Amina", "phone": "+255712345678" },
"channel": "sms",
"content": { "text": "Amina, order #1042 is ready." },
"status": "sending",
"error": null,
"sendAt": "2026-11-12T09:14:03Z",
"private": false,
"template": null
}
]
}| Placeholder | Description | Sample value |
|---|---|---|
id | String. The message's id. Webhooks and GET /v1/messages/{id} use it. | msg_7c1x9v2b4n6m8q0w |
status | String. Where it is. See statuses. | sending |
private | Boolean. It was sent with secrets, shown as •••••• in content. | false |
template | Object or null. The WhatsApp template it went as. | null |
Important: This answer only means Goomzo accepted the message. It doesn't mean it was delivered. Follow its status with webhooks.
Notes
- All or none: every message is checked, and the SMS for all of them set aside together. If one isn't valid, or
there isn't enough SMS for all of them, none is sent, and the error names the bad one, such as
messages[1].to. - Not enough SMS:
422 insufficient_smssays how many the requestneededand how many wereavailable. - Unknown numbers: a number that isn't one of your customers is still sent to, under the number itself. No customer is added.
- Before you send:
POST /v1/messaging/estimatetakes the samechannel,contentand audience, and says what it would use.
Next steps
Last updated