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

# Broadcast Messages

> Send messages to multiple recipients with intelligent rate limiting and real-time progress tracking

# Broadcast Messages

The Broadcast Messages feature enables you to send messages to multiple recipients efficiently while automatically handling WhatsApp API rate limits and providing real-time progress tracking.

## Overview

Send the same message or personalized template messages to thousands of recipients with:

* **Intelligent Rate Limiting**: Automatic compliance with WhatsApp's 80 msg/sec and 1000 msg/min limits
* **Progress Tracking**: Real-time updates on send status, success rate, and estimated completion time
* **Error Handling**: Individual message failures don't stop the entire broadcast
* **Batch Processing**: Efficient chunked processing for optimal throughput
* **Abort Control**: Stop broadcasts mid-process when needed

## Use Cases

<AccordionGroup>
  <Accordion title="E-commerce" icon="shopping-cart">
    * Order confirmations
    * Shipping updates
    * Delivery notifications
    * Cart abandonment reminders
  </Accordion>

  <Accordion title="Appointments & Reminders" icon="calendar">
    * Medical appointment confirmations
    * Service reminders
    * Event notifications
  </Accordion>

  <Accordion title="Marketing Campaigns" icon="megaphone">
    * Promotional messages (using approved templates)
    * Product launches
    * Special offers
  </Accordion>

  <Accordion title="Alerts & Notifications" icon="bell">
    * System status updates
    * Emergency alerts
    * Important announcements
  </Accordion>

  <Accordion title="Customer Service" icon="headset">
    * Survey requests
    * Feedback collection
    * Service updates
  </Accordion>
</AccordionGroup>

## Quick Start

### Simple Text Broadcast

```javascript theme={null}
import { WhatsAppClient } from 'whatsapp-client-sdk';

const client = new WhatsAppClient({
  accessToken: 'your-token',
  phoneNumberId: 'your-phone-id'
});

const phoneNumbers = [
  '+1234567890',
  '+0987654321',
  '+1122334455'
];

const result = await client.sendBroadcastText(
  phoneNumbers,
  'Hello! This is a broadcast message.'
);

console.log(`Sent: ${result.successful}/${result.total}`);
console.log(`Failed: ${result.failed}`);
console.log(`Duration: ${result.duration}ms`);
```

### Personalized Template Broadcast

```javascript theme={null}
const recipients = [
  {
    phoneNumber: '+1234567890',
    variables: {
      name: 'John',
      order_id: '#12345',
      amount: '$99.99'
    }
  },
  {
    phoneNumber: '+0987654321',
    variables: {
      name: 'Jane',
      order_id: '#12346',
      amount: '$149.99'
    }
  }
];

const result = await client.sendBulkTemplates(
  recipients,
  'order_confirmation',  // Your approved template name
  'en_US'
);
```

## Advanced Usage

### Progress Tracking

Monitor your broadcast in real-time:

```javascript theme={null}
const result = await client.sendBroadcastText(
  phoneNumbers,
  'Your message here',
  {
    onProgress: (progress) => {
      console.log(`Progress: ${progress.percentage.toFixed(1)}%`);
      console.log(`Sent: ${progress.sent}/${progress.total}`);
      console.log(`Failed: ${progress.failed}`);
      console.log(`Pending: ${progress.pending}`);
      console.log(`ETA: ${Math.round(progress.estimatedTimeRemaining / 1000)}s`);
    },
    onMessageSent: (result) => {
      if (result.success) {
        console.log(`✓ Sent to ${result.phoneNumber}`);
      } else {
        console.log(`✗ Failed to ${result.phoneNumber}: ${result.error}`);
      }
    }
  }
);
```

### Custom Batch Configuration

```javascript theme={null}
const result = await client.sendBroadcastText(
  phoneNumbers,
  'Your message',
  {
    batchSize: 100,              // Messages per batch (default: 50)
    delayBetweenBatches: 5000,   // Delay in ms (default: auto-calculated)
    stopOnError: false           // Continue on errors (default: false)
  }
);
```

### Abort Broadcast

```javascript theme={null}
// Start broadcast
const broadcastPromise = client.sendBroadcastText(
  largePhoneNumberList,
  'Message'
);

// Abort after 5 seconds
setTimeout(() => {
  if (client.isBroadcastRunning()) {
    client.abortBroadcast();
    console.log('Broadcast aborted!');
  }
}, 5000);

const result = await broadcastPromise;
console.log(`Sent before abort: ${result.successful}`);
```

