Broadcast
Send the same SMS or MMS message to up to 50,000 recipients in a single API call.
Endpoint
POST /api/v1/messaging/broadcast
Request body
| Field | Type | Required | Description |
|---|---|---|---|
recipients | array | Yes | List of recipient objects. Min 100, max 50,000. Each phone number must be unique. |
recipients[].to | string | Yes | Recipient phone number in E.164 format |
recipients[].idempotencyKey | string | No | Idempotency key for this specific recipient. Prevents duplicate messages to the same recipient on retries. |
from | string | Yes | Sender phone number in E.164 format or short code (5-6 digits). Must be active and assigned to your account. |
body | string | Conditional | Message text, up to 640 characters. Required for SMS. |
mediaUrl | string | No | Publicly accessible media URL. When provided, the broadcast is sent as MMS. |
idempotencyKey | string | No | Unique key to prevent duplicate broadcasts on retries. |
Example
curl -X POST https://platform.textingline.com/api/v1/messaging/broadcast \
-u "your_key_id:your_key_secret" \
-H "Content-Type: application/json" \
-d '{
"recipients": [
{"to": "+18005551001"},
{"to": "+18005551002"},
{"to": "+18005551003"}
],
"from": "+18005559876",
"body": "Flash sale! 20% off all items today only. Reply STOP to opt out."
}'Response
{
"id": "brc_DsAdb4EBYBh3z25sBA1qnv",
"from": "+18005559876",
"body": "Flash sale! 20% off all items today only. Reply STOP to opt out.",
"totalRecipients": 3,
"status": "queued",
"createdAt": "2026-03-13T14:30:00.000Z"
}The broadcast is queued as a background job. The response includes the total recipient count and an initial status of queued.
Recipient filtering
Two compliance filters apply to every broadcast. Recipients caught by either are silently dropped from the send, and the response's totalRecipients reflects only the accepted count — it may be lower than the number of recipients in the request.
Opt-in filter. Recipients that are not opted in to any group owned by your account are filtered out. If every recipient is not opted in, the broadcast is rejected with error code 33028.
Hard opt-out filter. Recipients who explicitly refused messages (texted STOP, opted out at a kiosk, or were flagged via carrier propagation) are filtered out. This is a permanent compliance signal — re-engaging these contacts requires fresh consent (they must text in again or otherwise affirmatively opt back in). If every recipient is hard-opted-out, the broadcast is rejected with error code 33029.
Merge tags
The body field supports per-recipient personalization via merge tags like {{contact_first_name}} and {{contact_custom_field_1}}. At send time, each recipient's phone number is looked up against your account's contact book and the matching values are substituted in.
curl -X POST https://platform.textingline.com/api/v1/messaging/broadcast \
-u "your_key_id:your_key_secret" \
-H "Content-Type: application/json" \
-d '{
"from": "+18005559876",
"body": "Hi {{contact_first_name}}, your {{contact_custom_field_1}} tier rewards are ready!",
"recipients": [
{"to": "+18005551001"},
{"to": "+18005551002"}
]
}'Missing data resolves to an empty string — no error is raised. If a recipient's phone number doesn't match any contact in your account, every merge tag in the body is replaced with an empty string for that recipient. The same applies when a contact exists but a specific referenced field is empty (e.g. the contact has no firstName — {{contact_first_name}} becomes an empty string, but other variables still resolve normally). The message is sent in both cases.
Merge tags are substituted in body only — mediaUrl is not templated. The broadcast mediaUrl is a single static URL sent identically to every recipient; if you need per-recipient media, use batch and compute each recipient's URL yourself.
See Merge Tags for the full variable list (contact-scoped, custom fields, date helpers, tracking links) and the Send a personalized broadcast with merge tags recipe for an end-to-end broadcast workflow.
Duplicate recipients
The recipients array must not contain duplicate phone numbers. If duplicates are found, the request is rejected with error code 33024:
{
"code": 33024,
"message": "recipients must not contain duplicate phone numbers",
"status": 400,
"moreInfo": "https://docs.smsfactory.com/docs/error-codes"
}Deduplicate your recipient list before submitting the request.
Credits
Credits are charged per recipient:
- SMS broadcast: 2 credits per recipient (1 message + 1 carrier lookup if needed)
- MMS broadcast: 1 SMS credits + 1 SMS credit per recipient (1 message + 1 carrier lookup if needed)
For a 10,000-recipient SMS broadcast, you'd need 20,000 SMS credits.
Rate limits
The broadcast endpoint allows 1 request per minute. For sending personalized messages to multiple recipients, consider using batch instead. See Rate Limits for details.
Common errors
| Code | Description |
|---|---|
33024 | Duplicate recipients in the request |
33004 | The from number is not assigned to your account |
33012 | Daily messaging quota reached |
33023 | Insufficient credits |
See Error Codes for the full reference.