Create a broadcast
Composes a broadcast in the draft state, in one of two
mutually-exclusive content modes:
- Template mode — supply
template_id(the template slug / file name fromGET /v1/templates, e.g.welcome.html, not a UUID) plus optionaltemplate_version(defaults to latest) andtemplate_data(shared merge data; per-recipient contact attributes are overlaid at send). Inject a large rendered HTML block as a triple-stache variable ({{{body_html}}}) so it is not HTML-escaped. - Inline mode — supply
html(raw, fully-rendered content) plus optionaltext. Inline HTML must satisfy the same caps as templates (≤500 KB, valid UTF-8, at least one HTML tag).
Supplying both template_id and html, or neither, is a
422 validation_failed. subject and preview_text are owned by the
broadcast (overridable per send). from_identity, when given, must be one
of the org's verified identities (see GET /v1/identities); omit it to
send from the default no-reply@<verified-domain> address. topic_id,
when given, is the topic name from GET /v1/topics (not a UUID).
Does not send — call POST /v1/broadcasts/{id}/send. Supports the
Idempotency-Key header: a duplicate key within 24 h replays the original
response.
Request body
Content type: application/json
name string required A label for the broadcast.
template_id string optional Template mode — the template slug (file name) the broadcast renders, i.e. the slug from GET /v1/templates (e.g. welcome.html), not an internal UUID. An unknown slug is a 422. Mutually exclusive with html.
template_version integer<int32> optional Template mode — the integer version to pin. Optional: omit (or send 0) to pin the latest version. (Git-backed templates carry no version history, so this is effectively always the latest for them.)
template_data object optional Template mode — shared merge data overlaid under each recipient's contact attributes. Inject a large rendered HTML block as a triple-stache variable ({{{body_html}}}) to avoid HTML-escaping.
html string optional Inline mode — raw, fully-rendered HTML. Mutually exclusive with template_id. Same caps as templates (≤500 KB, valid UTF-8, ≥1 HTML tag).
text string optional Inline mode — optional plain-text alternative.
audience_kind string enum required Whether audience_id references a List or a Segment.
One of: list, segment
audience_id string<uuid> required The List or Segment to send to.
topic_id string optional Optional opt-out topic, given by its name (the identifier GET /v1/topics exposes), not an internal UUID. An unknown name is a 422. Omit for a topic-less broadcast.
from_identity string optional Optional. A verified identity to send from (see GET /v1/identities); omit for the default no-reply@
subject string required The email subject (overrides any template subject in inline mode).
preview_text string optional Optional inbox preview text.
acknowledge_no_topic boolean optional Acknowledge the no-topic warnings up front (can also be supplied at send time). Required before a topic-less broadcast can be sent.
Responses
Errors follow the RFC 7807 problem format — see the error reference.
id string<uuid> required name string required content_mode string enum required The content source. template renders a pinned workspace template; inline sends caller-supplied raw HTML (not echoed back).
One of: template, inline
template_id string | null optional The template slug (file name) the broadcast renders — the same identifier GET /v1/templates exposes as slug, not an internal UUID. Null in inline mode.
template_version integer<int32> | null optional The pinned integer template version (null in inline mode).
audience_kind string enum required Whether audience_id references a List or a Segment.
One of: list, segment
audience_id string<uuid> required subject string required The broadcast owns the subject (overridable per send).
preview_text string optional from_identity string | null optional The explicit verified from-address, or null for the default no-reply@
default_template_data object optional DefaultTemplateData applied where a recipient lacks an attribute value.
topic_id string | null optional The topic name (the same identifier GET /v1/topics exposes), or null for a topic-less broadcast. Not an internal UUID.
schedule_at string<date-time> | null optional The scheduled UTC fire time, or null for a send-now broadcast.
state string enum required One of: draft, scheduled, sending, sent, partially_failed, cancelled
recipient_count integer<int64> | null optional Mailable snapshot size, stamped at send (null before send).
sent_count integer<int64> | null optional failed_count integer<int64> | null optional started_at string<date-time> | null optional completed_at string<date-time> | null optional created_at string<date-time> required updated_at string<date-time> required summary object | null optional The outcome rollup, present once a send has finalized the cached counts; null on a draft/scheduled broadcast that has never sent.
Fields of summary:
audience_size integer<int64> required Snapshot audience size before the consent filter.
mailable integer<int64> required Recipients that passed the consent filter (sent + failed).
sent integer<int64> required failed integer<int64> required filtered integer<int64> required Recipients dropped by the consent filter.
tags array<object> optional Org-side tags/folders applied to this broadcast (managed via the dashboard). Editable regardless of send state, so historical broadcasts stay organizable. Filter the collection with ?tag=.
Each entry in tags:
id string<uuid> required name string required Full folder path (e.g. Marketing/Newsletters).
key string required Normalized slug handle of the name.
color string optional Chip colour token (chart-1..chart-5), or empty.
description string optional created_at string<date-time> required updated_at string<date-time> required code is internal_error. The
request_id field can be quoted to SendOps support to investigate.
application/problem+json