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

# Overview

> Send an approved template to many recipients with per-recipient tracking

A broadcast sends one approved WhatsApp template to a list of recipients, and tracks delivery, reads, and replies for each one.

Broadcasts are template-only. Meta requires an approved template to open a conversation, so free-form text cannot be broadcast.

## Lifecycle

| Status      | Meaning                                                                                                   |
| ----------- | --------------------------------------------------------------------------------------------------------- |
| `draft`     | Being built. Recipients can be added or cleared                                                           |
| `scheduled` | Will start automatically at `scheduled_at`                                                                |
| `copying`   | Duplicated from another broadcast, recipients still being copied. Shown as **Preparing** in the dashboard |
| `sending`   | Currently delivering                                                                                      |
| `completed` | All recipients processed                                                                                  |
| `stopped`   | Manually stopped mid-send                                                                                 |
| `failed`    | Could not complete                                                                                        |

Two paths through it:

* `draft` → `sending` → `completed`, `failed`, or `stopped`
* `draft` → `scheduled` → `sending` → …

The transitions are enforced:

* Scheduling requires a `scheduled_at` timestamp
* Recipients can only be added or cleared while `draft` or `scheduled`
* Cancelling only works while `scheduled`, and returns the broadcast to `draft`
* Stopping only works while `sending`. Pending recipients stay pending and are not sent
* A `draft` or `scheduled` broadcast with a CSV upload or contact import still running rejects those changes with `422` until the import finishes
* A `copying` broadcast rejects them for the same reason, until its recipients have been copied

## Add recipients

Two ways, and they produce the same result:

<CardGroup cols={2}>
  <Card title="CSV upload" icon="file-csv" href="/docs/platform/broadcasts/csv-upload">
    Upload a spreadsheet in the dashboard. No code.
  </Card>

  <Card title="Broadcasts API" icon="code" href="/docs/platform/broadcasts/api">
    Create and send programmatically.
  </Card>
</CardGroup>

The API accepts up to 1000 recipients per request. Send more by repeating the call.

## Duplicate a broadcast

Duplicate an existing broadcast from the broadcast list or its details page. The copy keeps the
template, template parameters, agent, and every recipient with their personalized values, and
starts as a new `draft` with delivery state reset — no counts, timestamps, or per-recipient results
are carried over.

Large recipient lists are copied in the background. The copy stays in `copying` until every
recipient has been written, and cannot be edited, sent, or scheduled until then. If the copy
cannot be completed it becomes `failed` rather than `draft`.

While a copy is being prepared, the source broadcast is also locked: it cannot be edited, sent,
scheduled, or deleted until the copy finishes.

## Metrics

Every broadcast exposes running counts:

| Field              | Meaning                                                      |
| ------------------ | ------------------------------------------------------------ |
| `total_recipients` | Recipients on the list                                       |
| `pending_count`    | Not yet sent                                                 |
| `sent_count`       | Accepted by WhatsApp                                         |
| `delivered_count`  | Reached the device                                           |
| `read_count`       | Opened by the recipient                                      |
| `failed_count`     | Rejected or undeliverable                                    |
| `suppressed_count` | Skipped because the contact stopped marketing on this number |
| `responded_count`  | Recipients who replied                                       |
| `response_rate`    | `responded_count` as a percentage of `sent_count`            |

Per-recipient status, timestamps, and error messages are available through [List individual recipients](/docs/platform/broadcasts/api#list-individual-recipients).

## Marketing opt-outs

A contact can tell WhatsApp to stop receiving marketing messages from one of your numbers. Kapso
records that per number and enforces it on marketing template sends.

Recipients of a marketing broadcast who have stopped get the `suppressed` status. Nothing is sent
to them, and they are not charged. They stay out of the `sent_count` and `failed_count`
denominators, so delivery and failure rates describe only the messages you actually attempted.

The opt-out applies to marketing templates only. Utility and authentication templates, and
free-form replies inside an open session, are unaffected. It is also scoped to the number the
contact stopped: a broadcast from a different number reaches them normally.

Subscribe to [`whatsapp.contact.marketing_preference_changed`](/docs/platform/webhooks/message-events#whatsapp-contact-marketing-preference-changed)
to mirror these opt-outs into your own system, or check a contact before sending with the
[marketing preferences API](/docs/whatsapp/templates/marketing-opt-outs#check-a-contacts-preference).
See [Marketing opt-outs](/docs/whatsapp/templates/marketing-opt-outs) for the full behavior.

## Delivery pacing

Kapso batches sends automatically and paces them to stay within WhatsApp's throughput limits. Batch size scales with the size of the list, so you do not need to throttle your own requests or split large lists.
