Skip to main content
Add contacts to your broadcast before sending. Contacts can include personalization variables for customized messages.

Adding Contacts

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;
}

Recipient Formats

ChannelFormatExample
SMSE.164 phone+14155551234
WhatsAppE.164 phone+14155551234
EmailEmail addressuser@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": []
}

Handling Invalid Contacts

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.

Listing Contacts

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"
StatusDescription
pendingNot yet sent
queuedMessage created, waiting to send
sendingCurrently being sent
deliveredSuccessfully delivered
failedDelivery failed
skippedSkipped (broadcast cancelled)

Removing Contacts

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

LimitValueNotes
Contacts per request1,000Make multiple requests for larger lists
Contacts per broadcast1,000 (default)Contact support to increase this limit
Template variable size1,024 charsPer variable

Next Steps

Sending & Scheduling

Send your broadcast or schedule it for later