BULK MESSAGING

Bulk SMS & WhatsApp

Send messages to thousands of recipients over SMS or WhatsApp. Bulk jobs are processed asynchronously with status tracking. Both channels support scheduled delivery via scheduled_at (ISO 8601). Jobs with more than 5 recipients are automatically queued via Celery.

Create Bulk SMS Job

Submit a bulk SMS job. Messages are queued and processed in the background. Jobs with >5 recipients are automatically handed to Celery for async delivery.

POST /admin/api/bulk-jobs
ParameterTypeRequiredDescription
recipientsstring[]RequiredPhone numbers in E.164 format
messagestringRequiredMessage content to send
sender_idstringOptionalAlphanumeric sender ID for the message
scheduled_atstringOptionalISO 8601 datetime for delayed delivery
Create a bulk SMS job
curl -X POST "https://api.yourdomain.com/admin/api/bulk-jobs" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "recipients": [
      "+265888123456",
      "+265999654321",
      "+265777888999",
      "+265888111222"
    ],
    "message": "Important: Your appointment is tomorrow at 10am.",
    "sender_id": "HealthClinic"
  }'
200 OK
{
  "status": "queued",
  "total_scheduled": 4,
  "scheduled_at": null
}
Scheduled bulk SMS
curl -X POST "https://api.yourdomain.com/admin/api/bulk-jobs" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "recipients": [
      "+265888123456",
      "+265999654321"
    ],
    "message": "Flash sale starts tomorrow!",
    "sender_id": "MyBrand",
    "scheduled_at": "2026-01-15T08:00:00Z"
  }'
200 OK (scheduled)
{
  "status": "scheduled",
  "total_scheduled": 2,
  "scheduled_at": "2026-01-15T08:00:00Z"
}

Create Bulk WhatsApp Job

Send bulk messages (or media) over WhatsApp. Supports text-only, media with caption, and scheduled delivery. Jobs with >5 recipients are automatically handed to Celery for async delivery.

POST /admin/api/whatsapp/bulk
ParameterTypeRequiredDescription
recipientsstring[]RequiredPhone numbers in E.164 format
messagestringOptionalText message content (required if no media)
media_urlstringOptionalURL of image, video, audio, or document
media_typestringOptionalMIME type of the media (e.g. image/png)
captionstringOptionalCaption text for the media message
file_namestringOptionalFilename shown when sharing a document
scheduled_atstringOptionalISO 8601 datetime for delayed delivery
Send text bulk
curl -X POST "https://api.yourdomain.com/admin/api/whatsapp/bulk" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "recipients": [
      "+265888123456",
      "+265999654321",
      "+265777888999"
    ],
    "message": "Your verification code is 4829."
  }'
200 OK
{
  "status": "queued",
  "total_scheduled": 3,
  "scheduled_at": null
}
Send media bulk
curl -X POST "https://api.yourdomain.com/admin/api/whatsapp/bulk" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "recipients": [
      "+265888123456",
      "+265999654321"
    ],
    "media_url": "https://cdn.example.com/promo.png",
    "media_type": "image/png",
    "caption": "Check out our latest offers!"
  }'
200 OK (media)
{
  "status": "queued",
  "total_scheduled": 2,
  "scheduled_at": null
}
Scheduled bulk
curl -X POST "https://api.yourdomain.com/admin/api/whatsapp/bulk" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "recipients": [
      "+265888123456",
      "+265999654321"
    ],
    "message": "Happy New Year! Wishing you all the best.",
    "scheduled_at": "2026-01-01T06:00:00Z"
  }'
200 OK (scheduled)
{
  "status": "scheduled",
  "total_scheduled": 2,
  "scheduled_at": "2026-01-01T06:00:00Z"
}

Check Bulk Job Status

Poll the status endpoint to track progress of a bulk job (works for both SMS and WhatsApp jobs).

GET /admin/api/bulk-jobs/{job_id}
200 OK
{
  "job_id": "bulk_job_abc123",
  "status": "processing",
  "total": 4,
  "sent": 3,
  "failed": 0,
  "pending": 1,
  "progress_percent": 75
}

Best Practices

Async via Celery

Jobs with more than 5 recipients are automatically queued in Celery. You receive a job_id immediately and can poll for status.

Scheduling

Use scheduled_at (ISO 8601) to delay delivery. Both SMS and WhatsApp bulk jobs support future scheduling.

Media Messages

For WhatsApp, ensure media_url points to a publicly accessible URL. Supported types: images, videos, audio, and documents.

Rate Limiting

Bulk jobs respect your account rate limits. Check rate limit headers in responses.

Sender IDs

SMS sender_id must be registered and approved before use in bulk jobs.