Bulk Messaging Guide

Learn how to send bulk messages to multiple recipients using the Zend.

Bulk SMS Messages

Send the same message to multiple recipients:

POST /messages/bulk
{
  "messages": [
    {"to": "+233593152134", "body": "Welcome to our service!"},
    {"to": "+233593152135", "body": "Welcome to our service!"},
    {"to": "+233593152136", "body": "Welcome to our service!"}
  ],
  "preferred_channels": ["sms"],
  "fallback_enabled": true
}

Response:

{
  "id": "bulk_1705312345678",
  "status": "pending",
  "recipients": 3,
  "estimated_cost": 0.06,
  "message": "3 messages queued for processing"
}

Bulk WhatsApp with Templates

Send template messages to multiple recipients:

{
  "messages": [
    {
      "to": "+233593152134",
      "template_params": {
        "code": "123456",
        "verification_url": "https://yourapp.com/verify?code=123456"
      }
    },
    {
      "to": "+233593152135",
      "template_params": {
        "code": "789012",
        "verification_url": "https://yourapp.com/verify?code=789012"
      }
    }
  ],
  "template_id": "6884c5d09c14b2b164500d58",
  "preferred_channels": ["whatsapp"]
}

Bulk with Individual Customization

Send personalized messages to each recipient:

{
  "messages": [
    {
      "to": "+233593152134",
      "body": "Hi John, your order #12345 has been shipped!",
      "template_params": {
        "customer_name": "John",
        "order_number": "12345",
        "tracking_url": "https://track.com/12345"
      }
    },
    {
      "to": "+233593152135",
      "body": "Hi Sarah, your order #12346 has been shipped!",
      "template_params": {
        "customer_name": "Sarah",
        "order_number": "12346",
        "tracking_url": "https://track.com/12346"
      }
    }
  ],
  "template_id": "12345678912345",
  "preferred_channels": ["whatsapp", "sms"]
}

Bulk with Mixed Channels

Send to different channels based on recipient preferences:

{
  "messages": [
    {
      "to": "+233593152134",
      "body": "Your appointment reminder",
      "template_params": {
        "appointment_time": "2:00 PM",
        "location": "Main Office"
      },
      "preferred_channels": ["whatsapp"]
    },
    {
      "to": "+233593152135",
      "body": "Your appointment reminder",
      "template_params": {
        "appointment_time": "3:00 PM",
        "location": "Branch Office"
      },
      "preferred_channels": ["sms"]
    }
  ],
  "template_id": "12345678912345",
  "fallback_enabled": true
}

Bulk with Scheduling

Schedule bulk messages for future delivery:

{
  "messages": [
    {"to": "+233593152134", "body": "Happy Birthday! 🎉"},
    {"to": "+233593152135", "body": "Happy Birthday! 🎉"},
    {"to": "+233593152136", "body": "Happy Birthday! 🎉"}
  ],
  "preferred_channels": ["whatsapp", "sms"],
  "scheduled_for": "2024-01-15T09:00:00Z"
}

Bulk with Webhooks

Receive delivery status updates for all messages:

{
  "messages": [
    {"to": "+233593152134", "body": "System maintenance notification"},
    {"to": "+233593152135", "body": "System maintenance notification"},
    {"to": "+233593152136", "body": "System maintenance notification"}
  ],
  "preferred_channels": ["sms"],
  "webhook_url": "https://yourapp.com/webhooks/bulk-status"
}

Bulk Message Limits

  • Maximum Recipients: 10,000 per request
  • Rate Limit: 1,000 messages per hour
  • Processing Time: 5-10 minutes for large batches
  • Cost: Varies by channel and message type

Bulk Message Status Tracking

Check Bulk Status

GET /messages?bulk_id={bulk_id}

Response:

{
  "id": "bulk_1705312345678",
  "status": "processing",
  "total_recipients": 1000,
  "sent": 750,
  "delivered": 720,
  "failed": 30,
  "pending": 250,
  "total_cost": 15.20,
  "created_at": "2024-01-15T10:00:00Z",
  "estimated_completion": "2024-01-15T10:15:00Z"
}

Get Individual Message Statuses

GET /messages?bulk_id=bulk_1705312345678&limit=50&offset=0

Response:

{
  "messages": [
    {
      "id": "6884da240f0e633b7b979bff",
      "status": "delivered",
      "channel_used": "whatsapp",
      "to": "+233593152134",
      "total_cost": 0.008,
      "created_at": "2024-01-15T10:00:05Z"
    }
  ],
  "total": 1000,
  "page": 1,
  "pages": 20
}

Bulk Message Best Practices

1. Batch Size Optimization

