A broadcast is a draft that tells you what is wrong with it
email.broadcast.create makes a draft: a published template, sent from an address the project may send from — its own <project-slug>.via.trylath.com address, or one on a domain you have verified — to every contact with current consent for a topic, optionally narrowed by a segment.
It returns readiness immediately. A sender the project may not use, a missing postal address for the footer, an unknown topic or segment, an unpublished or reserved template, a template with no unsubscribe link: each comes back as a problem with a code, what is wrong and the fix. You find out at create time, not when you press send on a campaign to twenty thousand people.
A domain of your own is not required, but it is worth having before volume: mail from the shared parent sends under a name every other project also sends from, and a domain you own keeps your list’s reputation yours.
email.broadcast.update changes it while it is still a draft. email.broadcast.list and .get read them back — and get counts progress separately, because the counts on the broadcast itself are written once at send and never recomputed.
Sending is the point of no return, and it is guarded
email.broadcast.send runs the same readiness checks again and refuses with the first one that still stands. It also refuses an audience over 50,000 contacts with audience_too_large, a closed account, and — once an unpaid invoice is past its grace period — any marketing send at all. Those are the conditions under which a bulk send is lawful, deliverable and paid for, so they are enforced rather than recommended.
It then queues one message per consenting contact, with that contact’s properties as variables and a personal unsubscribe link. A contact who is suppressed still gets a message row, recorded as suppressed and never sent; a contact with no current consent gets no row at all and is only counted. The consent guide covers what counts as consenting; nothing here bypasses it.
Give scheduledAt and the broadcast is queued now and released at that time, rather than depending on something being awake to trigger it.
Pause, resume and cancel do exactly what they say
Pause holds a broadcast that is sending: messages not yet handed to delivery stop. Messages already sent are not recalled — nothing can recall those, and an API that implied otherwise would be lying.
Resume puts the held messages back in the queue and continues from where it stopped. Nobody is sent to twice: the ones that already went are untouched, and the audience policy is checked again for each remaining message at the moment it sends — so somebody who unsubscribed during the pause is not sent to.
Cancel closes a broadcast that has not finished, and cancels its messages that are still queued or paused. A broadcast that has finished sending is refused with already_sent, because marking it cancelled would rewrite the record of a send that fully happened. Again, what has already gone has gone.
SMS broadcasts
sms.broadcast.create, .send, .pause, .resume and .cancel work the same way, with checks that fit the channel rather than the same ones. There is no sender or postal-address check. Instead the template must be published, not empty and not a sign-in template, and must tell people how to stop — opt_out_missing when it never says STOP, which is not appended for you because it would change the segment count you measured. The topic and segment must exist, and every rendered message must fit the segment limit.
Quiet hours are on by default with no timezone, and an SMS broadcast is refused with quiet_hours_timezone_unset until the environment has one set with sms.settings.set — even when contacts carry their own, because a broadcast will not guess a zone for the ones that do not.
The SMS rules guide covers quiet hours and segments, and the consent guide the stricter opt-out rules for texts.
Messages that send themselves
A broadcast goes once, to an audience, when you say. An automation sends when an event happens — a contact created, a purchase recorded — to the contact the event names, through a tree of waits, sends and branches. It has the same readiness checks and the same draft-until-activated rule. The automations guide covers it.Last modified on September 23, 2026