Skip to content

Run a broadcast

Send one approved template to a list of customers or to everyone with a tag, now or later, and follow it until it's done.

15 minutesDevelopersUpdated

A broadcast sends one template to many customers, each with their own variables. It’s the API’s version of a campaign, and shows in Campaigns in the app like any other. This guide sends the diwali_offer template to Priya and Rahul.

  • An API key that can Create, cancel and resume broadcasts (broadcasts:write) and Read broadcasts and recipients (broadcasts:read)
  • An approved template on the number you send from. Authentication templates can’t be broadcast.
  • Room in your plan’s broadcast messages for this month

Look up the template’s variables first, as in Send a template. Every recipient fills in exactly those keys.

Send exactly one of these:

  • recipients: a list of 1 to 10,000 phone numbers, each with its own variables. Use it when your system decides who gets the message.
  • audience: your contacts with any of some tags, with the variables taken from each contact. Use it when Soosh already has the contacts.

Either way Soosh leaves out numbers that aren’t valid, repeats of a number already in the list, and, for a marketing template, contacts who opted out of marketing messages. It counts them in the broadcast’s skipped. Mexican and Argentine mobiles count as one number however WhatsApp writes them (with or without the 1 after 52, or the 9 after 54).

If that leaves nobody, a list is refused with 422 invalid_field. An audience is collected after the broadcast is made, so there the broadcast becomes failed instead, with paused_reason saying why. The same happens when a collected audience doesn’t fit in this month’s broadcast messages.

Create a broadcast with one of the two.

Terminal window
curl https://app.soosh.io/v1/broadcasts \
-H "Authorization: Bearer $SOOSH_API_KEY" \
-H "Idempotency-Key: diwali-2026" \
-H "Content-Type: application/json" \
-d '{
"name": "Diwali offer",
"template": { "name": "diwali_offer", "language": "en" },
"recipients": [
{ "to": "+919876543210", "name": "Priya", "body": { "1": "Priya" }, "buttons": { "0": "PRIYA10" } },
{ "to": "+919812345678", "name": "Rahul", "body": { "1": "Rahul" }, "buttons": { "0": "RAHUL10" } }
]
}'

If any recipient’s variables don’t match the template, nothing is saved. The answer is one 422 template_params, and details.rows lists up to 100 bad rows as {index, missing, unexpected}. The whole request can be at most 4 MB.

Terminal window
curl https://app.soosh.io/v1/broadcasts \
-H "Authorization: Bearer $SOOSH_API_KEY" \
-H "Idempotency-Key: diwali-2026-vip" \
-H "Content-Type: application/json" \
-d '{
"name": "Diwali offer for VIPs",
"template": { "name": "diwali_offer", "language": "en" },
"audience": {
"tags": ["VIP"],
"exclude_tags": ["Unsubscribed"],
"body": { "1": { "from": "contact.name", "fallback": "there" } },
"buttons": { "0": { "from": "attribute:coupon", "fallback": "DIWALI10" } }
}
}'

Each variable says where its value comes from:

from The value
contact.name The contact’s name
contact.phone The contact’s number, as + and digits
attribute:<name> One of the contact’s attributes, like attribute:coupon
text:<value> The same text for everyone, like text:Diwali

fallback is used when a contact has no usable value. It’s required for contact.name and attribute: sources.

The audience is the contacts that already existed when you made the broadcast, with the tags they have when Soosh collects them, a moment later. A contact added after you made the broadcast isn’t included, even if it has the tag. A contact that already existed and is tagged after you made it is included.

The broadcast comes back at once as preparing while Soosh collects the audience. It then sends, or becomes scheduled, on its own.

Add send_at, 5 minutes to 30 days from now, in RFC 3339:

"send_at": "2026-11-01T04:30:00Z"

The broadcast is scheduled until then. Its messages count against the month it sends in.

The answer to step 2 is the broadcast. Keep its id, then follow it in either of these ways:

To see what happened to each customer, list the recipients, for example only the failed ones:

Terminal window
curl "https://app.soosh.io/v1/broadcasts/$BROADCAST_ID/recipients?status=failed" \
-H "Authorization: Bearer $SOOSH_API_KEY"

A broadcast ends as completed, cancelled, failed or missed. See Campaign statuses.

A broadcast pauses on its own when something stops it, and paused_reason says why, for example “This workspace has sent its 1,000 broadcast messages for October. Campaigns can be resumed from November 1, or contact support to raise the limit.”

Limit Value
Recipients in a list 1 to 10,000
Request size 4 MB
Tags in an audience 1 to 20, and up to 20 to leave out
Broadcasts, templates and uploads made, and usage read 10 a minute for each workspace, together
Broadcast messages Your plan’s broadcast_messages_per_month. Soosh checks before it starts, and a broadcast that reaches the limit while sending pauses.

Broadcasts don’t count against api_messages_per_second. See Rate limits.

Priya and Rahul each get the offer with their own name and code. The broadcast shows in Campaigns in the app, made by your key, and its results update as WhatsApp reports them.