Broadcasts API — Mimeo docs

Broadcasts API

A one-off send: its own email, a segment, and a time. Membership is resolved when it sends, not when it's scheduled.

Method & path What it does
GET /api/v1/broadcasts All of them. Filter with ?status=.
POST /api/v1/broadcasts Compose one. Body: name, segment_id, email_source, email_id, emails_per_hour.
GET /api/v1/broadcasts/:id One, with its email, segment and stats.
PATCH /api/v1/broadcasts/:id Update name, segment_id, emails_per_hour.
DELETE /api/v1/broadcasts/:id Only a draft or a canceled one. 409 otherwise.
POST /api/v1/broadcasts/:id/replace_email Swap the email, while it's still a draft or scheduled.
POST /api/v1/broadcasts/:id/schedule Body: send_at. See scheduling for how the time is read.
POST /api/v1/broadcasts/:id/unschedule Back to draft, keeping its email and audience. 409 unless scheduled.
POST /api/v1/broadcasts/:id/send_now Send it. Answers with the recipient count.
POST /api/v1/broadcasts/:id/cancel Cancel it and everything it has queued.

A broadcast never shares its email

email_source is required and accepts only scratch or copy. shared is refused with 422, on the server, rather than trusted to whichever client is asking.

POST /api/v1/broadcasts
{ "email_source": "copy", "email_id": 42, "segment_id": 3, "name": "July announcement" }

What one broadcast sent should stay what it sent. If a broadcast pointed at a shared library row, editing a sequence step months later could silently rewrite the record of a send that already went out — so every broadcast gets a row of its own, blank or copied. This is also why emails/ in a manager repo fills up with rows that exist for one send: expected, not drift, and the used-in filter is how you tell them apart.

The email can only be swapped or forked while the broadcast is still a draft or scheduled. Once it's sending or sent, its email is history.

Scheduling

send_at takes any parseable datetime. A time without a UTC offset"2026-08-10T08:30" — is read in the account's timezone: the profile timezone setting, Eastern Time if none is set. Include an offset ("2026-08-10T08:30:00-04:00") to say exactly what you mean regardless of that setting. Responses always carry the offset. A time already in the past is refused with 422.

unschedule undoes scheduling and nothing else: the broadcast goes back to draft with its email and audience intact. cancel is the harder stop — it moves the broadcast to canceled and kills anything already queued, which is the tool once sending has started.

Delivery

Sending fans out through the ordinary paced queue — one queued email per recipient. Guards, send windows and tracking all apply, and every broadcast gets a full report.

The fan-out is spread across time at the broadcast's sending pace: emails_per_hour when the broadcast sets one, otherwise the account default (sending.broadcast_emails_per_hour, 5,000 by default). The pace is written into each queued row's due time at send time, so the queue shows the real schedule — 20,000 recipients at 5,000/hour is four hours of visible, cancelable rows. Set emails_per_hour to null to go back to the account default.

Audience

Resolved at send time from the segment's live rules, not stored when you schedule. A segment that grows between now and Friday means more recipients on Friday. Unsubscribed people are excluded, and the standing suppression guard checks again for every individual send.

Broadcasts are runtime rather than authoring, so they don't appear in a manager repo — though the emails they mint do.

See also: Emails API · Segments API · Broadcasts, for humans