Broadcast API - V2
The V2 Broadcasts API uses a payload-variable model. You supply a tabular payload (like a CSV) where each row is a recipient, and the template object maps column names to template variable slots via payload_variable fields with optional fallback values.
See the authentication page for how to obtain a bearer token.
Create a Broadcast
POST https://api.cuedesk.com/v2/broadcasts
Authorization: Bearer <token>
Content-Type: application/json
Examples
- Standard Template
- Carousel Template
- Using a Contact List
{
"name": "Holiday Sale",
"from": "447576209857",
"scheduled_at": "2024-06-15T10:00:00Z",
"valid_until": "2024-12-31T23:59:59Z",
"client_unique_identifier": "abe120b4-048c-4d00-9c1a-0b01d34c583c",
"template": {
"name": "holiday_sale_template",
"locale": "en",
"header": {
"type": "image",
"payload_variable": "header_image_url",
"fallback": "https://www.example.com/default-sale.jpg"
},
"body": {
"payload_variables": ["first_name", "discount_code", "expiry_date"],
"fallbacks": ["Customer", "SALE2024", "31 Dec"]
},
"buttons": [
{
"index": 0,
"type": "URL",
"payload_variable": "tracking_url_suffix",
"fallback": "default"
}
]
},
"payload": [
{
"identifier": "447592850122",
"client_reference": "order-abc-123",
"first_name": "Alex",
"discount_code": "ALEX20",
"expiry_date": "25 Dec",
"header_image_url": "https://www.example.com/alex-promo.jpg",
"tracking_url_suffix": "alex-campaign"
},
{
"identifier": "27827134468",
"client_reference": "order-def-456",
"first_name": "Jordan",
"discount_code": "JORDAN15",
"expiry_date": "30 Dec"
}
]
}
In this example, the second recipient does not have header_image_url or tracking_url_suffix in their payload row, so the fallback values from the template definition will be used instead.
{
"name": "Product Showcase",
"from": "447576209857",
"scheduled_at": "2024-06-15T10:00:00Z",
"template": {
"name": "product_carousel_template",
"locale": "en",
"body": {
"payload_variables": ["first_name"],
"fallbacks": ["Customer"]
},
"cards": [
{
"index": 0,
"header": {
"type": "image",
"payload_variable": "card_1_image",
"fallback": "https://www.example.com/product1.jpg"
},
"body": {
"payload_variables": ["card_1_product_name", "card_1_price"],
"fallbacks": ["Product 1", "$99.00"]
},
"buttons": [
{
"index": 0,
"type": "URL",
"payload_variable": "card_1_url_suffix",
"fallback": "product-1"
}
]
},
{
"index": 1,
"header": {
"type": "image",
"payload_variable": "card_2_image",
"fallback": "https://www.example.com/product2.jpg"
},
"body": {
"payload_variables": ["card_2_product_name", "card_2_price"],
"fallbacks": ["Product 2", "$79.00"]
},
"buttons": [
{
"index": 0,
"type": "URL",
"payload_variable": "card_2_url_suffix",
"fallback": "product-2"
}
]
}
]
},
"payload": [
{
"identifier": "447592850122",
"first_name": "Alex",
"card_1_product_name": "Running Shoes",
"card_1_price": "$99.00",
"card_1_url_suffix": "running-shoes-123",
"card_2_product_name": "Casual Sneakers",
"card_2_price": "$79.00",
"card_2_url_suffix": "casual-sneakers-456"
},
{
"identifier": "27827134468",
"first_name": "Jordan",
"card_1_product_name": "Trail Boots",
"card_1_price": "$120.00",
"card_1_url_suffix": "trail-boots-789",
"card_2_product_name": "Slip-Ons",
"card_2_price": "$49.00",
"card_2_url_suffix": "slip-ons-012"
}
]
}
Instead of providing recipients inline via payload, you can reference a pre-uploaded contact list by UUID:
{
"name": "Monthly Newsletter",
"from": "447576209857",
"template": {
"name": "monthly_newsletter",
"locale": "en",
"body": {
"payload_variables": ["first_name"],
"fallbacks": ["Subscriber"]
}
},
"contact_list_uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}
When using contact_list_uuid, the payload field should be omitted. The contact list provides the recipient identifiers and any payload variables associated with each contact.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Name of the broadcast (for your reference) |
from | string | Yes | Phone number or channel identifier used as the sender |
scheduled_at | datetime | No | ISO 8601 timestamp for when to send. Sends immediately if omitted |
valid_until | datetime | No | ISO 8601 timestamp after which undelivered messages expire. No expiry if omitted |
template | object | Yes | Template definition with payload variable mappings |
payload | array | No | Array of recipient rows. Each row is a key-value map |
contact_list_uuid | UUID | No | UUID of a pre-uploaded contact list. Alternative to payload |
client_unique_identifier | string | No | Idempotency key to prevent duplicate broadcasts |
Template Object
The template object defines which template to use and how payload columns map to template variable slots.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Name of the approved WhatsApp template |
locale | string | Yes | Language code (e.g. en, pt_BR) |
header | object | No | Header variable mapping |
body | object | No | Body variable mappings |
buttons | array | No | Button variable mappings |
cards | array | No | Card definitions for carousel templates |
Header
| Field | Type | Required | Description |
|---|---|---|---|
type | string | No | Header media type: image, video, document, or text |
payload_variable | string | No | Payload column name containing the header value (URL for media, text for text headers) |
fallback | string | No | Default value used when payload_variable is missing from a recipient's row |
filename | string | No | Filename for document type headers |
Body
| Field | Type | Required | Description |
|---|---|---|---|
payload_variables | array[string] | No | Ordered list of payload column names. Position 0 maps to {{1}}, position 1 maps to {{2}}, etc. |
fallbacks | array[string] | No | Positional fallback values. Must be the same length as payload_variables if provided |
Buttons
| Field | Type | Required | Description |
|---|---|---|---|
index | integer | Yes | Zero-based position of the button in the template |
type | string | No | Button type: URL, OTP, QUICK_REPLY |
payload_variable | string | No | Payload column name for the button's dynamic value |
fallback | string | No | Default value when payload_variable is missing |
Cards
| Field | Type | Required | Description |
|---|---|---|---|
index | integer | Yes | Zero-based card position. Fully static cards can be omitted |
header | object | No | Card-level header (same structure as above) |
body | object | No | Card-level body (same structure as above) |
buttons | array | No | Card-level buttons (same structure as above) |
Payload
The payload is an array of objects where each object represents one recipient. Every row must contain an identifier key with the recipient's phone number. All other keys are custom column names referenced by payload_variable in the template definition.
| Key | Type | Required | Description |
|---|---|---|---|
identifier | string | Yes | Recipient phone number with country code (no leading +) |
client_reference | string | No | Custom reference ID for this recipient, returned in webhook status updates (max 255 chars) |
| (custom keys) | string | No | Values for payload variables referenced in the template |
If a recipient row is missing a column referenced by a payload_variable and no fallback is defined, a warning will be generated for that recipient.
Response
202 Accepted
{
"broadcast": {
"uuid": "d3b3b3b3-3b3b-3b3b-3b3b-3b3b3b3b3b3b",
"name": "Holiday Sale",
"scheduled_at": "2024-06-15T10:00:00Z",
"status": "scheduled",
"created_at": "2024-06-01T12:00:00Z",
"recipients": 19750
},
"warnings": [
{
"identifier": "6563546436",
"errors": [
"Missing payload variable 'discount_code' with no fallback defined"
]
}
]
}
| Field | Type | Description |
|---|---|---|
broadcast.uuid | UUID | Unique identifier of the created broadcast |
broadcast.name | string | Broadcast name |
broadcast.scheduled_at | datetime | Scheduled send time (null if immediate) |
broadcast.status | string | Broadcast status: scheduled, processing, completed, cancelled |
broadcast.created_at | datetime | When the broadcast was created |
broadcast.recipients | integer | Total number of valid recipients |
warnings | array | Per-recipient warnings for validation issues |
warnings[].identifier | string | Recipient phone number |
warnings[].errors | array[string] | Warning messages for this recipient |
Error Responses
400 Bad Request:
{
"message": "Broadcast could not be created",
"details": "Template 'holiday_sale_template' not found or not approved"
}
403 Forbidden:
{
"message": "Forbidden",
"details": "Channel does not belong to your workspace"
}
422 Unprocessable Entity:
{
"error": {
"message": "Validation failed",
"details": "Template parameter count mismatch",
"violations": [
{
"field": "template.body.payload_variables",
"rule": "PARAMETER_COUNT_MISMATCH",
"message": "Template expects 3 body parameters but 2 were provided"
}
]
}
}