HelipodDocs

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:

  • segmentId set: the members of that segment at its last calculation.
  • otherwise topicId set: 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):

skipReasonWhy
status_unsubscribed, status_bouncedThe contact is not subscribed.
suppressedThe address is on the project's suppression list (including unsubscribes).
role_addressA shared role mailbox such as info@, admin@ or support@. Still reachable by transactional sends.
no_unsubscribe_linkAn 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 failed and a stopReason; otherwise the held recipients are released automatically. The broadcast's listCheck shows { 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

GET/broadcasts
The 100 most recent broadcasts, newest first.
curl https://mail.helipod.io/api/email/broadcasts \
  -H "Authorization: Bearer your_email_api_key"

Create a broadcast

POST/broadcasts
Create a draft.

Prop

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

GET/broadcasts/{id}
Read one broadcast with its counters.
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

PATCH/broadcasts/{id}
Edit a draft or scheduled broadcast.

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

POST/broadcasts/{id}/sendcharges your wallet
Build the recipient list and start sending now.

Allowed 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

POST/broadcasts/{id}/schedule
Send automatically at a future time.

Prop

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

POST/broadcasts/{id}/cancel
Cancel a draft, scheduled or sending broadcast.
curl -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

GET/broadcasts/{id}/recipients
Per-recipient status of a broadcast.
QueryTypeNotes
statusstringFor example queued, held, sent, delivered, bounced, complained, skipped, failed.
limitnumber1 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

DELETE/broadcasts/{id}
Delete a broadcast that is not currently sending.
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.

On this page