Broadcasts
Campaigns sent to an entire audience. Create a broadcast as a draft, then send or schedule it.
Sending a broadcast to an audience requires a paid plan. On Free you can create audiences,
build and preview broadcasts, and send test copies to your own account email or an address on a
verified domain — POST /broadcasts/:id/send returns 403 with code PLAN_LIMIT_EXCEEDED.
Broadcasts are campaigns sent to an entire audience (contact list). Create a broadcast as a draft, then send it when ready. In-flight broadcasts can be cancelled.
Lifecycle
draft → scheduled → sending → sent → cancelled
A broadcast can also move to paused if sending is halted
partway — for example it reaches your monthly or daily send limit, the sender
domain is no longer verified, or platform-wide sending is paused. Resume it by
sending again (POST /broadcasts/:id/send) once the underlying issue is resolved
— it continues from where it stopped.
Review on early list sends
New accounts can reach 500 recipients by broadcast before we've reviewed the account. Most first campaigns are smaller than that and go out in full, with nothing to do.
If your audience is larger, the first 500 are delivered immediately and the
broadcast moves to held with the rest queued behind a
quick manual review. You'll get an email when it's released, and the broadcast
continues from where it stopped — nothing is lost and nobody is emailed twice.
Unlike paused, a held broadcast can't be resumed by
sending again; POST /broadcasts/:id/send returns 403 with code
BROADCAST_HELD until the review clears.
The same allowance applies to very large POST /emails/batch sends, which return
LIST_SEND_HELD on the items beyond it.
This is a one-time step per account, not a recurring limit. It exists so one bad
actor can't damage the sending reputation that every customer on the platform
shares. If you're on a deadline, email support@eusend.dev and we'll clear it.
Sending from a domain registered in the last 30 days? The same 500-recipient allowance applies to
broadcasts until the account is reviewed. Transactional sending through POST /emails is
unaffected — send from a brand-new domain from day one.
API endpoints
/broadcasts| Parameter | Type | Description |
|---|---|---|
namerequired | string | Internal name for the campaign. |
audience_idrequired | string (UUID) | The audience (contact list) this broadcast is sent to. |
subjectrequired | string | Email subject line. |
fromrequired | string | Sender address. Accepts a bare email or a display name, e.g. "Acme <hello@yourdomain.com>". Must be from a verified domain. |
reply_to | string | Reply-To address for the campaign. Same format as from. Omit to have replies go to the sender address. |
html | string | HTML body. Required unless template_id is provided. A plain-text part is generated automatically. |
template_id | string (UUID) | Saved template to use instead of html. |
template_variables | object | Default {{variable}} values applied to every recipient (per-contact fields like first_name and custom properties override these). |
track_opens | boolean | Embed the open-tracking pixel. Omit to use your organization default (Settings → General → Email tracking). Resolved once at creation and kept for the life of the broadcast. |
track_clicks | boolean | Rewrite links to record clicks. Omit to use your organization default. Unsubscribe links are unaffected either way. |
curl -X POST https://api.eusend.dev/broadcasts \
-H "Authorization: Bearer eu_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "May Newsletter",
"audience_id": "550e8400-e29b-41d4-a716-446655440000",
"subject": "What'"'"'s new in May",
"from": "newsletter@acme.com",
"html": "<h1>Hello!</h1><p>Here'"'"'s what'"'"'s new...</p>"
}'/broadcasts/:id/sendSend a draft broadcast immediately, or schedule it for a future time by passing
scheduled_at. This endpoint also resumes a paused broadcast — it continues
from where it stopped, skipping recipients already sent. The audience is set when
creating the broadcast. Broadcasts can also be pre-scheduled via
PATCH /broadcasts/:id without triggering a send.
| Parameter | Type | Description |
|---|---|---|
scheduled_at | string (ISO 8601) | Future UTC datetime to deliver the broadcast. Omit to send immediately. Sets status to scheduled until the delivery time. |
curl -X POST https://api.eusend.dev/broadcasts/3fa85f64-5717-4562-b3fc-2c963f66afa6/send \
-H "Authorization: Bearer eu_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"scheduled_at": "2026-06-01T09:00:00Z"
}'/broadcasts/:id/testSend yourself a copy of the broadcast before it goes to the audience — the real message, through the real sending path, so you see exactly what a recipient sees.
Available on every plan, including Free. This is how you evaluate a broadcast without a paid subscription.
Recipients must be addresses on domains you have verified. A test send puts real
mail on the wire without the plan gate, so it is restricted to inboxes you already
control — pass an address anywhere else and you get 403 with code
DOMAIN_NOT_VERIFIED.
| Parameter | Type | Description |
|---|---|---|
torequired | string[] | Between 1 and 5 addresses, each on a domain this organization has verified. Duplicates are collapsed. |
What a test send does and does not do:
- Subject is prefixed with
[Test], so a test copy is never mistaken for the campaign. - Contact variables render with sample values (
{{first_name}}becomesAlex), rather than collapsing to an empty string and hiding a greeting that will look wrong later. Custom properties are borrowed from a real contact in the audience, since only your data knows what{{plan}}should look like. - The unsubscribe footer is included so you can see it, but its link is inert — there is no contact behind a test send to unsubscribe.
- It counts against your daily and monthly sending limits, because it is a real send.
- It does not change the broadcast's status, its recipient list, or its stats. Send as many tests as you like; the campaign stays a draft until you send it.
curl -X POST https://api.eusend.dev/broadcasts/3fa85f64-5717-4562-b3fc-2c963f66afa6/test \
-H "Authorization: Bearer eu_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"to": ["you@yourdomain.com"]
}'A test-mode key (eu_test_) cannot call this endpoint. "Test" here means a dress rehearsal, not a
sandbox — the message really is delivered, so it needs a live key.
/broadcasts/:id/cancelCancel a scheduled or in-flight broadcast. Emails already sent are not recalled.
The rest of the broadcast surface:
/broadcastsList broadcasts.
/broadcasts/:idGet broadcast details.
/broadcasts/:idUpdate draft / set scheduled_at.