PelekaPeleka Developers
Guides

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: draftscheduled or sendingsent. 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.

On this page