Broadcasts
A broadcast is one message sent to a contact list, as opposed to a transactional email sent to a person. In the API and the dashboard they are called campaigns.
Create and send in one call
curl -X POST https://app.mailstein.com/api/v1/campaigns \
-H "Authorization: Bearer $MAILSTEIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "August update",
"from": "hello@yourdomain.com",
"subject": "What is new this month",
"contactBookId": "cmsm9oxxc000hvseu4644xt6u",
"html": "<p>Hello.</p><p><a href=\"{{unsubscribe_url}}\">Unsubscribe</a></p>",
"sendNow": true
}'
Leave sendNow out to keep it as a draft, or pass scheduledAt to send later.
scheduledAt accepts ISO 8601 and also plain English — "tomorrow 9am",
"next monday 10:30".
Plain English is interpreted in the server's timezone, not yours.
"tomorrow 9am" means 9am where the server is, which is not where you are. If
the exact minute matters — and for a broadcast it usually does — send ISO 8601
with an offset and leave nothing to interpretation:
{ "scheduledAt": "2026-08-11T09:00:00-04:00" }
The unsubscribe link is not optional
A broadcast without {{unsubscribe_url}} in its body is refused at schedule
time. This is not a house style rule: bulk mail without a working unsubscribe
breaks CAN-SPAM and GDPR, and Gmail and Yahoo both require one-click
unsubscribe from bulk senders. mailstein adds the List-Unsubscribe and
List-Unsubscribe-Post headers for you, but the visible link has to be in your
body.
Pacing
batchSize limits how many go out at a time. A large list arriving at one
provider in a single burst looks like exactly what spam looks like, and the
sending reputation you damage is your own.
If you have never sent to this list before, send to your most engaged contacts first and grow from there. A cold list mailed all at once is the single most common way a new domain gets itself blocked.
Pausing
curl -X POST https://app.mailstein.com/api/v1/campaigns/$ID/pause \
-H "Authorization: Bearer $MAILSTEIN_API_KEY"
Pause stops a running send; resume continues it. Contacts already sent to are not sent to again.
Editing
Only a draft can be edited. Once a broadcast is scheduled or running, part of it may already be in inboxes, and changing the body would leave two halves of one campaign with different content and no way to tell who got which. Cancel and make a new one.