Skip to content

Campaigns

Campaigns allow you to send bulk WhatsApp messages to multiple contacts using approved templates. The API handles rate limiting and delivery tracking automatically.

Retrieve all campaigns.

Terminal window
GET /api/campaigns
ParameterTypeDescription
pageintegerPage number (default: 1)
limitintegerItems per page (default: 20)
statusstringFilter by status (draft, scheduled, sending, paused, completed, cancelled)
whatsapp_accountstringFilter by WhatsApp account name
searchstringSearch campaign name (case-insensitive)
fromstringISO date string - filter campaigns created on or after this date
tostringISO date string - filter campaigns created on or before this date
{
"status": "success",
"data": {
"campaigns": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Holiday Promotion",
"whatsapp_account": "default_account",
"template_id": "880e8400-e29b-41d4-a716-446655440000",
"template_name": "holiday_offer",
"status": "completed",
"total_recipients": 1000,
"sent_count": 1000,
"delivered_count": 950,
"read_count": 500,
"failed_count": 50,
"scheduled_at": "2024-01-01T10:00:00Z",
"started_at": "2024-01-01T10:00:05Z",
"completed_at": "2024-01-01T10:30:00Z",
"created_at": "2024-01-01T09:00:00Z",
"updated_at": "2024-01-01T10:30:00Z"
}
],
"total": 25,
"page": 1,
"limit": 20
}
}

Retrieve a single campaign with detailed progress.

Terminal window
GET /api/campaigns/{id}
{
"status": "success",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Holiday Promotion",
"whatsapp_account": "default_account",
"template_id": "880e8400-e29b-41d4-a716-446655440000",
"template_name": "holiday_offer",
"status": "sending",
"total_recipients": 1000,
"sent_count": 450,
"delivered_count": 400,
"read_count": 100,
"failed_count": 10,
"scheduled_at": null,
"started_at": "2024-01-01T10:00:05Z",
"created_at": "2024-01-01T09:00:00Z",
"updated_at": "2024-01-01T10:00:00Z"
}
}

Create a new campaign.

Terminal window
POST /api/campaigns
FieldTypeRequiredDescription
namestringYesCampaign name
whatsapp_accountstringYesWhatsApp account name
template_idstringYesUUID of template to use
header_media_idstringNoAlready-uploaded WhatsApp media ID for header
scheduled_atstringNoOptional ISO date-time string to schedule campaign
{
"name": "New Year Sale",
"whatsapp_account": "default_account",
"template_id": "880e8400-e29b-41d4-a716-446655440000",
"scheduled_at": "2024-01-01T12:00:00Z"
}
{
"status": "success",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "New Year Sale",
"whatsapp_account": "default_account",
"template_id": "880e8400-e29b-41d4-a716-446655440000",
"status": "draft",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
}
}

Update a draft campaign.

Terminal window
PUT /api/campaigns/{id}

Same structure as Create Campaign. Only fields provided will be updated.

Delete a campaign.

Terminal window
DELETE /api/campaigns/{id}

Upload a media file (image, video, document, audio) to WhatsApp to use as the template’s media header for the campaign.

This endpoint accepts multipart/form-data.

Terminal window
POST /api/campaigns/{id}/media
FieldTypeRequiredDescription
filefile binaryYesThe header media file to upload
{
"status": "success",
"data": {
"media_id": "990e8400-e29b-41d4-a716-446655440000",
"filename": "banner.png",
"mime_type": "image/png",
"local_path": "/media/campaigns/550e8400-e29b-41d4-a716-446655440000.png",
"message": "Media uploaded successfully"
}
}

Import recipients for a campaign. You should supply parameters on a per-recipient basis here.

Terminal window
POST /api/campaigns/{id}/recipients/import
{
"recipients": [
{
"phone_number": "+1234567890",
"recipient_name": "John Doe",
"template_params": { "customer_name": "John", "coupon": "SAVE20" },
"header_params": { "season": "Summer" }
},
{
"phone_number": "+0987654321",
"recipient_name": "Jane Smith",
"template_params": { "customer_name": "Jane", "coupon": "SAVE15" },
"header_params": { "season": "Winter" }
}
]
}

header_params is only needed for templates with a TEXT header variable (Meta allows at most one). It’s kept separate from template_params so a positional header {{1}} doesn’t collide with body {{1}}. Omit the field entirely for templates without a header variable.

{
"status": "success",
"data": {
"imported": 2,
"duplicates": 0,
"invalid": 0
}
}

Get campaign recipients with their delivery status.

Terminal window
GET /api/campaigns/{id}/recipients
{
"status": "success",
"data": {
"recipients": [
{
"id": "770e8400-e29b-41d4-a716-446655440000",
"phone_number": "+1234567890",
"recipient_name": "John Doe",
"status": "delivered",
"sent_at": "2024-01-01T10:00:10Z",
"delivered_at": "2024-01-01T10:00:15Z"
}
],
"total": 1
}
}

Delete a single recipient from a campaign.

Terminal window
DELETE /api/campaigns/{id}/recipients/{recipientId}
{
"status": "success",
"data": {
"message": "Recipient deleted successfully"
}
}

Begin sending messages.

Terminal window
POST /api/campaigns/{id}/start

Pause a running campaign.

Terminal window
POST /api/campaigns/{id}/pause

Cancel a campaign (cannot be resumed).

Terminal window
POST /api/campaigns/{id}/cancel

Reset all failed recipients to pending and retry sending messages to them.

Terminal window
POST /api/campaigns/{id}/retry-failed
{
"status": "success",
"data": {
"message": "Retrying failed messages",
"retry_count": 5,
"status": "processing"
}
}
StatusDescription
draftCampaign created, not yet started
scheduledCampaign scheduled for future sending
sendingCampaign is actively sending messages
pausedCampaign is paused
completedAll messages have been processed
cancelledCampaign was cancelled
failedCampaign failed

Campaigns automatically respect WhatsApp’s rate limits:

TierMessages per second
TIER_1K~10 msg/sec
TIER_10K~30 msg/sec
TIER_100K~80 msg/sec
TIER_UNLIMITEDNo limit