Broadcasts
DM Broadcasts let you send a message to a segmented list of contacts across supported social platforms. Broadcasts are queued and delivered asynchronously in batches.
Agency plan required. Broadcasts use the dm_broadcasts feature flag, which is only available on Agency plan. Requests on lower-tier plans return 403 with error code PLAN_UPGRADE_REQUIRED and message “DM Broadcasts require an Agency plan”.
Base URL
https://api.voxburst.io/v1/broadcastsBroadcast Statuses
These statuses apply to the top-level Broadcast object.
| Status | Description |
|---|---|
DRAFT | Created but not yet sent or scheduled |
SCHEDULED | Scheduled to send at a future time |
SENDING | Currently being delivered to contacts |
SENT | All deliveries enqueued |
PAUSED | Paused mid-delivery |
FAILED | Delivery failed unrecoverably |
Delivery Statuses
These statuses apply to individual BroadcastDelivery records (one per contact). They are distinct from broadcast-level statuses.
| Status | Description |
|---|---|
PENDING | Delivery record created, not yet processed |
DELIVERING | Delivery in progress |
DELIVERED | Message successfully delivered to the contact |
FAILED | Delivery to this contact failed |
READ | Contact has read the message |
SENT is a broadcast-level status only. Individual delivery records never have status === "SENT". Checking delivery.status === "SENT" will never match — use "DELIVERED" instead.
Broadcast Object
{
"id": "bc_example123",
"workspaceId": "wsp_example123",
"name": "May Newsletter",
"messageTemplate": "Hi there! Check out our latest update.",
"platforms": ["TWITTER"],
"socialAccountId": "sa_example456",
"segmentRules": {
"tags": ["newsletter"],
"platforms": ["TWITTER"],
"hasInteraction": true
},
"status": "DRAFT",
"totalContacts": 0,
"deliveredCount": 0,
"failedCount": 0,
"readCount": 0,
"scheduledFor": null,
"sentAt": null,
"createdAt": "2026-05-01T10:00:00Z",
"updatedAt": "2026-05-01T10:00:00Z"
}Broadcast Fields
| Field | Type | Description |
|---|---|---|
id | string | Broadcast ID |
workspaceId | string | Workspace this broadcast belongs to |
name | string | Human-readable name |
messageTemplate | string | Message text (max 1,000 chars) |
platforms | string[] | Platform constants to send on |
socialAccountId | string | null | The specific connected account to send from. null means the server selects an eligible account at send time |
segmentRules | object | Audience filtering rules — see Segment Rules |
status | string | Current broadcast status — see Broadcast Statuses |
totalContacts | integer | Total contacts targeted (populated at send time) |
deliveredCount | integer | Number of deliveries that reached DELIVERED status |
failedCount | integer | Number of deliveries that reached FAILED status |
readCount | integer | Number of deliveries that reached READ status |
scheduledFor | string | null | ISO 8601 scheduled send time |
sentAt | string | null | ISO 8601 timestamp when sending started |
createdAt | string | ISO 8601 creation timestamp |
updatedAt | string | ISO 8601 last-updated timestamp |
Segment Rules
The segmentRules object filters which contacts receive the broadcast. All conditions are ANDed together.
| Field | Type | Description |
|---|---|---|
tags | string[] | Only include contacts with ALL of these tags |
platforms | string[] | Only include contacts on these platforms |
hasInteraction | boolean | If true, only contacts with a recorded interaction (lastSeenAt is not null) |
Only contacts with lastSeenAt set (i.e., contacts who have previously interacted) are eligible for broadcast delivery, regardless of segmentRules. This is enforced server-side as an opt-in safeguard.
List Broadcasts
GET /v1/broadcasts
List broadcasts with optional status filter. Uses page/limit pagination.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: DRAFT, SCHEDULED, SENDING, SENT, PAUSED, FAILED |
page | integer | Page number (default: 1) |
limit | integer | Results per page (default: 20, max: 100) |
curl "https://api.voxburst.io/v1/broadcasts?status=DRAFT&limit=20" \
-H "Authorization: Bearer eyJexample..."Response
{
"broadcasts": [ { "...": "..." } ],
"pagination": {
"page": 1,
"limit": 20,
"total": 5,
"totalPages": 1
}
}Get Broadcast
GET /v1/broadcasts/:id
Retrieve a single broadcast with delivery statistics broken down by delivery status.
curl https://api.voxburst.io/v1/broadcasts/bc_example123 \
-H "Authorization: Bearer eyJexample..."Response
{
"broadcast": { "...": "..." },
"deliveryStats": {
"PENDING": 0,
"DELIVERED": 88,
"FAILED": 2,
"READ": 10
}
}deliveryStats is a map of delivery status to count. Only statuses with at least one delivery record appear as keys. Possible keys: PENDING, DELIVERING, DELIVERED, FAILED, READ.
Create Broadcast
POST /v1/broadcasts
Create a new broadcast in DRAFT status.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable name (1–255 chars) |
messageTemplate | string | Yes | Message text (1–1,000 chars) |
platforms | string[] | Yes | At least one platform constant |
socialAccountId | string | No | Pin this broadcast to a specific connected account. Must belong to this workspace and its platform must be in platforms. |
segmentRules | object | No | Audience filtering — see Segment Rules |
scheduledFor | string | No | ISO 8601 datetime to automatically send |
curl -X POST https://api.voxburst.io/v1/broadcasts \
-H "Authorization: Bearer eyJexample..." \
-H "Content-Type: application/json" \
-d '{
"name": "May Newsletter",
"messageTemplate": "Hi! Check out our latest update.",
"platforms": ["TWITTER"],
"segmentRules": { "tags": ["newsletter"] }
}'Response (201)
{
"broadcast": { "...": "..." }
}Preview Audience Count
POST /v1/broadcasts/preview-count
Returns the number of eligible contacts that would receive a broadcast given a platform, account, and tag selection. Uses the same eligibility logic as /:id/send — the count reflects the opt-in filter (lastSeenAt not null) and any specified segment filters. Useful for showing an estimated audience size before creating or sending a broadcast.
This endpoint uses the same contact eligibility query as POST /v1/broadcasts/:id/send. The returned count matches the contacts actually enqueued when you send, provided the selection inputs are the same.
Request Body
All fields are optional.
| Field | Type | Description |
|---|---|---|
platforms | string[] | Filter to contacts on these platforms |
socialAccountId | string | Filter to contacts reachable via this connected account |
tags | string[] | Filter to contacts with ALL of these tags |
curl -X POST https://api.voxburst.io/v1/broadcasts/preview-count \
-H "Authorization: Bearer eyJexample..." \
-H "Content-Type: application/json" \
-d '{
"platforms": ["TWITTER"],
"tags": ["newsletter"]
}'Response
{
"count": 342
}Update Broadcast
PATCH /v1/broadcasts/:id
Update a broadcast. Only DRAFT or SCHEDULED broadcasts can be updated. Returns 422 with error code BROADCAST_NOT_EDITABLE for any other status.
Request Body
All fields are optional.
| Field | Type | Description |
|---|---|---|
name | string | New name |
messageTemplate | string | New message template |
platforms | string[] | Replacement platform list (at least one element) |
socialAccountId | string | null | New pinned account, or null to clear |
segmentRules | object | Replacement segment rules |
scheduledFor | string | null | New scheduled time, or null to remove |
curl -X PATCH https://api.voxburst.io/v1/broadcasts/bc_example123 \
-H "Authorization: Bearer eyJexample..." \
-H "Content-Type: application/json" \
-d '{ "name": "Updated Newsletter" }'Response
{
"broadcast": { "...": "..." }
}Send Broadcast
POST /v1/broadcasts/:id/send
Enqueue a DRAFT or SCHEDULED broadcast for immediate delivery. Contacts matching the segment rules are resolved and queued for DM delivery.
curl -X POST https://api.voxburst.io/v1/broadcasts/bc_example123/send \
-H "Authorization: Bearer eyJexample..."Response
{
"broadcast": { "status": "SENDING" },
"enqueuedContacts": 102,
"batches": 3
}enqueuedContacts is the number of contacts that were matched by segment rules and enqueued. batches is the number of delivery message batches created (contacts are processed in groups of 50).
Error Responses
| Code | Status | Description |
|---|---|---|
BROADCAST_ALREADY_SENT | 422 | Broadcast is not in a sendable state (DRAFT or SCHEDULED) |
NO_ELIGIBLE_CONTACTS | 422 | No contacts match the segment rules and opt-in requirement |
BROADCAST_CONTACT_LIMIT_EXCEEDED | 422 | Audience exceeds the maximum of 50,000 contacts. Split the audience into smaller segments. |
Retry Broadcast
POST /v1/broadcasts/:id/retry
Retry all FAILED deliveries on a FAILED or SENT broadcast. Resets each failed delivery record to PENDING and re-enqueues them for processing. The broadcast status is set back to SENDING.
curl -X POST https://api.voxburst.io/v1/broadcasts/bc_example123/retry \
-H "Authorization: Bearer eyJexample..."Response
{
"broadcast": { "status": "SENDING" },
"retriedContacts": 14,
"batches": 1
}retriedContacts is the number of failed delivery records that were reset and re-enqueued. batches is the number of delivery message batches created.
Error Responses
| Code | Status | Description |
|---|---|---|
BROADCAST_NOT_RETRYABLE | 422 | Broadcast is not in FAILED or SENT status |
NO_FAILED_DELIVERIES | 422 | No FAILED delivery records exist on this broadcast |
List Deliveries
GET /v1/broadcasts/:id/deliveries
List individual delivery records for a broadcast.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
limit | integer | Results per page (default: 50, max: 100) |
curl "https://api.voxburst.io/v1/broadcasts/bc_example123/deliveries?page=1&limit=50" \
-H "Authorization: Bearer eyJexample..."Response
{
"deliveries": [
{
"id": "del_example789",
"broadcastId": "bc_example123",
"contactId": "cnt_example456",
"platform": "TWITTER",
"status": "DELIVERED",
"sentAt": "2026-05-01T10:05:00Z",
"readAt": null,
"errorCode": null,
"createdAt": "2026-05-01T10:00:00Z",
"updatedAt": "2026-05-01T10:05:00Z",
"contact": {
"id": "cnt_example456",
"displayName": "Alice Example",
"username": "alice",
"avatarUrl": "https://pbs.twimg.com/profile_images/example/photo.jpg",
"platform": "TWITTER"
}
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 102,
"totalPages": 3
}
}Delivery Record Fields
| Field | Type | Description |
|---|---|---|
id | string | Delivery record ID |
broadcastId | string | Parent broadcast ID |
contactId | string | Contact ID |
platform | string | Platform constant |
status | string | Delivery status — see Delivery Statuses |
sentAt | string | null | ISO 8601 timestamp when the message was sent |
readAt | string | null | ISO 8601 timestamp when the contact read the message; null if unread |
errorCode | string | null | Platform-specific error code when status is FAILED; null otherwise |
createdAt | string | ISO 8601 creation timestamp |
updatedAt | string | ISO 8601 last-updated timestamp |
contact.id | string | Contact ID |
contact.displayName | string | Contact display name |
contact.username | string | Contact username |
contact.avatarUrl | string | null | Contact avatar URL |
contact.platform | string | Contact platform constant |
Delete Broadcast
DELETE /v1/broadcasts/:id
Delete a broadcast. Only DRAFT, FAILED, or SENT broadcasts can be deleted. Broadcasts in SENDING, SCHEDULED, or PAUSED status cannot be deleted; cancel or wait for them to finish first. Returns 422 with error code BROADCAST_NOT_DELETABLE if the broadcast is in a non-deletable status.
curl -X DELETE https://api.voxburst.io/v1/broadcasts/bc_example123 \
-H "Authorization: Bearer eyJexample..."Response
{ "success": true }