Broadcasts
Send a campaign to all subscribed contacts, a segment, or the subscribers of a topic, now or at a scheduled time.
A broadcast is one message sent to many contacts. You create it as a draft, then send it now or schedule it. Broadcasts need a plan that includes them (402 BROADCASTS_NOT_ALLOWED otherwise).
All endpoints on this page accept an email API key (or a Helipod API key with the Email API enabled) and act on the key's project.
Audience
A broadcast goes to exactly one audience:
segmentIdset: the members of that segment at its last calculation.- otherwise
topicIdset: contacts subscribed to that topic. - neither: every contact of the project.
When sending, these contacts are skipped (they appear in the recipient list with status: "skipped" and a skipReason):
skipReason | Why |
|---|---|
status_unsubscribed, status_bounced | The contact is not subscribed. |
suppressed | The address is on the project's suppression list (including unsubscribes). |
role_address | A shared role mailbox such as info@, admin@ or support@. Still reachable by transactional sends. |
no_unsubscribe_link | An unsubscribe link could not be created; the recipient is never mailed without one. Re-send to retry. |
Personalisation
subject and body can use {{tokens}}: {{email}}, {{firstName}}, {{lastName}}, and any custom property of the contact, for example {{city}}. A token without a value becomes an empty string.
Every broadcast email gets an unsubscribe footer appended to the body and a one-click List-Unsubscribe header. Recipients who use them are suppressed for future broadcasts.
Safety checks
To protect your sending reputation, a broadcast can stop or pause on its own:
- List check. When most of the audience has never received a broadcast from this project, a random sample is sent first and the rest is held. If the sample bounces too much, the broadcast stops with status
failedand astopReason; otherwise the held recipients are released automatically. The broadcast'slistCheckshows{ status, sampleSize }while this runs. - Bounce stop. If more than 5% of what the broadcast has sent bounces (after at least 50 sends), it stops.
- Project pause. If the project is suspended for its bounce or complaint rate, sending stops.
A stopped or failed broadcast can be sent again: recipients who already received it are never sent a second copy.
Broadcast object
Prop
Type
The body is not part of the object returned by the API; keep your own copy if you need it.
List broadcasts
/broadcastscurl https://mail.helipod.io/api/email/broadcasts \
-H "Authorization: Bearer your_email_api_key"Create a broadcast
/broadcastsProp
Type
curl -X POST https://mail.helipod.io/api/email/broadcasts \
-H "Authorization: Bearer your_email_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "October newsletter",
"from": "Acme <[email protected]>",
"subject": "What is new in October, {{firstName}}",
"body": "<h1>Hi {{firstName}}</h1><p>Here is what we shipped this month.</p>",
"segmentId": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b"
}'Response 201: the broadcast object with status draft.
Errors: 402 BROADCASTS_NOT_ALLOWED, 403 DOMAIN_NOT_FOUND, 403 DOMAIN_NOT_VERIFIED, 404 SEGMENT_NOT_FOUND, 404 TOPIC_NOT_FOUND.
Get a broadcast
/broadcasts/{id}curl https://mail.helipod.io/api/email/broadcasts/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d \
-H "Authorization: Bearer your_email_api_key"Returns the broadcast object, or 404 BROADCAST_NOT_FOUND.
Update a broadcast
/broadcasts/{id}Prop
Type
curl -X PATCH https://mail.helipod.io/api/email/broadcasts/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d \
-H "Authorization: Bearer your_email_api_key" \
-H "Content-Type: application/json" \
-d '{"subject":"October at Acme, {{firstName}}"}'Returns the updated object. A broadcast that is not draft or scheduled returns 409 BROADCAST_LOCKED.
Send a broadcast
/broadcasts/{id}/sendcharges your walletAllowed when the status is draft, scheduled, cancelled or failed. Quota is reserved for every recipient at this point, the same way as for single sends.
curl -X POST https://mail.helipod.io/api/email/broadcasts/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/send \
-H "Authorization: Bearer your_email_api_key"Response 202:
{
"success": true,
"data": {
"jobId": "eml_5f6a7b8c9d0e1f2a3b4c",
"totalRecipients": 1240,
"skipped": 18,
"alreadySent": 0,
"listCheck": { "status": "sampling", "sampleSize": 200 }
}
}listCheck is present only when a list check started. When every deliverable recipient already received the broadcast, it is marked sent and the response has jobId: null.
Errors: 400 NO_RECIPIENTS (nobody left to send to), 409 BROADCAST_LOCKED (wrong status, or a send is already starting), 402 quota and plan errors, 403 sending-paused errors, 503 SEND_UNAVAILABLE (try again shortly).
Schedule a broadcast
/broadcasts/{id}/scheduleProp
Type
curl -X POST https://mail.helipod.io/api/email/broadcasts/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/schedule \
-H "Authorization: Bearer your_email_api_key" \
-H "Content-Type: application/json" \
-d '{"scheduledAt":"2026-10-20T02:00:00Z"}'{ "success": true, "data": { "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d", "status": "scheduled", "scheduledAt": "2026-10-20T02:00:00.000Z" } }Calling it again on a scheduled broadcast moves the time. Errors: 400 INVALID_SCHEDULE (not a valid future date), 409 BROADCAST_LOCKED.
Cancel a broadcast
/broadcasts/{id}/cancelcurl -X POST https://mail.helipod.io/api/email/broadcasts/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/cancel \
-H "Authorization: Bearer your_email_api_key"{ "success": true, "data": { "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d", "status": "cancelled" } }A sending broadcast stops before its next recipients. Sending it again later resumes with the recipients who have not received it.
List recipients
/broadcasts/{id}/recipients| Query | Type | Notes |
|---|---|---|
status | string | For example queued, held, sent, delivered, bounced, complained, skipped, failed. |
limit | number | 1 to 500, default 100. |
curl "https://mail.helipod.io/api/email/broadcasts/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/recipients?status=skipped" \
-H "Authorization: Bearer your_email_api_key"{
"success": true,
"data": [
{
"id": "1f2e3d4c-5b6a-4978-8a6b-5c4d3e2f1a0b",
"contactId": "0b1c2d3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
"email": "[email protected]",
"status": "skipped",
"skipReason": "role_address",
"sentAt": null,
"deliveredAt": null
}
]
}This list is not paginated: it returns at most limit rows, oldest first.
Delete a broadcast
/broadcasts/{id}curl -X DELETE https://mail.helipod.io/api/email/broadcasts/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d \
-H "Authorization: Bearer your_email_api_key"{ "success": true, "data": { "deleted": true } }A sending broadcast returns 409 BROADCAST_SENDING; cancel it first.