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

# Broadcasts

> Send messages to thousands of recipients with a single API call

Broadcasts let you send the same message to many recipients without making individual API calls. Perfect for marketing campaigns, announcements, and bulk notifications.

## Why Use Broadcasts?

Instead of making 10,000 individual API calls:

```typescript theme={null}
// Without broadcasts - 10,000 API calls
for (const contact of contacts) {
  await zavu.messages.send({
    to: contact.phone,
    text: "Black Friday sale starts now!",
  });
}
```

Use a single broadcast:

```typescript theme={null}
// With broadcasts - 3 API calls total
const broadcast = await zavu.broadcasts.create({
  name: "Black Friday Campaign",
  channel: "sms",
  text: "Black Friday sale starts now!",
});

await zavu.broadcasts.addContacts(broadcast.id, {
  contacts: contacts.map(c => ({ recipient: c.phone })),
});

await zavu.broadcasts.send(broadcast.id);
```

## Key Features

<CardGroup cols={2}>
  <Card title="Batch Processing" icon="layer-group">
    Add up to 1,000 contacts per request. Zavu handles rate limiting and delivery optimization automatically.
  </Card>

  <Card title="Personalization" icon="user">
    Customize each message with per-contact template variables like names, order IDs, or custom fields.
  </Card>

  <Card title="Scheduling" icon="clock">
    Schedule broadcasts for future delivery. Perfect for time-zone aware campaigns.
  </Card>

  <Card title="Real-time Progress" icon="chart-line">
    Poll for delivery progress with instant updates on sent, delivered, and failed counts.
  </Card>
</CardGroup>

## Balance Reservation

When you send a broadcast, Zavu reserves the estimated cost from your balance. This ensures funds are available for the entire campaign and prevents overspending.

```
Balance: $100.00 → Send Broadcast ($25 estimated) → Available: $75.00, Reserved: $25.00
```

