Skip to content
On this site

Broadcasts

One message to a segment. A broadcast is a draft until it is sent, passes a compliance gate on the way out, and becomes one ordinary email per recipient — each with its own events.

Lifecycle

draftscheduled or queuedsendingsent. A cancel from scheduled or queued ends in canceled; a cancel while sending stops at the next page of recipients, and the sends already created go out. Only a draft can be updated or deleted.

The gate

A send is refused with 422 — and creates nothing — unless all of these hold:

What a broadcast needs before it is queued
NeedsMeaning
A verified sending domainfrom is on a domain of yours verified for sending.
A postal addressSet once under Settings → Sender. It is printed in every broadcast's footer.
A segmentsegment_id names a live segment.
A bodyhtml, text, or a published template.
A team in good standingA team that cannot send transactional mail cannot send a broadcast either.

Recipients

  • The segment's members, minus anyone globally unsubscribed, opted out of the broadcast's topic, on the suppression list, or deleted. Each exclusion is recorded with its reason and shows up in the recipients report.
  • Every recipient is an ordinary send: it counts toward your quota, carries List-Unsubscribe headers for one-click unsubscribe, and raises the same email.* events a transactional send does.

Merge variables

Bodies and the subject may carry {{{KEY}}} or {{{KEY|default}}}. A missing value takes the inline default, then the property's fallback_value, then the empty string. Values are HTML-escaped in html and written as-is in text and subject.

Merge variables
VariableValue
FIRST_NAMEThe contact's first name.
LAST_NAMEThe contact's last name.
EMAILThe contact's address.
<PROPERTY_KEY>Any declared contact property, upper- or lower-case as declared.
UNSUBSCRIBE_URLA one-click global unsubscribe link for this recipient.
PREFERENCES_URLThe hosted preference page for this recipient.

A body with neither {{{UNSUBSCRIBE_URL}}} nor {{{PREFERENCES_URL}}} gets a plain footer appended — an unsubscribe link and your postal address — so no broadcast leaves without both.

Endpoints

POST /broadcasts

A draft, or — with `send: true` — a broadcast queued straight through the gate.

Body

Body
FieldTypeDescription
namestringA label for the dashboard. Not shown to recipients.
segment_idstringThe segment the broadcast goes to.
fromstringName <address> on one of your verified domains.
subjectstringThe subject line. Merge variables are allowed.
reply_tostring[]Where replies go.
htmlstringThe HTML body. At least one of html and text before sending.
textstringThe plain-text body.
sendbooleanSend now (or at scheduled_at) instead of leaving a draft. Defaults to false.
scheduled_atstringISO 8601, between one minute and thirty days out. Only with send: true.
3 more fields (preview_text, topic_id, template)
Body, less common
FieldTypeDescription
preview_textstringThe inbox preview line.
topic_idstringScope the broadcast to a topic: only contacts opted in to it receive it.
templateobject{ id } of a published template to copy the content from, instead of html and text.
curl -X POST "https://api.rasket.com/broadcasts" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "September product update",
  "segment_id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
  "from": "Acme <news@send.acme.example>",
  "subject": "What shipped in September",
  "reply_to": ["hello@acme.example"],
  "html": "<p>Hi {{{FIRST_NAME|there}}},</p><p>Here is what shipped in September.</p><p><a href=\"{{{UNSUBSCRIBE_URL}}}\">Unsubscribe</a></p>"
}'

Response 201

{
  "object": "broadcast",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"
}
  • from and subject are required; everything else can wait for an update. Sending needs a segment and a body.
  • Bodies may carry {{{KEY}}} or {{{KEY|default}}} over FIRST_NAME, LAST_NAME, EMAIL, every contact property key, UNSUBSCRIBE_URL and PREFERENCES_URL, rendered per recipient.
  • A body with neither {{{UNSUBSCRIBE_URL}}} nor {{{PREFERENCES_URL}}} gets a footer with an unsubscribe link and your postal address appended, so no broadcast leaves without one.
  • With send: true, a gate refusal creates nothing.

GET /broadcasts

Every broadcast, newest first.

Query parameters

Query parameters
FieldTypeDescription
limitintegerHow many items to return, 1–100. Defaults to 20.
afterstringReturn the page that follows this item ID. Mutually exclusive with before.
beforestringReturn the page that precedes this item ID. Mutually exclusive with after.
curl -X GET "https://api.rasket.com/broadcasts" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
      "name": "September product update",
      "segment_id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
      "status": "sent",
      "created_at": "2026-09-08T22:22:17.595Z",
      "sent_at": "2026-09-09T09:00:04.118Z"
    }
  ]
}
  • scheduled_at and sent_at are absent until they are set, never null. Deleted drafts are not listed.

GET /broadcasts/{id}

One broadcast, with its content and status.

Path parameters

Path parameters
FieldTypeDescription
id*stringThe broadcast's ID.
curl -X GET "https://api.rasket.com/broadcasts/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "broadcast",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
  "name": "September product update",
  "segment_id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
  "from": "Acme <news@send.acme.example>",
  "subject": "What shipped in September",
  "reply_to": ["hello@acme.example"],
  "preview_text": "Three new features and a faster editor.",
  "status": "draft",
  "created_at": "2026-09-08T22:22:17.595Z",
  "html": "<p>Hi {{{FIRST_NAME|there}}},</p><p>Here is what shipped in September.</p><p><a href=\"{{{UNSUBSCRIBE_URL}}}\">Unsubscribe</a></p>",
  "text": null,
  "topic_id": null
}
  • status is one of draft, scheduled, queued, sending, sent, canceled or failed.

