Send personalised bulk SMS with the API
Use the send-bulk API to send one message to many people in a single request, with each person's message personalised from your own data, such as a first name, an order number or an appointment time.
You don't need an address book. You choose the field names, and they are not stored.
3 of 3 rows
| Send the same text to one or more numbers | POST /api/sms/send |
| Send a personalised text to many numbers in one request | POST /api/sms/send-bulk |
| Check what happened to one message | POST /api/sms/status |
💡
Already use $_first_name in the portal? Those fields only work when you send from the portal to an address book. Over the API they are sent as those exact characters, so use the placeholders below instead.
Before you start
- An SMS service with an approved Sender ID.
- An SMS API key. Open your SMS service in Atomic and go to API Key.
- Your SMS API URL. It is on the same page, under Service Details > SMS API URL.
- The full API reference: docs.atomtelecom.com.au, then choose Hosted API at the top.
Step 1: Write your message with placeholders
Put each person's details in your message as a placeholder. Both styles work:
json
Hi {{first_name}}, your {{item}} ships {{day}}
Hi %%first_name%%, your %%item%% ships %%day%%- Names can use letters, numbers and underscores.
- Upper or lower case doesn't matter.
- If a person has no value for a placeholder, it is left blank and their message still sends.
Step 2: Add your recipients and their details
Each recipient has a number (
to), your own reference (optional) and their details (fields).json
POST <your SMS API URL>/sms/send-bulk
Authorization: Bearer <your SMS API key>
Content-Type: application/json
{
"from": "ACME",
"text": "Hi {{first_name}}, your {{item}} ships {{day}}",
"callback": "https://your-server.example/receipts",
"recipients": [
{ "to": "61491570001", "reference": "cust-123",
"fields": { "first_name": "Jane", "item": "widget", "day": "Tuesday" } },
{ "to": "61491570002", "reference": "cust-456",
"fields": { "first_name": "John", "item": "gadget", "day": "Wednesday" } }
]
}⚠️
Put each phone number in quotes ("61491570001"), one number per recipient, with no spaces inside it.
Step 3: Read the reply
You get one row back per recipient, in the same order you sent them.
3 of 3 rows
queued | Accepted and going out | Nothing. Don't send it again. |
failed | Not sent. The row says why. | Fix it and resend that recipient. |
unknown | We couldn't confirm it either way | Check its message ids (Step 5) before resending. |
Each row also shows
parts: how many SMS that person's message came to. Each part is charged, and long details can push a message into two parts.Step 4: Get delivery receipts (optional)
Add a
callback address to your request. When each part is Delivered or Undelivered, we send that result to your address. A message sent in two parts gives you two receipts.- Your server must reply with a success (2xx) within 5 seconds.
- Some parts never get a receipt. Check those with Step 5.
Step 5: Check a message's status
Send one message id to
POST /api/sms/status to see what happened to it. The API reference lists every status and what it means.Limits
4 of 4 rows
| Recipients per request | 500 |
| Message template | 2,000 characters |
| Sender ID | 20 characters |
| Personalised message | 6 SMS parts per recipient |
Troubleshooting
5 of 5 rows
The message shows $_first_name | That field is portal-only | Use {{first_name}} and send the value in fields |
Reply is 403 | The Sender ID isn't approved for your account, or the API key is wrong | Use an approved Sender ID and check the key |
A recipient says not a valid phone number | Spaces inside the number, or more than one number | One number per recipient, digits only, optional + |
A recipient says over the 6-part limit | That person's message is too long | Shorten the template or their details |
| A placeholder came out blank | No matching field for that person | Check the field name in fields |
