Send or schedule a campaign
Same review rules as POST /v1/broadcasts/{broadcastId}/send: a WhatsApp campaign on an approved template starts directly, email starts once automated review passes, other channels wait for a person. Omit scheduledAt to send now.
Authorization
AuthorizationheaderrequiredBearer YOUR_API_KEY. Create a key in the dashboard.
Path parameters
campaignIdstringrequiredCampaign ID. The same ID works as
broadcastIdon /v1.
Body
application/json · optional
scheduledAtstring<date-time>Schedule for future delivery. Omit to send immediately.
Responses
202Submitted for review, scheduled, or started.
campaignobjectrequiredA campaign. The same object as a /v1 broadcast: its
idworks on/v1/broadcasts/{broadcastId}.26 properties
idstringrequirednamestringrequiredstatusstringrequiredCurrent status of the campaign.
pending_review: in the automated content review.pending_admin_review: the automated review passed and it waits for a person, which is where every channel but a WhatsApp campaign on an approved template goes.rejected: the review refused it; edit it and send again, or escalate.scheduledandsendingfollow approval.One ofdraftpending_reviewpending_admin_reviewapprovedrejectedescalatedrejected_finalscheduledsendingpausedcompletedcancelledfailedchannelstringrequiredBroadcast delivery channel. Use 'smart' for per-contact intelligent routing.
One ofsmartsmssms_onewaywhatsapptelegramemailmessageTypestringrequiredType of message for broadcast.
One oftextimagevideoaudiodocumenttemplatetextstringcontentobjectContent for non-text broadcast message types.
8 properties
mediaUrlstringURL of the media file.
mediaIdstringMedia ID if already uploaded.
mimeTypestringMIME type of the media.
filenamestringFilename for documents.
templateIdstringTemplate ID for template messages.
templateVariablesobjectDefault body variables (can be overridden per contact). Key them to match the template body: by position (
1,2, ...) for positional templates, or by name (e.g.customer_name) for named templates. Zavu detects the template's format and sends the correct payload to Meta. Do not mix positional and named keys.1 properties
{key}string
templateButtonVariablesobjectDefault button variables for dynamic URL/OTP buttons. Keys are the button index (0, 1, 2). Per-contact values override these.
1 properties
{key}string
templateHeaderVariablesobjectDefault value for a text-header variable, keyed by
1(can be overridden per contact). If omitted, Zavu resolves the header fromtemplateVariablesby the header placeholder's name.1 properties
{key}string
emailSubjectstringtotalContactsintegerrequiredTotal number of contacts in the broadcast.
pendingCountintegersendingCountintegersentCountintegerRecipients whose message the provider accepted, without a confirmed delivery yet. Channels that never report delivery keep their recipients here.
deliveredCountintegerRecipients with confirmed delivery to the device.
failedCountintegerestimatedCostnumberEstimated total cost in USD.
reservedAmountnumberAmount reserved from balance in USD.
actualCostnumberActual cost so far in USD.
scheduledAtstring<date-time>startedAtstring<date-time>completedAtstring<date-time>metadataobject1 properties
{key}string
createdAtstring<date-time>requiredupdatedAtstring<date-time>reviewResultobjectAI content review result.
5 properties
scorenumberContent safety score from 0.0 to 1.0, where 1.0 is completely safe.
categoriesstring[]Policy categories violated, if any.
reasoningstringExplanation of the review decision.
reviewedAtstring<date-time>flaggedContentstring[]Problematic text fragments, if any.
reviewAttemptsintegerNumber of review attempts (max 3).
fromstringThe address the campaign is sent from, for its
channel(the sender's first address whenchannelissmart).
400No recipients, invalid status, `template_not_approved`, or `sender_not_found` when the campaign's sender was deleted after it was created.
codestringrequiredmessagestringrequireddetailsobjectMachine-readable context. Keys that mean the same thing everywhere: -
errors: present on every400 invalid_requestfor an invalid body or query parameter,[{path, message, ...}],pathnaming the field (["to"],["contacts", 2, "recipient"],["limit"]). -recommendation: one sentence saying what to do next. -dashboardUrl: the dashboard screen that fixes it. -connect: on409 no_channel, the channels this project can connect to reach the recipient, each{type, request, note, available, dashboardUrl?};requestis the exact call (POST /v2/channelswith its body, orPOST /v2/numbers), or null for a channel connected from the dashboard (WhatsApp, Instagram, Messenger).available: falsesays why innote(one-way SMS closed until business verification is approved). -address/from: the address the error is about, under the name the request used for it.1 properties
errorsobject[]3 properties
pathobject[]requiredmessagestringrequiredcodestring
401Unauthorized.
codestringrequiredmessagestringrequireddetailsobjectMachine-readable context. Keys that mean the same thing everywhere: -
errors: present on every400 invalid_requestfor an invalid body or query parameter,[{path, message, ...}],pathnaming the field (["to"],["contacts", 2, "recipient"],["limit"]). -recommendation: one sentence saying what to do next. -dashboardUrl: the dashboard screen that fixes it. -connect: on409 no_channel, the channels this project can connect to reach the recipient, each{type, request, note, available, dashboardUrl?};requestis the exact call (POST /v2/channelswith its body, orPOST /v2/numbers), or null for a channel connected from the dashboard (WhatsApp, Instagram, Messenger).available: falsesays why innote(one-way SMS closed until business verification is approved). -address/from: the address the error is about, under the name the request used for it.1 properties
errorsobject[]3 properties
pathobject[]requiredmessagestringrequiredcodestring
402`insufficient_balance`, with `details.availableBalance`; or `paid_plan_required`: an email campaign on the Free plan (`details.dashboardUrl`). Email campaigns need a paid plan; drafts can still be created and edited.
codestringrequiredmessagestringrequireddetailsobjectMachine-readable context. Keys that mean the same thing everywhere: -
errors: present on every400 invalid_requestfor an invalid body or query parameter,[{path, message, ...}],pathnaming the field (["to"],["contacts", 2, "recipient"],["limit"]). -recommendation: one sentence saying what to do next. -dashboardUrl: the dashboard screen that fixes it. -connect: on409 no_channel, the channels this project can connect to reach the recipient, each{type, request, note, available, dashboardUrl?};requestis the exact call (POST /v2/channelswith its body, orPOST /v2/numbers), or null for a channel connected from the dashboard (WhatsApp, Instagram, Messenger).available: falsesays why innote(one-way SMS closed until business verification is approved). -address/from: the address the error is about, under the name the request used for it.1 properties
errorsobject[]3 properties
pathobject[]requiredmessagestringrequiredcodestring
404Campaign not found, or it belongs to another project.
codestringrequiredmessagestringrequireddetailsobjectMachine-readable context. Keys that mean the same thing everywhere: -
errors: present on every400 invalid_requestfor an invalid body or query parameter,[{path, message, ...}],pathnaming the field (["to"],["contacts", 2, "recipient"],["limit"]). -recommendation: one sentence saying what to do next. -dashboardUrl: the dashboard screen that fixes it. -connect: on409 no_channel, the channels this project can connect to reach the recipient, each{type, request, note, available, dashboardUrl?};requestis the exact call (POST /v2/channelswith its body, orPOST /v2/numbers), or null for a channel connected from the dashboard (WhatsApp, Instagram, Messenger).available: falsesays why innote(one-way SMS closed until business verification is approved). -address/from: the address the error is about, under the name the request used for it.1 properties
errorsobject[]3 properties
pathobject[]requiredmessagestringrequiredcodestring