Add contacts to your broadcast before sending. Contacts can include personalization variables for customized messages.
const result = await zavu.broadcasts.addContacts(broadcast.id, {
contacts: [
{ recipient: "+14155551234" },
{ recipient: "+14155555678" },
{ recipient: "+14155559012" },
],
});
console.log(`Added: ${result.added}`);
console.log(`Duplicates: ${result.duplicates}`);
console.log(`Invalid: ${result.invalid}`);
Response
{
"added": 3,
"duplicates": 0,
"invalid": 0,
"errors": []
}
With Personalization
Add template variables for each contact to personalize messages:
await zavu.broadcasts.addContacts(broadcast.id, {
contacts: [
{
recipient: "+14155551234",
templateVariables: {
name: "John Smith",
order_id: "ORD-12345",
delivery_date: "January 20th",
},
},
{
recipient: "+14155555678",
templateVariables: {
name: "Jane Doe",
order_id: "ORD-12346",
delivery_date: "January 21st",
},
},
],
});
The message template Hi {{name}}, your order #{{order_id}} arrives {{delivery_date}}! becomes:
- John: “Hi John Smith, your order #ORD-12345 arrives January 20th!”
- Jane: “Hi Jane Doe, your order #ORD-12346 arrives January 21st!”
Batch Processing
Add contacts in batches of up to 1,000 per request. For larger lists, make multiple requests:
const BATCH_SIZE = 1000;
async function addAllContacts(broadcastId: string, allContacts: Contact[]) {
let totalAdded = 0;
for (let i = 0; i < allContacts.length; i += BATCH_SIZE) {
const batch = allContacts.slice(i, i + BATCH_SIZE);
const result = await zavu.broadcasts.addContacts(broadcastId, {
contacts: batch.map(c => ({
recipient: c.phone,
templateVariables: { name: c.name },
})),
});
totalAdded += result.added;
console.log(`Batch ${Math.floor(i / BATCH_SIZE) + 1}: Added ${result.added} contacts`);
}
return totalAdded;
}
| Channel | Format | Example |
|---|
| SMS | E.164 phone | +14155551234 |
| WhatsApp | E.164 phone | +14155551234 |
| Email | Email address | user@example.com |
Phone numbers must be in E.164 format (starting with + and country code). Invalid formats will be rejected.
Handling Duplicates
The API automatically deduplicates contacts:
- Within request: If the same recipient appears twice in one request, only one is added
- Across requests: If a recipient is already in the broadcast, they won’t be added again
{
"added": 8,
"duplicates": 2,
"invalid": 0,
"errors": []
}
Invalid contacts are rejected with detailed errors:
{
"added": 7,
"duplicates": 0,
"invalid": 3,
"errors": [
{ "recipient": "invalid-phone", "reason": "Invalid phone number format" },
{ "recipient": "+1234", "reason": "Phone number too short" },
{ "recipient": "not-an-email", "reason": "Invalid email format" }
]
}
Validate phone numbers before adding them to avoid high rejection rates. Use E.164 format: +[country code][number] with no spaces or dashes.
View contacts in a broadcast:
const contacts = await zavu.broadcasts.listContacts(broadcast.id, {
limit: 50,
});
for (const contact of contacts.items) {
console.log(`${contact.recipient}: ${contact.status}`);
}
// Paginate through all contacts
if (contacts.nextCursor) {
const nextPage = await zavu.broadcasts.listContacts(broadcast.id, {
cursor: contacts.nextCursor,
});
}
Response
{
"items": [
{
"id": "bc_abc123",
"recipient": "+14155551234",
"recipientType": "phone",
"status": "pending",
"templateVariables": { "name": "John" },
"createdAt": "2024-01-15T10:30:00.000Z"
},
{
"id": "bc_def456",
"recipient": "+14155555678",
"recipientType": "phone",
"status": "pending",
"templateVariables": { "name": "Jane" },
"createdAt": "2024-01-15T10:30:00.000Z"
}
],
"nextCursor": "eyJpZCI6ImJjX2RlZjQ1NiJ9"
}
Filtering by Status
Filter contacts by delivery status:
curl "https://api.zavu.dev/v1/broadcasts/{broadcastId}/contacts?status=failed" \
-H "Authorization: Bearer $ZAVU_API_KEY"
| Status | Description |
|---|
pending | Not yet sent |
queued | Message created, waiting to send |
sending | Currently being sent |
delivered | Successfully delivered |
failed | Delivery failed |
skipped | Skipped (broadcast cancelled) |
Remove a contact before the broadcast is sent:
await zavu.broadcasts.removeContact(broadcast.id, contact.id);
Contacts can only be removed while the broadcast is in draft status. Once sending begins, contacts cannot be removed.
Limits
| Limit | Value | Notes |
|---|
| Contacts per request | 1,000 | Make multiple requests for larger lists |
| Contacts per broadcast | 1,000 (default) | Contact support to increase this limit |
| Template variable size | 1,024 chars | Per variable |
Next Steps
Sending & Scheduling
Send your broadcast or schedule it for later