Activate a campaign

View as Markdown
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`:** every `pending` contact is queued for the dialer. The dialer calls only inside the campaign `schedule` (hours in its timezone, `startHour` inclusive, `endHour` exclusive), at most `max_concurrent_calls` at 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 after `retry_interval_minutes` until the contact has had `max_retry_attempts` dials. If the workspace has no phone number, or the agent is paused, the system pauses the campaign and fills `blocked_reason`. - **`whatsapp` with `whatsapp_template_id`:** one approved-template message per `pending` contact is queued. Placeholders are filled per contact, and a missing `whatsapp_number` is copied from an E.164 `phone_number`. Sending is paced, and opted-out/`dnc` contacts are skipped. - **`email` with both `email_subject` and `email_body`:** one email per `pending` contact with an `email`, 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 `pending` contacts, 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). **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.** Voice calls emit `call.completed` / `call.failed`; the campaign emits `campaign.completed` (`{ campaignId, campaignName }`) when it finishes; plus `audit.log_recorded`. See [Webhooks](/webhooks). **Access** - **Required scope:** `full`. Admin-only route: `read`/`write` keys 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](/rate-limits). - **Plan:** Active-campaign cap: Starter 1, Growth 3, Business and Enterprise unlimited (the system `manual` campaign does not count). Pending contacts must not exceed the plan's contact limit (Starter 500, Growth 2,000, Business 20,000).

Authentication

AuthorizationBearer
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. | Scope | GET / HEAD | POST / PUT / PATCH / DELETE | Admin-only routes | | --- | --- | --- | --- | | `read` | Yes | No | No | | `write` | Yes | Yes | No | | `full` | Yes | Yes | Yes | 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](/authentication).

Path parameters

campaignIdstringRequiredformat: "uuid"

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).

dataobject

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.

Errors

400
Bad Request Error
401
Unauthorized Error
403
Forbidden Error
404
Not Found Error
409
Conflict Error
429
Too Many Requests Error