Create campaign
Create, schedule, validate, or queue a bulk WhatsApp campaign.
Body parameters
| namerequired | string |
| business_id | string |
| channelrequired | string |
| channel_id | string |
| audiencerequired | object |
| template_id | string |
| template_variables | object |
| mode | string |
- A campaign dispatches real sends, so (on top of
campaigns:write) the key must be authorised to send on the campaign's channel: the umbrellamessages:send, or the channel's least-privilege send scope (whatsapp:send/sms:send/email:send). - Set test_mode: true to validate audience counts without queueing.
- Pass business_id when creating campaigns for one managed business.
- WhatsApp templates are attached to a specific WhatsApp number; pass channel_id to choose the sending number explicitly.
- Email campaigns require
subject(supports {{n}} variables) and may passdocument_sourceto attach a per-recipient PDF. - A WhatsApp statement run uses a template with a DOCUMENT header and
document_source:mode: "url_field"withfield_key(a contact custom field holding the https URL for each recipient),mode: "url"for one file to everyone, ormode: "library"for files uploaded in the dashboard (matched to contacts by phone or a custom field in the filename, kept 90 days).filename_template(for example "Statement {{first_name}}.pdf") is required for a DOCUMENT header. missing_policydecides a recipient with no document: "skip" sends to everyone else and marks that recipient failed with document_missing; "block" refuses a campaign sent now with 400 validation_failed and details.missing_count, and nothing is created.- A scheduled campaign is checked when it fires, not when you create it: the call answers 202 with status "scheduled". If a recipient then has no document under "block", the campaign is closed unsent and a campaign_blocked alert in the workspace names the missing count.
- Email campaigns may pass
block_content, a block-editor document ({ version: 1, blocks: [...] }with heading/text/button/image/divider/spacer/columns/hero/social/video/html blocks), instead ofbody; it compiles to branded HTML plus a plain-text part per recipient at send time. Pass eitherbodyorblock_content, not both. - An email
template_idthat references a block-designed template carries its design automatically; an inlineblock_contentoverrides it. - A starter template's example link (
https://example.com, with or without a path) or placeholder image (https://placehold.co/...) left inblock_content, or in the design atemplate_idcarries, is refused with 400 validation_failed anddetails.code: "placeholder_content". Replace them and send again. - Audience accepts
{ type: "all" },{ type: "list", list_id }or{ type: "segment", segment_id }. Pass a segment id to target a smart audience evaluated at send time. - To schedule, set
mode: "schedule"andscheduled_at(ISO 8601, at most 90 days ahead); the responsestatusis thenscheduled. Sends less than 30s out collapse back to immediate. - Optional fields:
description(internal label),preheader(email preview text, supports {{n}}),unique_entries(default true; dedupes recipients that match twice) andengagement_limit(cap the number of recipients).
curl -X POST "https://app.blueticked.com/api/v1/campaigns" \
-H "Authorization: Bearer $BLUETICKED_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: change-me-per-request-0001" \
-d '{
"name": "Launch announcement",
"business_id": "22222222-2222-4222-9222-222222222222",
"channel": "whatsapp",
"channel_id": "11111111-1111-4111-9111-111111111111",
"audience": {
"type": "list",
"list_id": "8f0d0b9a-0000-4000-9000-abcdef123456"
},
"template_id": "1f2f3f4f-0000-4000-9000-abcdef123456",
"template_variables": {
"1": {
"source": "first_name"
},
"2": {
"source": "custom",
"value": "Blueticked"
}
},
"mode": "now"
}'Response
{
"campaign_id": "8701a57c-11df-4a63-a950-0f22206d6bdf",
"status": "active_in_progress",
"message_count": 240,
"queued": true,
"request_id": "req_b2e3d610e10f1b07468721ee98f0e1d2"
}