Broadcast endpoints
Configure triggered per-status follow-ups on a campaign, and create and run manual bulk broadcasts. See the Broadcasts guide for the concepts; this page is the API reference.
All broadcast endpoints require an active paid session and the broadcasts
feature on your tariff. Enabling a triggered block, or starting a manual
broadcast, on a plan without the feature returns error: broadcasts.
Triggered config
Per-campaign, per-status message blocks. Five statuses, one block each:
0 wait · 1 hold · 2 approve · 3 cancel · 4 trash.
Get a campaign’s blocks
GET /api/camp/broadcast.json
Returns all five blocks. Statuses with no block yet come back as the zero block
(on: 0).
| Parameter | Description |
|---|---|
id | Campaign id |
{
"status": "ok",
"data": [
{ "status": 0, "on": 1, "delay": 1800,
"text": "Welcome! Tap below to continue 👇",
"media": "", "media_type": 0,
"button": "Open", "link": "https://example.com/l?click={click}" },
{ "status": 1, "on": 0, "delay": 0, "text": "", "media": "", "media_type": 0, "button": "", "link": "" },
{ "status": 2, "on": 0, "delay": 0, "text": "", "media": "", "media_type": 0, "button": "", "link": "" },
{ "status": 3, "on": 0, "delay": 0, "text": "", "media": "", "media_type": 0, "button": "", "link": "" },
{ "status": 4, "on": 0, "delay": 0, "text": "", "media": "", "media_type": 0, "button": "", "link": "" }
]
}delay is in seconds after the lead enters the status. media_type is
0 none, 1 photo, 2 video.
Save one block
POST /api/camp/broadcast.json
Upserts the block for one status.
| Parameter | Required | Description |
|---|---|---|
id | ✓ | Campaign id |
status | ✓ | Lead status 0–4 |
on | 1 to enable, 0 to disable | |
delay | Seconds after entering the status before sending | |
text | Message text (Telegram Markdown) | |
media | Media ref from media/upload; "" for none | |
media_type | 1 photo, 2 video (from the upload response) | |
button | Button caption | |
link | Button URL (may contain macros) |
{ "status": "ok" }Enabling a block (on=1) requires the broadcasts feature → error: broadcasts
otherwise. Disabling or editing an already-off block is always allowed (so a
downgraded account can still turn one off).
Send a block to myself
POST /api/camp/btest.json
Delivers a “send to myself” preview of one saved status block to the logged-in user via the service bot (text + button only — media isn’t included).
| Parameter | Required | Description |
|---|---|---|
id | ✓ | Campaign id |
status | ✓ | Lead status 0–4 |
{ "status": "ok" }Manual broadcasts
A broadcast is created as a draft, edited, then started. Statuses:
0 draft · 1 running · 2 done · 3 cancelled · 4 paused.
List broadcasts
GET /api/broadcast/list.json
Returns the user’s broadcasts, newest first, with live counters.
{
"status": "ok",
"data": [
{
"id": 5,
"name": "May win-back",
"status": 1,
"statuses": 24,
"campaigns": [],
"total": 1240,
"sent": 800,
"queued": 440,
"failed": 0,
"started": 1717500000,
"created": 1717490000
}
]
}statuses is a bitmask of target lead statuses (bit 0 wait … bit 4 trash);
24 = bits 3+4 = cancel + trash. campaigns is the campaign-scope list (empty =
all). Times are unix seconds (0 = unset).
Daily-limit gauge
GET /api/broadcast/quota.json
{ "status": "ok", "data": { "cap": 500, "used": 120, "queued": 440 } }| Field | Meaning |
|---|---|
cap | Today’s manual-send cap from your tariff; 0 = unlimited |
used | Manual messages sent today (UTC day) |
queued | Messages (both modes) currently waiting in the send queue |
Get one broadcast
GET /api/broadcast/get.json
Returns the full broadcast including its campaign scope and filters. For a
non-running broadcast it also recomputes total (the live audience) and
remaining (the top-up size — leads not yet reached).
| Parameter | Description |
|---|---|
id | Broadcast id |
{
"status": "ok",
"data": {
"id": 5, "name": "May win-back", "status": 2, "statuses": 24,
"campaigns": [12, 18],
"created_from": 0, "created_to": 0,
"status_from": 1714521600, "status_to": 1717113600,
"text": "We miss you — here's 20% off 🎁",
"media": "", "media_type": 0,
"button": "Claim", "link": "https://example.com/back?click={click}",
"total": 1300, "remaining": 60,
"queued": 0, "sent": 1240, "failed": 0,
"started": 1717500000, "created": 1717490000
}
}Create a draft
POST /api/broadcast/add.json
| Parameter | Description |
|---|---|
name | Optional name |
{ "status": "ok", "data": { "id": 5 } }Edit a broadcast
POST /api/broadcast/edit.json
Replaces the broadcast’s fields and campaign scope. Allowed in any state — the body is resolved at send time, so an edit to a running broadcast affects its still-pending messages.
| Parameter | Description |
|---|---|
id | Broadcast id |
name | Display name |
statuses | Target lead-status bitmask (bit 0 wait … bit 4 trash) |
campaigns | Comma-separated campaign ids; empty = all your campaigns |
created_from / created_to | Filter on lead-created time (unix; 0 = unbounded) |
status_from / status_to | Filter on lead status-changed time (unix; 0 = unbounded) |
text | Message text (Telegram Markdown) |
media / media_type | Media ref from media/upload and its type |
button / link | Button caption + URL (macros allowed) |
{ "status": "ok" }Start (always a top-up)
POST /api/broadcast/start.json
Enqueues the audience and flips the broadcast to running. It is always a
top-up: only leads the broadcast hasn’t already reached are enqueued, so
re-running a done/cancelled broadcast sends just to the new leads. Allowed
from draft/done/cancelled; a running/paused broadcast returns
error: state.
| Parameter | Description |
|---|---|
id | Broadcast id |
{ "status": "ok", "data": { "queued": 60 } }queued is the number of messages enqueued. 0 means there was nothing new to
reach, and the broadcast’s status is left unchanged.
Pause / Resume
POST /api/broadcast/pause.json — running → paused; pending messages are parked
and kept.
POST /api/broadcast/resume.json — paused → running; parked messages become due
again and sending continues exactly where it stopped.
| Parameter | Description |
|---|---|
id | Broadcast id |
{ "status": "ok" }Pausing anything that isn’t running returns error: state.
Stop (cancel)
POST /api/broadcast/cancel.json
running/paused → cancelled; drops the remaining queued messages. The
already-reached set is kept, so a later top-up Start won’t re-message them.
| Parameter | Description |
|---|---|
id | Broadcast id |
{ "status": "ok" }Reset
POST /api/broadcast/reset.json
Clears the reached-leads set and counters and returns a done/cancelled
broadcast to draft, keeping its name, filters, and body. The next Start then
re-sends to the whole audience.
| Parameter | Description |
|---|---|
id | Broadcast id |
{ "status": "ok" }Delete
POST /api/broadcast/del.json
Deletes a non-running broadcast and its scope, queue, and reached rows. A running broadcast must be stopped first.
| Parameter | Description |
|---|---|
id | Broadcast id |
{ "status": "ok" }Send to myself
POST /api/broadcast/test.json
Delivers a preview of the broadcast body to the logged-in user via the service bot (text + button only — media isn’t included).
| Parameter | Description |
|---|---|
id | Broadcast id |
{ "status": "ok" }Errors
| Error | Meaning |
|---|---|
broadcasts | The broadcasts feature isn’t on your tariff — upgrade |
state | The action isn’t valid for the broadcast’s current status (e.g. starting a running one) |
access | The broadcast or campaign isn’t yours |
func | A required parameter is missing or invalid |
unpaid | Your subscription is inactive |