Reserved funds are released when the broadcast completes or is cancelled. [Learn more](/guides/broadcasts/sending#balance-reservation)

## Broadcast Lifecycle

```
Draft → Pending Review → Approved → Scheduled (optional) → Sending → Completed
              ↓                                               ↓
          Rejected ────→ Escalated ────→ Rejected Final   Cancelled
              ↑              ↓
              └──── Edit ←───┘
```

| Status           | Description                                |
| ---------------- | ------------------------------------------ |
| `draft`          | Initial state. Add/remove contacts freely. |
| `pending_review` | Content being reviewed by AI.              |
| `approved`       | Review passed, ready to send.              |
| `rejected`       | Content rejected, edit and retry.          |
| `escalated`      | Sent to human review.                      |
| `rejected_final` | Rejected by human review (cannot appeal).  |
| `scheduled`      | Waiting to send at scheduled time.         |
| `sending`        | Messages being delivered.                  |
| `completed`      | All messages processed.                    |
| `cancelled`      | Broadcast stopped before completion.       |

## Quick Example

<CodeGroup>
  ```typescript TypeScript theme={null}
  import Zavudev from '@zavudev/sdk';

  const zavu = new Zavudev({
    apiKey: process.env['ZAVUDEV_API_KEY'], // This is the default and can be omitted
  });

  // 1. Create the broadcast
  const broadcast = await zavu.broadcasts.create({
    name: "Order Confirmation Campaign",
    channel: "sms",
    text: "Hi {{name}}, your order #{{order_id}} has shipped!",
  });

  // 2. Add contacts with personalization
  await zavu.broadcasts.addContacts(broadcast.id, {
    contacts: [
      {
        recipient: "+14155551234",
        templateVariables: { name: "John", order_id: "ORD-001" }
      },
      {
        recipient: "+14155555678",
        templateVariables: { name: "Jane", order_id: "ORD-002" }
      },
    ],
  });

  // 3. Send immediately
  await zavu.broadcasts.send(broadcast.id);

  // 4. Check progress
  const progress = await zavu.broadcasts.getProgress(broadcast.id);
  console.log(`${progress.percentComplete}% complete`);
  ```

  ```python Python theme={null}
  import os
  from zavudev import Zavudev

  zavu = Zavudev(
      api_key=os.environ.get("ZAVUDEV_API_KEY"),  # This is the default and can be omitted
  )

  # 1. Create the broadcast
  broadcast = zavu.broadcasts.create(
      name="Order Confirmation Campaign",
      channel="sms",
      text="Hi {{name}}, your order #{{order_id}} has shipped!"
  )

  # 2. Add contacts with personalization
  zavu.broadcasts.add_contacts(broadcast.id, contacts=[
      {
          "recipient": "+14155551234",
          "templateVariables": {"name": "John", "order_id": "ORD-001"}
      },
      {
          "recipient": "+14155555678",
          "templateVariables": {"name": "Jane", "order_id": "ORD-002"}
      },
  ])

  # 3. Send immediately
  zavu.broadcasts.send(broadcast.id)

  # 4. Check progress
  progress = zavu.broadcasts.get_progress(broadcast.id)
  print(f"{progress.percent_complete}% complete")
  ```

  ```ruby Ruby theme={null}
  require "zavudev"

  client = Zavudev::Client.new(api_key: ENV["ZAVUDEV_API_KEY"])

  # 1. Create the broadcast
  broadcast = client.broadcasts.create(
    name: "Order Confirmation Campaign",
    channel: "sms",
    text: "Hi {{name}}, your order #{{order_id}} has shipped!"
  )

  # 2. Add contacts with personalization
  client.broadcasts.add_contacts(broadcast.id, contacts: [
    {
      recipient: "+14155551234",
      template_variables: { name: "John", order_id: "ORD-001" }
    },
    {
      recipient: "+14155555678",
      template_variables: { name: "Jane", order_id: "ORD-002" }
    },
  ])

  # 3. Send immediately
  client.broadcasts.send(broadcast.id)

  # 4. Check progress
  progress = client.broadcasts.get_progress(broadcast.id)
  puts "#{progress.percent_complete}% complete"
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"fmt"
  	"os"

  	"github.com/zavudev/sdk-go"
  )

  func main() {
  	client := zavudev.NewClient(zavudev.WithAPIKey(os.Getenv("ZAVUDEV_API_KEY")))

  	// 1. Create the broadcast
  	broadcast, _ := client.Broadcasts.Create(context.TODO(), zavudev.BroadcastCreateParams{
  		Name:    zavudev.String("Order Confirmation Campaign"),
  		Channel: zavudev.String("sms"),
  		Text:    zavudev.String("Hi {{name}}, your order #{{order_id}} has shipped!"),
  	})

  	// 2. Add contacts with personalization
  	client.Broadcasts.AddContacts(context.TODO(), broadcast.ID, zavudev.BroadcastAddContactsParams{
  		Contacts: []zavudev.BroadcastContactInput{
  			{
  				Recipient:         zavudev.String("+14155551234"),
  				TemplateVariables: map[string]string{"name": "John", "order_id": "ORD-001"},
  			},
  			{
  				Recipient:         zavudev.String("+14155555678"),
  				TemplateVariables: map[string]string{"name": "Jane", "order_id": "ORD-002"},
  			},
  		},
  	})

  	// 3. Send immediately
  	client.Broadcasts.Send(context.TODO(), broadcast.ID, zavudev.BroadcastSendParams{})

  	// 4. Check progress
  	progress, _ := client.Broadcasts.GetProgress(context.TODO(), broadcast.ID)
  	fmt.Printf("%v%% complete\n", progress.PercentComplete)
  }
  ```

  ```php PHP theme={null}
  $client = new Zavudev\Client(apiKey: getenv('ZAVUDEV_API_KEY'));

  // 1. Create the broadcast
  $broadcast = $client->broadcasts->create([
      'name' => 'Order Confirmation Campaign',
      'channel' => 'sms',
      'text' => 'Hi {{name}}, your order #{{order_id}} has shipped!',
  ]);

  // 2. Add contacts with personalization
  $client->broadcasts->addContacts($broadcast->id, [
      'contacts' => [
          [
              'recipient' => '+14155551234',
              'templateVariables' => ['name' => 'John', 'order_id' => 'ORD-001'],
          ],
          [
              'recipient' => '+14155555678',
              'templateVariables' => ['name' => 'Jane', 'order_id' => 'ORD-002'],
          ],
      ],
  ]);

  // 3. Send immediately
  $client->broadcasts->send($broadcast->id);

  // 4. Check progress
  $progress = $client->broadcasts->getProgress($broadcast->id);
  echo "{$progress->percentComplete}% complete\n";
  ```

  ```bash cURL theme={null}
  # 1. Create the broadcast
  curl -X POST https://api.zavu.dev/v1/broadcasts \
    -H "Authorization: Bearer $ZAVU_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Order Confirmation Campaign",
      "channel": "sms",
      "text": "Hi {{name}}, your order #{{order_id}} has shipped!"
    }'

  # 2. Add contacts
  curl -X POST https://api.zavu.dev/v1/broadcasts/{broadcastId}/contacts \
    -H "Authorization: Bearer $ZAVU_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "contacts": [
        {"recipient": "+14155551234", "templateVariables": {"name": "John", "order_id": "ORD-001"}},
        {"recipient": "+14155555678", "templateVariables": {"name": "Jane", "order_id": "ORD-002"}}
      ]
    }'

  # 3. Send the broadcast
  curl -X POST https://api.zavu.dev/v1/broadcasts/{broadcastId}/send \
    -H "Authorization: Bearer $ZAVU_API_KEY"

  # 4. Check progress
  curl https://api.zavu.dev/v1/broadcasts/{broadcastId}/progress \
    -H "Authorization: Bearer $ZAVU_API_KEY"
  ```
</CodeGroup>

## Supported Channels

| Channel  | Message Types                                 | Personalization    |
| -------- | --------------------------------------------- | ------------------ |
| SMS      | Text                                          | Template variables |
| WhatsApp | Text, Image, Video, Audio, Document, Template | Template variables |
| Email    | Text, HTML                                    | Template variables |

<Info>
  WhatsApp broadcasts using free-form messages (non-template) require an open 24-hour conversation window with each recipient. Use WhatsApp templates for marketing campaigns to recipients who haven't messaged you recently.
</Info>

## Limits

| Limit                  | Default  | Notes                       |
| ---------------------- | -------- | --------------------------- |
| Contacts per request   | 1,000    | Add contacts in batches     |
| Contacts per broadcast | 1,000    | Contact support to increase |
| Concurrent broadcasts  | No limit | Rate limits still apply     |

## Next Steps

<CardGroup cols={2}>
  <Card title="Creating Broadcasts" icon="plus" href="/guides/broadcasts/creating-broadcasts">
    Configure message content and channel settings
  </Card>

  <Card title="Adding Contacts" icon="users" href="/guides/broadcasts/adding-contacts">
    Batch upload and personalization
  </Card>

  <Card title="Sending & Scheduling" icon="paper-plane" href="/guides/broadcasts/sending">
    Send immediately or schedule for later
  </Card>

  <Card title="Tracking Progress" icon="chart-simple" href="/guides/broadcasts/tracking-progress">
    Monitor delivery in real-time
  </Card>
</CardGroup>