## Rate Limiting

The SDK automatically handles WhatsApp Business API rate limits:

| Limit               | Value             | SDK Behavior                              |
| ------------------- | ----------------- | ----------------------------------------- |
| Messages per second | 80                | Throttles to \~77 msg/sec (safety margin) |
| Messages per minute | 1000              | Batches with calculated delays            |
| Concurrent requests | No official limit | Limits to 10 concurrent within batch      |

### How It Works

1. **Chunking**: Large batches are split into chunks of 10 messages
2. **Throttling**: Each message takes minimum 13ms (\~77 msg/sec)
3. **Batch Delays**: Automatic delays between batches to respect per-minute limits
4. **Sequential Processing**: Chunks processed sequentially to prevent spikes

## API Reference

### `sendBroadcast(phoneNumbers, message, options?)`

Send the same message to multiple recipients.

**Parameters:**

* `phoneNumbers` (string\[]): Array of recipient phone numbers
* `message` (OutgoingMessage): Message object with type and content
* `options` (BroadcastOptions): Optional configuration

**Returns:** `Promise<BroadcastResult>`

***

### `sendBroadcastText(phoneNumbers, text, options?)`

Shorthand for sending text broadcasts.

**Parameters:**

* `phoneNumbers` (string\[]): Array of recipient phone numbers
* `text` (string): Message text
* `options` (BroadcastOptions): Optional configuration

**Returns:** `Promise<BroadcastResult>`

***

### `sendBulkTemplates(recipients, templateName, languageCode, options?)`

Send personalized template messages to multiple recipients.

**Parameters:**

* `recipients` (BroadcastRecipient\[]): Recipients with variables
* `templateName` (string): Approved template name
* `languageCode` (string): Template language (e.g., 'en\_US')
* `options` (BroadcastOptions): Optional configuration

**Returns:** `Promise<BroadcastResult>`

***

### `abortBroadcast()`

Stop the currently running broadcast.

**Returns:** `void`

***

### `isBroadcastRunning()`

Check if a broadcast is currently in progress.

**Returns:** `boolean`

## Types

### BroadcastOptions

```typescript theme={null}
interface BroadcastOptions {
  batchSize?: number;                              // Messages per batch (default: 50)
  delayBetweenBatches?: number;                    // Delay in ms (default: auto)
  onProgress?: (progress: BroadcastProgress) => void;
  onMessageSent?: (result: MessageSendResult) => void;
  stopOnError?: boolean;                           // Stop on first error (default: false)
}
```

### BroadcastResult

```typescript theme={null}
interface BroadcastResult {
  broadcastId: string;           // Unique broadcast identifier
  total: number;                 // Total messages attempted
  successful: number;            // Successfully sent
  failed: number;                // Failed to send
  results: MessageSendResult[];  // Individual results
  duration: number;              // Total duration in ms
  startTime: number;             // Start timestamp
  endTime: number;               // End timestamp
}
```

### BroadcastProgress

```typescript theme={null}
interface BroadcastProgress {
  total: number;                 // Total messages
  sent: number;                  // Messages sent (successful + failed)
  failed: number;                // Failed messages
  pending: number;               // Remaining messages
  percentage: number;            // Completion percentage (0-100)
  startTime: number;             // Start timestamp
  currentTime: number;           // Current timestamp
  estimatedTimeRemaining?: number; // Estimated ms remaining
}
```

### MessageSendResult

```typescript theme={null}
interface MessageSendResult {
  phoneNumber: string;
  success: boolean;
  messageId?: string;            // WhatsApp message ID if successful
  error?: string;                // Error message if failed
  timestamp: number;             // Send attempt timestamp
}
```

### BroadcastRecipient

```typescript theme={null}
interface BroadcastRecipient {
  phoneNumber: string;
  variables?: Record<string, string>; // Template variable substitutions
}
```

## Best Practices

### 1. Use Templates for Marketing

Text messages only work within the 24-hour conversation window. For marketing or notifications outside this window, use approved message templates.

