Create and launch a broadcast
Build a request to copy
This page never sends a request. Fill in the fields, then copy the request and run it from your server.
curl -X POST 'https://api.whatsable.app/v1/broadcasts' \
-H 'Content-Type: application/json' \
-d '{
"from": "cm2v8a1b20002qz8h9i0j1k2l",
"template": {
"name": "october_promo",
"language": "en_US"
},
"variables": {
"1": "friend"
},
"recipients": [
{
"to": "+5491155550000",
"variables": {
"1": "Ana"
}
},
{
"to": "+5491155550001"
}
],
"labels": [
"October promo"
],
"scheduled_at": "2026-10-22T09:00:00-03:00",
"time_zone": "America/Argentina/Buenos_Aires"
}'Creates a broadcast and starts it now, or at scheduled_at. There is no draft step.
A refused request creates nothing. WhatsAble checks the number, the template, the labels, the plan, the media header link and the variables of every recipient first.
A send to one recipient can still fail later. Read each result with GET /v1/broadcasts/{id}/recipients.
bearerAuthAuthorizationBearer <nfy_live_<32 characters>>An API key from Settings > API keys, sent as Authorization: Bearer <key>.
Idempotency-Key?stringAny string up to 255 characters. A repeat with the same key and body answers the stored response; with another body, 409 idempotency_key_reused.
length <= 255application/json- body
A broadcast to create and launch in one call: a template, its recipients, and when and how fast to send. Everything is checked before anything is created.
name?stringShown in the dashboard. Defaults to the template's name and the time of creation.
1 <= length <= 200from?stringThe number to send from, by id or E.164 phone. Absent, the key's default number sends. It must be active.
1 <= length <= 64template*An approved template of the sending number's WhatsApp Business Account. Not an authentication template, and not one with a coupon-code button.
variables?Values for all recipients, keyed by variables[].key. A recipient's own variables win. Left out, a media header sends the file the template was approved with.
recipients*array<>1 to 10,000 recipients, in a body of at most 2 MB. A phone listed twice gets one message, with its first entry's values. Every entry is checked.
1 <= items <= 10000scheduled_at?stringWhen to start, as an RFC 3339 instant with its offset. Absent, or up to 60 seconds in the past, the broadcast starts now. An older instant is refused.
date-timetime_zone?stringAn IANA time zone name, kept for display only. scheduled_at is never read in it.
1 <= length <= 64labels?array<>Labels, by id or exact name, added to each recipient's contact once its message is sent. Each must be available on the sending number.
items <= 1000mode?stringregular: batch_size messages a minute. smart: batches of batch_size, the next only while the read rate holds target_read_rate. risk: as fast as the number may.
"regular""regular""smart""risk"batch_size?integerregular: messages a minute, 1 to 60, default 3. smart: the batch, 1 to 20, default 5. Not for risk.
1 <= value <= 60target_read_rate?numbersmart only: the share of sent messages that must be read before the next batch, 0.1 to 1, default 0.3.
0.1 <= value <= 1The broadcast is scheduled or running.
application/json- response
One template sent to a list of recipients from one number, paced over time.
object*stringid*string1 <= length <= 64name*stringnumber_id*stringThe business number it sends from.
1 <= length <= 64template*The template every recipient gets.
status*stringscheduled, running, then completed when each recipient is sent, failed or skipped. paused: stopped early, also for a lapsed subscription. cancelled: after a cancel.
"scheduled""running""paused""completed""cancelled"mode*stringHow it is paced: regular (fixed messages a minute), smart (batches while the read rate holds its target) or risk (as fast as the number may send).
"regular""smart""risk"scheduled_at*|When it starts, or started: the scheduled_at it was created with, or the moment it was created for one started at once. Null when none was recorded.
time_zone*|The IANA time zone the creator gave, kept for display.
label_ids*array<>Labels added to each recipient's contact once its message is sent.
recipient_count*integerRecipients, each phone counted once.
0 <= value <= 9007199254740991sent_count*integer0 <= value <= 9007199254740991failed_count*integer0 <= value <= 9007199254740991read_count*integer0 <= value <= 9007199254740991pending_count*|Recipients not sent yet. Counted on GET /v1/broadcasts/{id}; null in a list.
started_at*|nullcompleted_at*|nullcreated_at*stringdate-timecurl -X POST 'https://api.whatsable.app/v1/broadcasts' \ -H 'Content-Type: application/json' \ -d '{ "from": "cm2v8a1b20002qz8h9i0j1k2l", "template": { "name": "october_promo", "language": "en_US" }, "variables": { "1": "friend" }, "recipients": [ { "to": "+5491155550000", "variables": { "1": "Ana" } }, { "to": "+5491155550001" } ], "labels": [ "October promo" ], "scheduled_at": "2026-10-22T09:00:00-03:00", "time_zone": "America/Argentina/Buenos_Aires"}'{ "object": "broadcast", "id": "cm2v8w1a00001qz8h5e6f7g8h", "name": "October promo", "number_id": "cm2v8a1b20002qz8h9i0j1k2l", "template": { "id": "cm2v8t1a00001qz8habcd1234", "name": "october_promo", "language": "en_US" }, "status": "running", "mode": "regular", "scheduled_at": "2026-10-20T19:51:20Z", "time_zone": null, "label_ids": [ "cm2v8l1a00001qz8h2b3c4d5e" ], "recipient_count": 1200, "sent_count": 340, "failed_count": 4, "read_count": 120, "pending_count": 856, "started_at": "2026-10-20T19:51:21Z", "completed_at": null, "created_at": "2026-10-20T19:51:20Z"}