Broadcasts
One-off marketing sends to an audience or segment — create, send, cancel, stats.
A broadcast is a one-off marketing send to an audience or segment with its own
draft lifecycle — separate from transactional
POST /v1/email traffic.
Lifecycle
draft ──send──▶ scheduled (future scheduled_at)
│ └───▶ sending (fan-out cron's next tick)
│ └──▶ sent
└──cancel──▶ cancelled ◀──cancel (only from draft/scheduled)| Step | Endpoint |
|---|---|
| Create a draft | POST /v1/broadcasts |
| Edit the draft | PATCH /v1/broadcasts/{id} — draft only, else 409 not_editable |
| Send or schedule | POST /v1/broadcasts/{id}/send — draft only, else 409 not_draft |
| Cancel | POST /v1/broadcasts/{id}/cancel — draft/scheduled only, else 409 not_cancelable |
| Read stats | GET /v1/broadcasts/{id} |
| Delete | DELETE /v1/broadcasts/{id} — hard delete, any status |
Sending
POST /v1/broadcasts/{id}/send validates first — subject, body_html or
body_text, a target that still resolves, and a verified from_domain_id
(errors: invalid_subject, invalid_body, invalid_target,
domain_not_verified). It then:
- computes a best-effort
total_recipientssnapshot, - sets
status = scheduledif you passed a futurescheduled_at(epoch ms), otherwisestatus = sending.
Nothing is enqueued by the call itself — the per-minute fan-out cron picks up
sending broadcasts on its next tick.
{ "scheduled_at": 1783472400000 }Targeting
target_kind is audience or segment with the matching target_id —
built from Contacts & audiences. Re-validating a
target happens when a PATCH touches target_kind/target_id.
Listing & pagination
GET /v1/broadcasts pages with ?limit= (max 100) and a composite
"{created_at}:{id}" cursor.
Multi-step programs
For wait/branch logic (drip sequences), use
/v1/automations: create steps
(send / wait / branch), then activate, pause, and enroll
contacts. Guardrails are explicit: no_steps, not_activatable,
wait_out_of_range, bad_branch_filter, and friends.