Skip to content

Create a WhatsApp campaign

post/whatsapp-campaigns
Any key

Creates a campaign that sends one approved template to an audience from the chatbot's official WhatsApp integration, and starts it now or at schedule.at.

The audience is either a lead filter (the same filters as the dashboard builder) or a list of phone numbers. When the campaign starts, the audience is resolved once into one message per phone number. Numbers are excluded when they are invalid, blocked, opted out of marketing (marketing templates), US numbers on a marketing template, already sent a marketing template by this chatbot in the last 24 hours, or missing a variable value with no fallback.

mapping gives each slot of the template (named as in /whatsapp-templates, e.g. body[1], buttons[0][1]) a source: a lead field (name, first_name, email, phone), a custom lead attribute, or fixed text, with an optional fallback used when the lead's value is empty.

With replyMode: live_chat, a recipient's reply is handed to a human agent in Live chats instead of the AI (requires the live chat plan feature).

Request body

Sending 4 of 10 fields
Required
chatbotIdstring
namestring
templateobject
namestring
audienceobject
Two-letter country for phone numbers without a country code.

Only these fields are sent (application/json).

Try it · POST /whatsapp-campaigns
curl 'https://api.chat-data.com/api/v2/whatsapp-campaigns' \  -H "Authorization: Bearer $CHAT_DATA_API_KEY" \  -H 'Content-Type: application/json' \  -d '{  "chatbotId": "6650f1c2a9e4b83d2c7a1f05",  "name": "November restock",  "template": {    "name": "Jane Doe"  },  "audience": {}}'
Loading…

Responses

The campaign, scheduled until it starts.

Content type: application/json

FieldDescription
statusstringOne of: success.
campaignobject
campaign.idstring
campaign.namestring
campaign.phoneNumberIdstring
campaign.templateobject
campaign.template.namestring
campaign.template.languagestring
campaign.template.categorystring
campaign.replyModestringOne of: ai, live_chat.
campaign.statusstringOne of: draft, scheduled, sending, paused, completed, cancelled, failed.
campaign.pauseReasonstring
campaign.scheduleobject
campaign.schedule.atstring
campaign.schedule.timeZonestring
campaign.recipientsintegerRecipients after exclusions, set when the campaign starts.
campaign.exclusionsobjectExcluded numbers by reason.
campaign.statsobjectsent, delivered, read and replied count every message that reached that stage (a read message was also delivered).
campaign.stats.queuedinteger
campaign.stats.sentinteger
campaign.stats.deliveredinteger
campaign.stats.readinteger
campaign.stats.repliedinteger
campaign.stats.formCompletedinteger
campaign.stats.failedinteger
campaign.stats.cancelledinteger
campaign.startedAtstring
campaign.completedAtstring
campaign.createdAtstring

Example

{  "status": "success",  "campaign": {    "id": "6650f1c2a9e4b83d2c7a1f3c",    "name": "Jane Doe",    "phoneNumberId": "6650f1c2a9e4b83d2c7a1f3c",    "template": {      "name": "Jane Doe",      "language": "sample language",      "category": "sample category"    },    "replyMode": "ai",    "status": "draft",    "pauseReason": "sample pause reason",    "schedule": {      "at": "2026-10-14T09:30:00.000Z",      "timeZone": "sample time zone"    },    "recipients": 10,    "exclusions": {      "opted_out": 3,      "us_marketing": 12    },    "stats": {      "queued": 10,      "sent": 10,      "delivered": 10,      "read": 10,      "replied": 10,      "formCompleted": 10,      "failed": 10,      "cancelled": 10    },    "startedAt": "2026-10-14T09:30:00.000Z",    "completedAt": "2026-10-14T09:30:00.000Z",    "createdAt": "2026-10-14T09:30:00.000Z"  }}

Last updated October 14, 2026