// Optimal batch sizes
const optimalBatchSizes = {
  sms: 1000,      // SMS: 1000 per batch
  whatsapp: 500,  // WhatsApp: 500 per batch
  mixed: 750      // Mixed channels: 750 per batch
};

2. Rate Limiting

// Implement rate limiting for large batches
const sendBulkWithRateLimit = async (messages, batchSize = 500) => {
  const batches = [];
  for (let i = 0; i < messages.length; i += batchSize) {
    batches.push(messages.slice(i, i + batchSize));
  }
  
  for (const batch of batches) {
    await sendBulkMessage(batch);
    // Wait 1 minute between batches
    await new Promise(resolve => setTimeout(resolve, 60000));
  }
};

3. Error Handling

try {
  const response = await fetch('/messages/bulk', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      messages: recipientList,
      preferred_channels: ['whatsapp', 'sms'],
      fallback_enabled: true
    })
  });
  
  if (!response.ok) {
    const error = await response.json();
    console.error('Bulk send failed:', error.message);
  } else {
    const result = await response.json();
    console.log(`Bulk message queued: ${result.recipients} recipients`);
  }
} catch (error) {
  console.error('Network error:', error);
}

4. Progress Monitoring

const monitorBulkProgress = async (bulkId) => {
  const checkStatus = async () => {
    const response = await fetch(`/messages?bulk_id=${bulkId}`);
    const status = await response.json();
    
    console.log(`Progress: ${status.sent}/${status.total_recipients} sent`);
    
    if (status.status === 'completed') {
      console.log('Bulk send completed!');
      return;
    }
    
    // Check again in 30 seconds
    setTimeout(checkStatus, 30000);
  };
  
  checkStatus();
};

Bulk Message Templates

Marketing Campaign Template

{
  "name": "marketing_campaign",
  "description": "Marketing campaign with personalized offers",
  "category": "marketing",
  "variables": [
    {"name": "customer_name", "type": "text", "required": true},
    {"name": "offer_code", "type": "text", "required": true},
    {"name": "expiry_date", "type": "text", "required": true},
    {"name": "shop_url", "type": "url", "required": true}
  ],
  "channel_variants": [
    {
      "channel": "sms",
      "content": "Hi {{customer_name}}! Special offer: {{offer_code}} valid until {{expiry_date}}. Shop now: {{shop_url}}"
    },
    {
      "channel": "whatsapp",
      "content": "Hi {{customer_name}}! 🎉\n\nWe have a special offer just for you!\n\nUse code: {{offer_code}}\nValid until: {{expiry_date}}\n\nDon't miss out!",
      "header": "Special Offer",
      "footer": "Limited time only",
      "buttons": [
        {
          "type": "url",
          "text": "Shop Now",
          "variable_name": "shop_url"
        }
      ]
    }
  ]
}

Using Bulk Marketing Template

{
  "messages": [
    {
      "to": "+233593152134",
      "template_params": {
        "customer_name": "John",
        "offer_code": "SAVE20",
        "expiry_date": "Jan 31, 2024",
        "shop_url": "https://shop.com/SAVE20"
      }
    },
    {
      "to": "+233593152135",
      "template_params": {
        "customer_name": "Sarah",
        "offer_code": "SAVE25",
        "expiry_date": "Jan 31, 2024",
        "shop_url": "https://shop.com/SAVE25"
      }
    }
  ],
  "template_id": "12345678912345",
  "preferred_channels": ["whatsapp", "sms"]
}

Bulk Message Errors

Insufficient Credits

{
  "statusCode": 400,
  "message": "Insufficient credits for bulk send. Required: 20.000, Available: 15.500. Please purchase more credits.",
  "error": "Bad Request"
}

Invalid Recipients

{
  "statusCode": 400,
  "message": "Invalid phone numbers found: +233INVALID, +233INVALID2. Please fix and retry.",
  "error": "Bad Request"
}

Template Errors

{
  "statusCode": 400,
  "message": "Template 'welcome_template' not found or not accessible",
  "error": "Bad Request"
}

Bulk Message Analytics

Get Bulk Statistics

GET /analytics/overview

Response:

{
  "bulk_id": "bulk_1705312345678",
  "total_recipients": 1000,
  "delivery_stats": {
    "sent": 950,
    "delivered": 920,
    "failed": 30,
    "pending": 50
  },
  "channel_stats": {
    "whatsapp": {
      "sent": 600,
      "delivered": 580,
      "failed": 20
    },
    "sms": {
      "sent": 350,
      "delivered": 340,
      "failed": 10
    }
  },
  "cost_breakdown": {
    "whatsapp": 4.64,
    "sms": 6.80,
    "total": 11.44
  },
  "delivery_times": {
    "average": 45,
    "median": 32,
    "p95": 120
  }
}