Broadcast (mass delivery)
Send a message to all subscribers or a segment.
POST /v1/broadcast
Creates a broadcast job. Messages are sent through a queue.
text string requiredMessage text
format string Text format: plain (default), markdown, or html
media object Media object: {type, url}. Types: photo, video, document
buttons array Array of button rows: [[{text, url}]] or [[{text, callback_data}]]
permission string Filter by permission
tags array Filter by tags: ["vip", "beta"]
tags_all array AND filter: subscriber must have ALL listed tags
tags_any array OR filter: subscriber must have at least one of the tags
exclude_tags array Exclude subscribers with any of these tags
exclude_permissions array Exclude subscribers with any of these permissions
messages_per_minute number Rate limit (messages/min). Defaults to max bot quota
dry_run boolean true — preview without sending: returns audience, credits and a sample message
Response
Preview (dry-run)
With dry_run: true no broadcast is created — you get an audience/credit estimate and a sample rendered message. Handy to verify filters before sending.
Response
GET /v1/broadcast/:job_id
Get broadcast status.
Response fields: status (pending/processing/completed/failed/cancelled), total, sent, failed, skipped.
DELETE /v1/broadcast/:job_id
Stops a broadcast. Already sent messages stay, no new ones go out. The worker notices the cancellation on its next iteration; on finish it fires the broadcast.cancelled webhook.
GET /v1/broadcast/:job_id/deliveries
Detailed per-subscriber delivery report. Params: status (success/failed), limit (up to 500), cursor (for pagination — the next_cursor value from the previous response).
Frequency cap
Project-level cap on marketing messages per subscriber (per day / per week). Configured in the dashboard on the Broadcasts tab. Off by default. Subscribers over the limit are skipped during a broadcast (skipped field in the status).