> ## Documentation Index
> Fetch the complete documentation index at: https://www.vobiz.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Vobiz Messaging API - Broadcasts

> The Vobiz Broadcasts API sends one personalised SMS template to up to 10,000 recipients at a controlled rate - create a draft, upload recipients, preview, launch, then track and export the results.

A broadcast sends one SMS template to a list of recipients, personalised per recipient from the columns of your upload. You use it for announcements, reminders and notifications that go to many people at once, at a rate you choose. Every recipient gets its own message, its own status and its own row in the results export.

<Warning>
  Launching or resuming a broadcast sends real SMS to every pending recipient and charges your account per segment. Run those calls only with your own credentials, on a list you have consent to message.
</Warning>

## The broadcast object

| Field | Type | Description |
| - | - | - |
| `id` | string (UUID) | Unique identifier. Use it in every `/broadcasts/{id}` path. |
| `accountId` | string | Your Vobiz account ID (`MA_...`). |
| `name` | string | Your label for the broadcast, up to 255 characters. |
| `from` | string | The sending number in E.164, a short code, or an alphanumeric sender ID of up to 11 characters. |
| `channel` | string | Always `sms`. |
| `template` | string | Message body with `{{variable}}` placeholders, up to 5,000 characters. |
| `status` | string | `draft`, `scheduled`, `running`, `paused`, `completed`, `cancelled` or `failed`. |
| `pauseReason` | string | Present only when the broadcast paused itself. `insufficient_balance` means the balance ran out. |
| `scheduledAt` | string or `null` | When sending starts after launch (UTC). `null` sends on launch. |
| `ratePerSecond` | integer | Maximum messages per second, 1 to 50. Default 5. |
| `tag` | string | Your label, copied onto every message the broadcast sends. |
| `dltEntityId`, `dltHeaderId`, `dltTemplateId` | string | India (TRAI DLT) IDs copied onto every message. |
| `columns` | array of strings | Column names from the latest upload. The first is the phone column. |
| `stats` | object | Recipient counts: `total`, `pending`, `sent`, `delivered`, `failed`, `optedOut`, `skipped`. |
| `createdAt`, `updatedAt` | string | ISO 8601 timestamps (UTC). |
| `startedAt`, `completedAt` | string or `null` | When sending began and when the broadcast finished or was cancelled. |

## Endpoints

| Method | Endpoint | What it does |
| - | - | - |
| `POST` | [`/broadcasts`](/docs/sms/api/broadcasts/create-broadcast) | Create a draft broadcast. |
| `GET` | [`/broadcasts`](/docs/sms/api/broadcasts/list-broadcasts) | List broadcasts, newest first. |
| `GET` | [`/broadcasts/{id}`](/docs/sms/api/broadcasts/get-broadcast) | Retrieve one broadcast with live stats. |
| `PUT` | [`/broadcasts/{id}`](/docs/sms/api/broadcasts/update-broadcast) | Change fields on a draft. |
| `DELETE` | [`/broadcasts/{id}`](/docs/sms/api/broadcasts/delete-broadcast) | Delete a draft or cancelled broadcast. |
| `POST` | [`/broadcasts/{id}/recipients`](/docs/sms/api/broadcasts/upload-recipients) | Upload recipients from CSV, XLSX or JSON. |
| `GET` | [`/broadcasts/{id}/recipients`](/docs/sms/api/broadcasts/list-recipients) | List recipients and their send state. |
| `GET` | [`/broadcasts/{id}/preview`](/docs/sms/api/broadcasts/preview-broadcast) | Render samples and count segments before launch. |
| `GET` | [`/broadcasts/{id}/export`](/docs/sms/api/broadcasts/export-broadcast) | Download per-recipient results as CSV. |
| `POST` | [`/broadcasts/{id}/launch`](/docs/sms/api/broadcasts/launch-broadcast) | Start sending. |
| `POST` | [`/broadcasts/{id}/pause`](/docs/sms/api/broadcasts/pause-broadcast) | Pause a running broadcast. |
| `POST` | [`/broadcasts/{id}/resume`](/docs/sms/api/broadcasts/resume-broadcast) | Resume a paused broadcast. |
| `POST` | [`/broadcasts/{id}/cancel`](/docs/sms/api/broadcasts/cancel-broadcast) | Stop a broadcast for good. |

## Lifecycle

A broadcast starts as a `draft`. You can edit it, replace its recipients and preview it as often as you like; nothing is sent until you launch.

| From | Action | To |
| - | - | - |
| `draft` | Launch with no `scheduledAt`, or one in the past | `running` |
| `draft` | Launch with a future `scheduledAt` | `scheduled`, then `running` at that time |
| `running` | Pause | `paused` |
| `running` | Balance runs out | `paused` with `pauseReason: insufficient_balance` |
| `paused` | Resume | `running` |
| `running` | Every recipient processed | `completed` |
| `running` | The run stops on an error | `failed` |
| `draft`, `scheduled`, `running`, `paused` | Cancel | `cancelled` |

An action that does not apply to the current status returns `409` with a message such as `cannot pause a broadcast that is draft`. Only a `draft` can be edited or given new recipients. Only a `draft` or `cancelled` broadcast can be deleted.

## Recipients and variables

* A file upload (`.csv` or `.xlsx`, up to 10 MB) turns every column other than the phone column into a template variable named after its header. A JSON upload with `numbers` gives a plain list with no variables.
* Placeholders match column names case-insensitively, so `{{ Name }}` fills from a `name` column. Placeholders with no matching column render as empty text and appear in the preview's `missingVariables`.
* Numbers without a country code are normalised to E.164 with `defaultCountry` (default `US`).
* Duplicates are dropped and invalid rows are reported with a reason. Numbers that opted out of SMS from you are stored as `opted_out` and never sent.
* A broadcast holds up to 10,000 recipients. Each upload replaces the previous list.

Each recipient moves through `pending`, `sending`, `sent` and `delivered`, or ends as `failed`, `opted_out` or `skipped` (still pending when the broadcast was cancelled).

## Pagination

`GET /broadcasts` and `GET /broadcasts/{id}/recipients` take `limit` (1 to 500, default 50) and `offset` (default 0). Both return the page in an array next to a `total` count, so you can page until `offset` reaches `total`.

## Example

Upload recipients from a CSV file to a draft:

```bash cURL theme={null}
curl -X POST "https://api.vobiz.ai/api/v1/sms/broadcasts/9b2e1c40-8a3d-4f5e-9c1a-7d6b2e8f4a01/recipients" \
  -H "X-Auth-ID: MA_XXXXXXXX" \
  -H "X-Auth-Token: YOUR_AUTH_TOKEN" \
  -F "file=@recipients.csv" \
  -F "defaultCountry=US"
```

```json Response theme={null}
{
  "total": 3,
  "valid": 2,
  "invalid": [
    { "row": 4, "value": "12", "reason": "too short" }
  ],
  "invalidCount": 1,
  "duplicates": 0,
  "optedOut": 0,
  "columns": ["phone", "name", "amount"]
}
```

## Related

* [Broadcasts guide](/docs/sms/broadcasts) - the full create, upload, preview and launch walkthrough.
* [Opt-outs](/docs/sms/opt-outs) - how opted-out numbers are excluded from broadcasts.
* [India DLT](/docs/sms/compliance/india-dlt) - the DLT IDs to set when you message Indian numbers.
* [WebSocket](/docs/sms/websocket) - follow progress with the `broadcast.updated` event.
* [Errors](/docs/sms/errors) - error responses and how to handle them.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.