Sending broadcasts programmatically
Create a broadcast, target an audience, and send or schedule it, the same lifecycle the dashboard's composer uses.
A broadcast goes through the same states whether you build it in the dashboard or through the API: draft → scheduled or sending → sent. Creating one via the API drops it in draft, same as opening a blank composer. Nothing goes out until you explicitly send or schedule it.
Create a draft
curl -X POST https://api.peleka.io/api/v1/broadcasts \
-H "X-API-Key: pel_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "August product update",
"subject": "What'\''s new this month",
"fromName": "Peleka Team",
"fromEmail": "[email protected]",
"audienceType": "all"
}'name is the only required field; it's the internal label, not what subscribers see. Leave subject off for now if you want; you can patch it in later. The response comes back with status: "draft" and an id you'll use for every following call.
Content
A broadcast's body lives in its blocks array, the same structure the visual email builder writes to when you drag blocks around in the dashboard. There's no simplified "just send me some HTML" field; blocks are how Peleka assembles and themes the email. If you haven't looked at the shape of a real blocks array yet, build one broadcast by hand in the dashboard first, then GET /broadcasts/{id} to see exactly what it produced. That's the fastest way to learn the format, faster than guessing from the schema alone.
Targeting an audience
audienceType is all, segments, or tags. For anything narrower than your whole list, pair it with audienceFilter:
{
"audienceType": "segments",
"audienceFilter": {
"segmentIds": ["a1b2c3d4-..."],
"excludeSegmentIds": []
}
}Or by tag:
{
"audienceType": "tags",
"audienceFilter": {
"tagIds": ["e5f6a7b8-..."]
}
}If you don't already have the segment or tag ID, GET /segments and GET /tags list what exists in the workspace.
Sending
Once the draft looks right, send it immediately:
curl -X POST https://api.peleka.io/api/v1/broadcasts/{id}/send \
-H "X-API-Key: pel_live_..."This queues the send; it returns right away with a confirmation message, not a completion. Poll GET /broadcasts/{id}/stats afterward to watch delivery and open counts come in, or subscribe to the relevant webhook events instead of polling.
Scheduling
To send later instead of now, schedule it rather than calling /send:
curl -X POST https://api.peleka.io/api/v1/broadcasts/{id}/schedule \
-H "X-API-Key: pel_live_..." \
-H "Content-Type: application/json" \
-d '{ "scheduledAt": "2026-08-20T14:00:00Z" }'scheduledAt is UTC by default (timezoneMode: "fixed"). If you'd rather send at a fixed local time per subscriber (9am in each contact's own timezone, say), set timezoneMode to subscriber and pass localTime/localDate instead of a single UTC instant. A scheduled broadcast can still be pulled back with POST /broadcasts/{id}/cancel, which drops it back to draft, right up until it actually starts sending.
Before you automate a real send
Send yourself a test first — POST /broadcasts/{id}/test delivers to a specific address without touching your real audience or affecting stats. Worth wiring into any pipeline that creates and sends broadcasts unattended, so a bad template doesn't reach your whole list before anyone notices.