PATCH /broadcasts/{id}

Change a draft. Only the fields present are touched.

Path parameters

Path parameters
FieldTypeDescription
id*stringThe broadcast's ID.

Body

Body
FieldTypeDescription
namestringA label for the dashboard. Not shown to recipients.
segment_idstringThe segment the broadcast goes to.
fromstringName <address> on one of your verified domains.
subjectstringThe subject line. Merge variables are allowed.
reply_tostring[]Where replies go.
htmlstringThe HTML body. At least one of html and text before sending.
textstringThe plain-text body.
2 more fields (preview_text, topic_id)
Body, less common
FieldTypeDescription
preview_textstringThe inbox preview line.
topic_idstringScope the broadcast to a topic: only contacts opted in to it receive it.
curl -X PATCH "https://api.rasket.com/broadcasts/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "subject": "What shipped in September — and what is next"
}'

Response 200

{
  "object": "broadcast",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"
}
  • A broadcast past draft is 400 validation_error; cancel it first if it has not started sending.

DELETE /broadcasts/{id}

Remove a draft.

Path parameters

Path parameters
FieldTypeDescription
id*stringThe broadcast's ID.
curl -X DELETE "https://api.rasket.com/broadcasts/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "broadcast",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
  "deleted": true
}
  • Drafts only. A broadcast that was sent keeps its report; one that was scheduled must be canceled instead.

POST /broadcasts/{id}/send

Queue a draft now, or schedule it.

Path parameters

Path parameters
FieldTypeDescription
id*stringThe broadcast's ID.

Body

Body
FieldTypeDescription
scheduled_atstringISO 8601, between one minute and thirty days out. Omit it to send now.
curl -X POST "https://api.rasket.com/broadcasts/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17/send" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "scheduled_at": "2026-09-12T09:00:00Z"
}'

Response 200

{
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"
}
  • The gate refuses with 422 unless: from is on a domain verified for sending; the team has a postal address (Settings → Sender); the segment resolves; and the broadcast has a body. A team that cannot send is 403.
  • Recipients are the segment's members, minus anyone globally unsubscribed, opted out of the broadcast's topic, suppressed or deleted. Each is an ordinary send with email.* events of its own.
  • The response is { id } alone, as the reference document has it.

POST /broadcasts/{id}/cancel

Stop a scheduled or queued broadcast.

Path parameters

Path parameters
FieldTypeDescription
id*stringThe broadcast's ID.
curl -X POST "https://api.rasket.com/broadcasts/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17/cancel" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "broadcast",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"
}
  • A broadcast mid-send stops at its next page of five hundred recipients; sends already created go out. Only scheduled and queued (or sending) broadcasts can be canceled.

GET /broadcasts/{id}/recipients

Who was sent, delivered, opened, clicked, bounced, complained, unsubscribed or skipped.

Path parameters

Path parameters
FieldTypeDescription
id*stringThe broadcast's ID.

Query parameters

Query parameters
FieldTypeDescription
type*stringsent, delivered, opened, clicked, bounced, complained, unsubscribed or suppressed.
emailstringOnly recipients whose address contains this.
bounce_typestringpermanent, transient or undetermined. Only with type=bounced.
limitintegerHow many items to return, 1–100. Defaults to 20.
afterstringReturn the page that follows this item ID. Mutually exclusive with before.
beforestringReturn the page that precedes this item ID. Mutually exclusive with after.
curl -X GET "https://api.rasket.com/broadcasts/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17/recipients?type=clicked&limit=20" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "cur_01k4xq8p9m",
      "contact_id": "e169aa45-1ecf-4183-9955-b1499d5701d3",
      "email": "ronald.williams@example.com",
      "count": 2,
      "clicked_links": [
        {
          "url": "https://acme.example/changelog",
          "clicks": 2
        }
      ]
    }
  ]
}
  • id is an opaque cursor for paging, not an entity id. count appears for opened and clicked, bounce_type for bounced, clicked_links for clicked.
  • contact_id is null for a contact deleted since the send.

GET /broadcasts/{id}/checklist

Every condition of the send gate, passed or not, in the order a send checks them.

Path parameters

Path parameters
FieldTypeDescription
id*stringThe broadcast's ID.
curl -X GET "https://api.rasket.com/broadcasts/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17/checklist" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "broadcast_compliance",
  "broadcast_id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
  "sendable": false,
  "conditions": [
    {
      "condition": "sending_domain",
      "passed": true
    },
    {
      "condition": "postal_address",
      "passed": false,
      "name": "validation_error",
      "message": "A postal address is required before sending a broadcast."
    },
    {
      "condition": "segment",
      "passed": true
    }
  ]
}
  • A failed condition carries the name and message a send would answer with.
  • It is a snapshot: POST /broadcasts/{id}/send runs the same gate again when you call it.