How a broadcast runs
1
Create a draft
Name it, pick the sending number and write the template.
2
Upload recipients
A CSV, XLSX or JSON list. Extra columns become template variables.
3
Preview
See rendered samples, segment counts and any variables the file is missing.
4
Launch
Send now or at
scheduledAt. Pause, resume or cancel while it runs.5
Track and export
Per-recipient statuses, live stats, and a CSV of the results.
1. Create a broadcast
Create a broadcast returns a draft:cURL
Response - 201 Created
409 {"error":"cannot edit a broadcast that is running"}.
2. Upload recipients
Upload recipients replaces the draft’s recipient list. Two body formats are accepted.- CSV or XLSX file
- JSON list
Send
multipart/form-data with a file field (.csv or .xlsx, up to 10 MB) and an optional defaultCountry:cURL
recipients.csv
- The phone column is detected by header (
phone,mobile,msisdn,number,to,phonenumberand similar). Without a match the first column is used. - A file with no header row gets columns named
phone,column2,column3, … - The delimiter (
,,;or tab) is sniffed. For XLSX the first sheet is read. - Every other column becomes a template variable with the header as its name.
defaultCountry (default US) is the ISO 3166-1 alpha-2 country used to turn national-format numbers into E.164. Numbers that already start with + are kept as they are.
Supported defaultCountry values
Supported defaultCountry values
US, CA, GB, IN, AU, NZ, IE, DE, FR, ES, IT, NL, BE, CH, AT, SE, NO, DK, FI, PL, PT, BR, MX, AR, CO, CL, SG, MY, ID, PH, TH, VN, JP, KR, CN, HK, AE, SA, QA, IL, TR, ZA, NG, KE, EG, PK, BD, LK, NP. Any other value returns 400 {"error":"defaultCountry must be a supported ISO 3166-1 alpha-2 code"}.Response - 200 OK
Limits and errors: up to 10,000 recipients per broadcast (
422 too many recipients: the limit is 10000 per broadcast), files over 10 MB return 413, other extensions return 400 file must be .csv or .xlsx, and uploads to a broadcast that is no longer a draft return 409.
3. Preview
Preview a broadcast renders the template against the first recipients:cURL
Response - 200 OK
samplesshows the renderedtext, itssegmentsandencoding(GSM-7orUCS-2) for each of the firstlimitrecipients (default 5, maximum 50). See segments and encoding.missingVariableslists placeholders in the template that no uploaded column provides. Fix the template or re-upload before you launch.estimatedSegmentsis the total segments across all pending recipients - multiply by your per-segment rate for the expected cost.
4. Launch
Launch a broadcast starts sending. Only adraft can be launched.
cURL
status is running when sending starts at once, or scheduled when scheduledAt is in the future - it moves to running at that time.
Launch checks return 422 with one of:
Each recipient is sent through the same path as Send a message with the broadcast’s
tag and DLT IDs, at ratePerSecond. Every send carries an idempotency key of broadcast:<broadcastId>:<recipientId>, so a retried worker never double-sends.
Pause, resume, cancel and delete
Any other transition returns
409 {"error":"cannot <action> a broadcast that is <status>"}. An unknown or malformed id returns 404 {"error":"broadcast not found"}.
The worker moves a running broadcast to completed when every recipient has been processed, or to failed if the run cannot continue. When a send is refused for insufficient balance, the broadcast is paused with pauseReason: "insufficient_balance"; top up and call resume.
Broadcast statuses
draft, scheduled, running, paused, completed, cancelled, failed.
Track recipients and stats
Get a broadcast returns freshstats:
limit 1-500, default 50; offset) and filters by status:
Each recipient carries
row, to, variables (the uploaded columns), messageId, errorCode, errorMessage and sentAt. Open the message itself with Retrieve a message for its full status history.
Live updates
Connect to the WebSocket and listen forbroadcast.updated. The event carries the full broadcast object with stats on every status change and roughly every 2 seconds while the broadcast is running - enough to drive a progress bar without polling.
Export the results
Export a broadcast streams a CSV (text/csv, Content-Disposition: attachment; filename="broadcast-<id>.csv"):
cURL
row, to, status, message_id, error_code, error_message, sent_at, followed by one column per uploaded variable. Cells that begin with =, +, -, @ or a tab are prefixed with ' so spreadsheets do not treat them as formulas.
Listing broadcasts
List broadcasts returns{"broadcasts": [...], "total": n}, newest first, with limit 1-500 (default 50) and offset.
Before you go live
Compliance overview
Register before you send at volume.
Messaging numbers
Pick a registered sender for the broadcast.
Related
Opt-outs
How opted-out numbers are excluded from every broadcast.
SMS
Segments, encoding and statuses behind each recipient.
India DLT
DLT IDs for broadcasts to Indian numbers.
WebSocket
Live
broadcast.updated events.