Docs
Campaigns
Broadcast an approved template to an audience — now, later or on a schedule — with live stats.
GET
/v1/campaignsPOST
/v1/campaignsPOST
/v1/campaigns/estimate— Recipients, exclusions and costPOST
/v1/campaigns/{id}/launchPOST
/v1/campaigns/{id}/pausePOST
/v1/campaigns/{id}/resumePOST
/v1/campaigns/{id}/cancelGET
/v1/campaigns/{id}/reportCreate a campaign
Parameters
namestringrequiredInternal name.phone_number_iduuidrequiredSending number.template_iduuidrequiredAn APPROVED template.audienceobjectrequiredlists,segments,tags,contact_ids(union) minusexclude_tags.variablesobjectoptionalMaps each template parameter to a static value or a contact field, with fallback.schedule_typeenumrequirednow·at·recurringscheduled_atdatetimeoptionalRequired whenschedule_typeisat.recurrenceobjectoptionale.g.{ "frequency": "weekly", "by_weekday": [1], "time": "10:00" }timezonestringrequiredIANA timezone, e.g.Asia/Kolkata.throttle_per_minintegeroptionalMax messages per minute.send_windowobjectoptionale.g.{ "start": "09:00", "end": "21:00" }; sending pauses outside it.
POST /v1/campaigns
{
"name": "Festive sale — VIPs",
"phone_number_id": "1c2d…",
"template_id": "3c7d…",
"audience": { "lists": [], "segments": ["5e6f…"], "tags": ["7f…"], "contact_ids": [], "exclude_tags": ["9a…"] },
"variables": {
"body.1": { "source": "name", "fallback": "there" },
"body.2": { "source": "attribute", "key": "city", "fallback": "your city" },
"button.0": { "source": "static", "value": "FESTIVE30" }
},
"schedule_type": "at",
"scheduled_at": "2026-11-14T04:30:00Z",
"timezone": "Asia/Kolkata",
"throttle_per_min": 2000,
"send_window": { "start": "09:00", "end": "21:00" }
}Variable sources: static (uses value), name, phone, or attribute (uses key). fallback is used when the contact field is empty.
Estimate before launch
POST /v1/campaigns/estimate → 200
{
"recipients": 48210,
"excluded": { "opted_out": 1204, "blocked": 37, "no_address": 12 },
"estimated_cost": { "currency": "INR", "amount": 37845.5 },
"messaging_limit": "TIER_100K"
}Messaging limits
WhatsApp limits how many unique people a business portfolio can message in a rolling 24 hours. Campaigns larger than your limit are paced automatically across days.
Lifecycle
Report
GET /v1/campaigns/{id}/report
{
"stats": { "total": 48210, "queued": 0, "sent": 48210, "delivered": 46480,
"read": 34612, "failed": 1730, "replied": 2210, "skipped": 0 },
"errors": [
{ "code": 131049, "title": "Per-user marketing limit reached", "count": 1288 },
{ "code": 131026, "title": "Message undeliverable", "count": 442 }
]
}Subscribe to campaign.progress and campaign.completed webhooks for push updates.