Update a campaign

View as Markdown
Partially updates a `draft`, `active` or `paused` campaign. Only the fields in the body change, an empty body returns the campaign unchanged, and the agent cannot be swapped. Send `null` for `whatsappTemplateId`, `whatsappTemplateVariables`, `whatsappTemplateVariableMap`, `emailSubject` or `emailBody` to clear it. Clearing the template, or the subject and body, makes the next activation inbound-only. Editing an `active` campaign is allowed and takes effect for work that has not started yet. The dialer reads `schedule`, `status` and the retry settings each time it picks up a contact. WhatsApp and email messages that are already queued keep the content rendered at activation, so new content reaches only contacts queued later (pause, then activate again). Checks: the campaign is not `completed`/`archived` (400); a new `channel` is served by the campaign's agent (400); tokens and the WhatsApp variable map resolve against the template that will be in effect after the change (400). `maxConcurrentCalls` is silently lowered to the plan's ceiling. **Side effects.** Updates the row, clears the campaign caches and writes an audit entry. No provider is called. **Idempotency.** Safe to retry: sending the same body again leaves the same state. **Webhook events.** `audit.log_recorded` for webhooks subscribed to it. 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:** Available on every plan. The concurrency ceiling depends on the plan.

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 update. A campaign from another workspace or a deleted one answers 404; a value that is not a UUID answers 400.

Request

This endpoint expects an object.
namestringOptional1-200 characters
New display name.
productContextstringOptional10-5000 characters
New product context for the agent.
targetAudiencestringOptional1-1000 characters
New audience description for the agent.
scheduleobjectOptional

Weekly calling window, stored and returned exactly as sent (camelCase inside the object). The dialer starts a call only when the local hour in timezone is >= startHour and < endHour on an enabled day; outside it, the call is rescheduled to the next window. A call that started inside the window may run past endHour. Days that are left out count as disabled. Validation: timezone must be a valid IANA zone (Invalid IANA timezone), every enabled day needs startHour < endHour, and at least one day must be enabled (At least one day must be enabled). WhatsApp and email sends are not bound to this window.

maxConcurrentCallsintegerOptional1-500

New concurrency; silently lowered to the plan’s ceiling.

maxRetryAttemptsintegerOptional0-10

New maximum dial attempts per contact (counting the first).

retryIntervalMinutesintegerOptional5-1440
New minutes between a missed call and its redial.
channelenumOptional

New channel (voice, whatsapp, webchat or email). The campaign’s current agent must serve it (400 otherwise).

categoryenumOptional

New purpose (see Campaign.category for each value).

whatsappTemplateIdstring or nullOptionalformat: "uuid"

New WhatsApp template, or null to make the campaign inbound-only. The variable map is re-checked against the new template body.

whatsappTemplateVariableslist of strings or map from strings to strings or nullOptional

New campaign-wide placeholder values (same shapes as on create), or null to clear them.

whatsappTemplateVariableMapmap from strings to any or nullOptional

New per-contact placeholder map (same shape as on create); null clears it so every placeholder uses the campaign-wide values.

emailSubjectstring or nullOptional1-300 characters

New email subject, or null to clear it.

emailBodystring or nullOptional1-20000 characters

New email body, or null to clear it.

Response

The updated campaign (or the unchanged one, for an empty body).

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
429
Too Many Requests Error