Activate a campaign
Moves a draft or paused campaign to active and starts outreach. This contacts real
people. No request body.
What happens depends on the channel:
voice: everypendingcontact is queued for the dialer. The dialer calls only inside the campaignschedule(hours in its timezone,startHourinclusive,endHourexclusive), at mostmax_concurrent_callsat once (and never above the plan’s ceiling). Before each call it checks the workspace’s consent policy and compliance rules. Unanswered, busy or unconnected calls are redialed afterretry_interval_minutesuntil the contact has hadmax_retry_attemptsdials. If the workspace has no phone number, or the agent is paused, the system pauses the campaign and fillsblocked_reason.whatsappwithwhatsapp_template_id: one approved-template message perpendingcontact is queued. Placeholders are filled per contact, and a missingwhatsapp_numberis copied from an E.164phone_number. Sending is paced, and opted-out/dnccontacts are skipped.emailwith bothemail_subjectandemail_body: one email perpendingcontact with anemail, rendered per contact and sent from the workspace’s own mailbox, paced and filtered by opt-outs and daily caps.- Anything else (
webchat, WhatsApp without a template, email without content): the campaign is inbound-only; activation only arms the agent to answer whoever writes.
Contacts a WhatsApp or email run cannot reach (no address, a placeholder that does not resolve
and has no fallback) are marked invalid and counted in the in-app notification. If that leaves
no work at all, the campaign can complete within seconds, even though this response still shows
active.
Refused before anything is queued when:
- the status is not
draft/paused(400); - a voice campaign has no
pendingcontacts, or a non-voice campaign has no contacts (400); - the agent no longer serves the channel (400);
- the WhatsApp template is missing or not approved by WhatsApp, its placeholders are not all covered, or the business WhatsApp sender is offline (400);
- the email subject/body is half-filled or the mailbox has a sending issue (400), or no own mailbox is selected (409);
- pending contacts exceed the plan’s contact limit (400), or the plan’s active-campaign cap is full (403). This is where the cap is enforced: drafts can be created beyond it.
Side effects. Places outbound calls through the telephony carrier and the voice engine (billed as voice minutes) or sends WhatsApp/email messages (billed as messages), enqueues background jobs, sends an in-app notification and writes an audit entry.
Idempotency. Safe to retry: activating a campaign that is already active returns it with
200 and queues nothing again. That also means contacts added after activation are not queued.
To reach them, pause and activate again: only pending contacts are queued, so nobody already
called or messaged is contacted twice. Two concurrent activations of the same campaign resolve to
one winner; the other gets 409.
Webhook events. Emits campaign.started ({ campaign_id, campaign_name, agent_id, channel, previous_status, status }) the first time the campaign becomes active, or campaign.resumed
(same fields, previous_status: paused) when it was paused. Voice calls emit call.completed /
call.failed; the campaign emits campaign.completed ({ campaign_id, campaign_name }) when it
finishes; plus audit.log_recorded.
See Webhooks.
Access
- Required scope:
full. Admin-only route:read/writekeys get 403; signed-in users need the admin or owner role. - Rate limit: Configuration mutations — 10 requests/min per workspace, shared with agent mutations, on top of the general API limit (120 to 600 requests/min by plan). See Rate limits.
- Plan: Active-campaign cap: Starter 1, Growth 3, Business and Enterprise unlimited (the system
manualcampaign does not count). Pending contacts must not exceed the plan’s contact limit (Starter 500, Growth 2,000, Business 20,000).
Authentication
Workspace API key: jl_ followed by 64 lowercase hex characters, created by the workspace owner in the
dashboard (Settings → API Keys) and sent as Authorization: Bearer jl_.... The plaintext is shown once,
at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys.
Operations restricted to admins or owners reject keys without the full scope with 403, and say so in
their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret —
that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds.
See Authentication.
Path parameters
UUID of the campaign to activate. An unknown, deleted or foreign campaign answers 404; a value that is not a UUID answers 400.
Response
The campaign is active (or already was).
A campaign row as returned by the retrieve, create, update, activate and pause endpoints.
Keys are snake_case, exactly as stored. The list endpoint returns a lighter
CampaignListItem instead.
Removed from responses (2026-09-15). retry_policy, voicemail_action and voicemail_message
were legacy columns nothing read; none of them was ever settable through this API and none is
returned any more. Redials come from max_retry_attempts and retry_interval_minutes; voicemail
detection is an agent setting (enableVoicemailDetection).