<Tabs>
  <Tab title="✅ Good">
    ```javascript theme={null}
    // Using templates
    await client.sendBulkTemplates(recipients, 'promo_template', 'en_US');
    ```
  </Tab>

  <Tab title="❌ Avoid">
    ```javascript theme={null}
    // Text outside 24h window will fail
    await client.sendBroadcastText(numbers, 'Buy now!'); // Will fail for most
    ```
  </Tab>
</Tabs>

### 2. Handle Individual Failures

```javascript theme={null}
const result = await client.sendBroadcastText(numbers, text);

// Check failed messages
const failedNumbers = result.results
  .filter(r => !r.success)
  .map(r => ({ phone: r.phoneNumber, error: r.error }));

if (failedNumbers.length > 0) {
  console.log('Failed messages:', failedNumbers);
  // Implement retry logic or alert system
}
```

### 3. Respect User Preferences

```javascript theme={null}
// Filter opt-out users before sending
const activeUsers = await getActiveSubscribers(); // Your DB logic
const phoneNumbers = activeUsers.map(u => u.phoneNumber);

await client.sendBroadcastText(phoneNumbers, message);
```

### 4. Optimize Batch Size

```javascript theme={null}
// For smaller lists (< 500), use larger batches
await client.sendBroadcastText(numbers, text, {
  batchSize: 100
});

// For very large lists (10k+), use default or smaller batches
await client.sendBroadcastText(numbers, text, {
  batchSize: 50  // More frequent progress updates
});
```

### 5. Monitor and Log

```javascript theme={null}
const result = await client.sendBroadcastText(numbers, text, {
  onProgress: (progress) => {
    // Log to your monitoring system
    logger.info('Broadcast progress', {
      broadcastId: result.broadcastId,
      progress: progress.percentage,
      failed: progress.failed
    });
  }
});

// Store results for analysis
await db.saveBroadcastResults(result);
```

## Examples

### Example 1: Simple Broadcast with Progress Tracking

```javascript theme={null}
async function sendAnnouncementBroadcast() {
  const phoneNumbers = [
    '+1234567890',
    '+0987654321',
    '+1122334455',
    // Add more recipients...
  ];

  const message = 'Hello! This is an important announcement for all our customers. 🎉';

  try {
    const result = await client.sendBroadcastText(phoneNumbers, message, {
      batchSize: 50,
      onProgress: (progress) => {
        console.log(`📊 Progress: ${progress.sent}/${progress.total} (${progress.percentage.toFixed(1)}%)`);
        console.log(`   ✅ Successful: ${progress.sent - progress.failed}`);
        console.log(`   ❌ Failed: ${progress.failed}`);
        if (progress.estimatedTimeRemaining) {
          console.log(`   ⏱️  ETA: ${Math.round(progress.estimatedTimeRemaining / 1000)}s\n`);
        }
      },
    });

    console.log('\n✅ Broadcast completed!');
    console.log(`   Total: ${result.total}`);
    console.log(`   Successful: ${result.successful}`);
    console.log(`   Failed: ${result.failed}`);
    console.log(`   Duration: ${(result.duration / 1000).toFixed(2)}s`);

    // Handle failed messages
    if (result.failed > 0) {
      const failedNumbers = result.results
        .filter(r => !r.success)
        .map(r => ({ phone: r.phoneNumber, error: r.error }));

      console.log('\n❌ Failed recipients:', failedNumbers);
      // Implement retry logic here
    }
  } catch (error) {
    console.error('❌ Broadcast failed:', error.message);
  }
}
```

### Example 2: Detailed Message Tracking

```javascript theme={null}
async function sendPromotionWithTracking() {
  const phoneNumbers = ['+1234567890', '+0987654321', '+1122334455'];
  const message = '🎁 Special offer! Use code WELCOME10 for 10% off.';

  const successfulRecipients = [];
  const failedRecipients = [];

  const result = await client.sendBroadcastText(phoneNumbers, message, {
    onMessageSent: (msgResult) => {
      if (msgResult.success) {
        successfulRecipients.push(msgResult.phoneNumber);
        console.log(`✅ Sent to ${msgResult.phoneNumber} (ID: ${msgResult.messageId})`);
      } else {
        failedRecipients.push(msgResult);
        console.log(`❌ Failed: ${msgResult.phoneNumber} - ${msgResult.error}`);
      }
    },
    onProgress: (progress) => {
      // Visual progress bar
      const bar = '█'.repeat(Math.floor(progress.percentage / 5)) +
                  '░'.repeat(20 - Math.floor(progress.percentage / 5));
      console.log(`[${bar}] ${progress.percentage.toFixed(1)}%`);
    },
  });

  console.log('\n📊 Final Report:');
  console.log(`   Broadcast ID: ${result.broadcastId}`);
  console.log(`   Success Rate: ${((result.successful / result.total) * 100).toFixed(1)}%`);
  console.log(`   Duration: ${(result.duration / 1000).toFixed(2)}s`);
}
```

