Skip to main content

Campaign approvals

Campaign approvals add a review step between “an operator launches a campaign” and “messages leave the platform.” One person drafts campaigns; a different person — an owner or an admin — signs off on what goes out. It is the dual-control pattern regulated teams run on email platforms, applied to every outbound channel (SMS, WhatsApp, email, voice). Use it when a member or developer should not launch to a large audience unreviewed, or when your compliance policy requires a named reviewer on every send. If your launch permission depends on an org-wide policy, this page covers the surface; for the full campaign object it gates, see the campaign lifecycle concept.

Who does what

The gate separates the requester from the approver:
  • Requester — any team member with launch rights on the campaign (a member or developer). They build the campaign, resolve the audience, and press Launch campaign on the campaign detail page.
  • Approver — an owner or an admin. They review queued launches under Outbound → Approvals and decide. Owners and admins launching themselves are never gated — the gate would deadlock otherwise.
Every member of the team can read the approval policy (GET /campaigns/approvals/settings) — an operator needs to know whether their next launch will be gated before they press the button.

Enabling the gate

Turn the gate on under Outbound → Approvals, or over the API. Two org-level settings decide what gets gated: Both default to off, so until an owner or admin enables the gate, launches go straight through — the gate is strictly opt-in. Owners and admins can always launch directly; the threshold only narrows which non-supervisor launches get parked. Configure over the API:

What launch looks like to the requester

When the gate is on, a requester’s launch does not send. It parks:
The launch returns 202 with an approval id — not an error. The campaign moves to pending_approval, and the request lands in the supervisors’ queue with the resolved audience size and an optional note from the requester. Nothing reaches recipients until an approver acts.

Working the queue

Open Outbound → Approvals. The page has two parts: the policy toggle at the top (Enable / size threshold) and the Pending launches queue below it. Each queued launch shows:
  • Who requested it — the team member’s display name resolved from the team list, so the supervisor sees a person, not an id.
  • Audience size — the resolved recipient count at request time (the gate snapshots it, so a later list change does not re-derive the count the supervisor approved).
  • When it was submitted — relative then absolute timestamp.
  • Requester’s note — optional context the requester attached; empty shows “No note from the requester.”
An approver has two decisions:
  • Approve & send — the campaign re-enters the normal launch path and dispatches exactly as if the approver had launched it themselves. The approval is marked only after dispatch succeeds.
  • Reject — optional reason; the campaign returns to draft. Nothing was sent. The requester edits the body, list, or schedule and resubmits.
Reject has no partial approve-with-edits mode — the approver either sends the campaign as-is or hands it back. If dispatch fails on approve (insufficient wallet, a policy gate on the campaign itself), the approval stays in the queue and the error surfaces to the approver — the queue does not silently lose the launch.

Campaign states across the lifecycle

The campaign lifecycle page covers the full status machine these four steps slot into.

How deny affects scheduling

A denied campaign does not fail; it returns to draft. Anything the launch depended on (a schedule, a list fix, a body edit) is still editable — the approver just enforced a human checkpoint before any of it ran. A rejected launch never sends, and the audit reason (if provided) is stored with the decision. This is by design: the gate changes who can launch, not how messages leave. An approved campaign dispatches over the same pipeline as a direct launch — the same suppression, consent, quiet-hours, and provider chain.

API surface

Bulk approval — approvers decide one campaign at a time; the queue is the batch surface, so the reviewer handles each payload deliberately rather than rubber-stamping a page of checkboxed launches.

Worked example: gated launch to a rejected campaign

A pass through gate → reject → re-edit → approve: 1. Enable the gate (owner, once per org) — gate every launch above 500 recipients:
2. A member launches a 7,800-recipient SMS campaign. The launch parks:
3. An admin opens Outbound → Approvals, reads the requester’s note (“Holiday promo — audience is the opted-in holiday list”), and rejects with reason “Audience list includes recipients from the suppressed segment — trim and resubmit.”
The campaign returns to draft; the requester trims the list, re-resolves the audience, and resubmits the launch. This time the approver approves, the campaign dispatches on the normal path, and the launch reads approved in the queue’s history.