Broadcasts

Create, schedule and send marketing broadcasts to an audience.

A broadcast sends one message to every subscribed contact of an audience, rendered per contact. Broadcasts don't use your transactional email quota; they are governed by your Marketing plan's contact limit. All endpoints require a full_access key.

Create a broadcast

POST/api/v1/broadcasts

Creates a draft. Set send: true to create and send (or schedule) in one call.

Body

fromstringrequired
Sender on a verified domain of the workspace (3–320 characters). The onboarding address can't send broadcasts.
subjectstringrequired
Subject line (1–998 characters). May contain variables.
audience_idstring
Audience to send to (required before sending). segment_id is accepted as an alias.
namestring
Internal name (≤ 200 characters).
reply_tostring
Reply-To address (≤ 320 characters).
htmlstring
HTML body with variables.
textstring
Plain-text body. Generated from the HTML when omitted.
template_idstring
Use a template's published content; the broadcast's own html / text / subject take precedence when set.
sendbooleandefault false
Send immediately after creating.
scheduled_atstring (ISO 8601)
With send: true: send at this time instead (future, ≤ 30 days).
# Create and schedule a broadcast
curl -X POST 'https://api.bytesms.com/api/v1/broadcasts' \
  -H 'Authorization: Bearer tp_live_xxxxxxxxx' \
  -H 'Content-Type: application/json' \
  -d '{"name":"October newsletter","audience_id":"cmg4p3v1e0006l8v9k8d2m5nb","from":"Acme <[email protected]>","subject":"New in October","html":"<p>Hi {{{first_name|there}}},</p><p>Here is what shipped this month.</p><p><a href=\"{{{unsubscribe_url}}}\">Unsubscribe</a></p>","send":true,"scheduled_at":"2026-10-01T02:00:00Z"}'
Response
{
  "id": "cmg4q2r6g0008l8v9b3n7w4xd"
}

Personalisation and unsubscribe

  • Variables use the template syntax. Available per contact: {{{first_name}}}, {{{last_name}}}, {{{email}}}, every contact property, and {{{unsubscribe_url}}} (alias {{{RESEND_UNSUBSCRIBE_URL}}}). Missing values render empty unless a fallback is given.
  • If the content has no unsubscribe_url placeholder, an unsubscribe link is appended automatically. Every broadcast email also carries one-click List-Unsubscribe headers; unsubscribing marks the contact unsubscribed.
  • Unsubscribed, suppressed and invalid contacts are skipped and counted in skipped_count.

Send a broadcast

POST/api/v1/broadcasts/{broadcast_id}/send

Body

scheduled_atstring (ISO 8601)
Optional future send time (≤ 30 days).

Only a draft with an audience and a body can be sent. Sending is refused (403 plan_limit_exceeded, code: contact_limit_exceeded) while the workspace has more contacts than its Marketing plan allows.

# Send now
curl -X POST 'https://api.bytesms.com/api/v1/broadcasts/cmg4q2r6g0008l8v9b3n7w4xd/send' \
  -H 'Authorization: Bearer tp_live_xxxxxxxxx' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "id": "cmg4q2r6g0008l8v9b3n7w4xd"
}

Retrieve a broadcast

GET/api/v1/broadcasts/{broadcast_id}
Response
{
  "object": "broadcast",
  "id": "cmg4q2r6g0008l8v9b3n7w4xd",
  "name": "October newsletter",
  "audience_id": "cmg4p3v1e0006l8v9k8d2m5nb",
  "from": "Acme <[email protected]>",
  "subject": "New in October",
  "reply_to": null,
  "html": "<p>Hi {{{first_name|there}}},</p>…",
  "text": null,
  "template_id": null,
  "status": "sent",
  "total_recipients": 1250,
  "sent_count": 1238,
  "skipped_count": 12,
  "failure_reason": null,
  "created_at": "2026-09-28T11:00:00.000Z",
  "scheduled_at": "2026-10-01T02:00:00.000Z",
  "sent_at": "2026-10-01T02:00:41.000Z"
}
statusMeaning
draftEditable, not sent.
scheduledWaiting for scheduled_at.
queuedAbout to be sent.
sendingEmails are being created for each contact.
sentEvery contact was processed.
canceledCanceled before sending.
failedCouldn't be sent — see failure_reason.

List broadcasts

GET/api/v1/broadcasts

Query

statusstring
Filter by status.
audience_idstring
Filter by audience.

Update a broadcast

PATCH/api/v1/broadcasts/{broadcast_id}

Only drafts can be edited. Same fields as create (without send/scheduled_at), all optional; null clears an optional field. Returns { id }.

Cancel a broadcast

POST/api/v1/broadcasts/{broadcast_id}/cancel

Cancels a scheduled or queued broadcast. Returns { object: "broadcast", id }.

Delete a broadcast

DELETE/api/v1/broadcasts/{broadcast_id}

Only draft or canceled broadcasts can be deleted.

Response
{
  "object": "broadcast",
  "id": "cmg4q2r6g0008l8v9b3n7w4xd",
  "deleted": true
}

Test sends

Sending a test copy of a broadcast to yourself is available in the dashboard.