### Example 3: Personalized Template Broadcast

```javascript theme={null}
async function sendOrderConfirmations() {
  // Each recipient with personalized data
  const recipients = [
    {
      phoneNumber: '+1234567890',
      variables: {
        name: 'John Doe',
        orderNumber: 'ORD-12345',
        deliveryDate: 'December 25, 2024',
      },
    },
    {
      phoneNumber: '+0987654321',
      variables: {
        name: 'Jane Smith',
        orderNumber: 'ORD-12346',
        deliveryDate: 'December 26, 2024',
      },
    },
  ];

  try {
    const result = await client.sendBulkTemplates(
      recipients,
      'order_confirmation', // Your pre-approved template name
      'en_US',
      {
        batchSize: 30,
        onProgress: (progress) => {
          console.log(`📤 Sending: ${progress.sent}/${progress.total}`);
        },
        onMessageSent: (msgResult) => {
          if (msgResult.success) {
            console.log(`✅ Template sent to ${msgResult.phoneNumber}`);
          } else {
            console.log(`❌ Failed: ${msgResult.phoneNumber} - ${msgResult.error}`);
          }
        },
      }
    );

    console.log('\n✅ Template broadcast completed!');
    console.log(`   Success: ${result.successful}/${result.total}`);
    console.log(`   Avg time per message: ${(result.duration / result.total).toFixed(0)}ms`);
  } catch (error) {
    console.error('❌ Template broadcast failed:', error.message);
  }
}
```

<Note>
  **Template Setup Required**: Before using template broadcasts, ensure your template is approved in WhatsApp Business Manager. Template approval can take 1-48 hours.
</Note>

## Limitations

<Warning>
  **Important Limitations**

  1. **24-Hour Window**: Text broadcasts require an active conversation window (user messaged you in last 24h). Use templates otherwise.

  2. **Template Approval**: Template messages must be pre-approved by Meta. This can take 1-48 hours.

  3. **Rate Limits**: While the SDK handles rate limiting, sending to 100k+ recipients will take considerable time (\~20+ minutes).

  4. **No Retry Logic**: Currently, failed messages are not automatically retried. Implement your own retry logic if needed.

  5. **Single Broadcast**: Only one broadcast can run at a time per client instance.
</Warning>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Messages failing with rate limit errors">
    **Solution**: The SDK should handle this automatically. If you're still seeing errors:

    * Reduce `batchSize` option
    * Increase `delayBetweenBatches`
    * Ensure you're not running multiple broadcasts simultaneously
  </Accordion>

  <Accordion title="All messages failing immediately">
    **Possible causes:**

    * Invalid access token or phone number ID
    * Messages sent to users outside 24-hour window (use templates)
    * Phone numbers incorrectly formatted
  </Accordion>

  <Accordion title="Broadcast slower than expected">
    **This is normal**: For 10,000 recipients at 80 msg/sec, expect \~2 minutes minimum. The SDK prioritizes delivery success over speed.
  </Accordion>
</AccordionGroup>

## Migration Guide

If you're upgrading from a previous version without broadcast support:

```javascript theme={null}
// OLD: Sending one by one
for (const phone of phoneNumbers) {
  await client.sendText(phone, message);
}

// NEW: Broadcast
await client.sendBroadcastText(phoneNumbers, message);
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Template Messages" icon="template" href="/messages/template">
    Learn about using pre-approved templates
  </Card>

  <Card title="Text Messages" icon="message" href="/messages/text">
    Learn about basic text messaging
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation" href="/guides/error-handling">
    Handle errors and implement retry logic
  </Card>

  <Card title="Message Overview" icon="grid" href="/messages/overview">
    Explore all available message types
  </Card>
</CardGroup>

## Version

<Note>
  Broadcast feature added in version **1.6.0**
</Note>
