API reference
Send a batch
One text or template to up to 100 numbers in one call, each with its own variables and reference.
POSThttps://api.siellabs.com/v1/messages/batch
Request#
The headers are those of Send a message. The fields that apply to every message come once, and messages lists the recipients.
fromstringRequired
One of your approved sender IDs.
bodystringOptional
The text, with
{{variables}} to fill per message. Send body or template_id.template_idstringOptional
One of your templates, instead of
body.variablesobjectOptional
Values for every message. A message's own
variables win over these.messagesarrayRequired
1 to 100 messages, below.
validity_periodintegerOptional
Seconds, 10 to 86,400, counted from this call, for every message. See Send a message.
callback_urlstringOptional
Where every message's webhooks go, instead of your account's callback URL.
smart_encodingbooleanOptional
As for Send a message.
shorten_linksbooleanOptional
As for Send a message: each message gets its own short links.
Each message#
tostringRequired
The recipient in international format:
+447700900123.variablesobjectOptional
This message's values for the text's
{{variables}}: strings or numbers.client_referencestringOptional
Your own id for this message, up to 256 characters. It comes back in the message and its webhooks.
How it's sent#
- What applies to every message is checked first: your account, the sender ID, the template,
validity_periodandcallback_url. If one fails, the call fails with the usual error and nothing is sent. - Then each message is sent and charged as Send a message would send it, and answers for itself: a bad number, a missing variable or a country you don't send to refuses that message alone.
- Messages count against your messages per second like any other, but a batch waits its turn instead of refusing them. One that would wait more than 25 seconds is refused as
rate_limited, withretry_after: send those again. - With an
Idempotency-Key, a repeat of the call with the same key returns the messages sent the first time instead of sending them again. Each message is keyed by its place inmessages, so keep the order when you retry.
{
"from": "YourBrand",
"body": "Hi {{name}}, your table is booked for {{time}}.",
"variables": { "time": "19:30" },
"validity_period": 3600,
"messages": [
{ "to": "+447700900123", "variables": { "name": "Amy" }, "client_reference": "booking-311" },
{ "to": "+447700900456", "variables": { "name": "Ben", "time": "20:00" }, "client_reference": "booking-312" },
{ "to": "07700 900789", "variables": { "name": "Cy" }, "client_reference": "booking-313" }
]
}Response#
200 OK once the batch was looked at, whatever became of each message: accepted and refused count them, and data has one entry per message, in the order sent. An accepted one has its message; a refused one has to and client_reference as you sent them, and the error it would have got on its own.
{
"accepted": 2,
"refused": 1,
"data": [
{
"index": 0,
"message": {
"id": "01a18c17-566b-7b3d-9f42-6a8e0d51c2b7",
"to": "+447700900123",
"from": "YourBrand",
"body": "Hi Amy, your table is booked for 19:30.",
"status": "queued",
"price_micros": 30000,
"client_reference": "booking-311",
"expires_at": "2026-10-30T10:15:02.123456Z",
…
}
},
{
"index": 1,
"message": {
"id": "01a18c17-566b-7c01-a3c2-5b7e9d0f1a22",
"body": "Hi Ben, your table is booked for 20:00.",
…
}
},
{
"index": 2,
"to": "07700 900789",
"client_reference": "booking-313",
"error": {
"code": "invalid_to",
"message": "to must be a valid phone number in E.164 format, e.g. +447700900123"
}
}
]
}Errors#
Those of Send a message, for the whole batch or per message, and:
| HTTP | code | When |
|---|---|---|
| 422 | invalid_messages | messages is empty or holds more than 100 |
| 400 | invalid_json | The body isn't JSON, has an unknown field, or is over 512 KiB |