Send carousel template
An approved template with up to 10 swipeable cards, each with its own media and values.
A carousel has two levels. The template itself has a body — the intro line above the cards — which takes bodyParams like any other template. Each card then carries its own header media, its own body values and its own buttons, supplied through the cards array.
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
| to | string | Required | Recipient number in international format, digits only — 919876543210, not +91 98765 43210. |
| type | string | Required | Must be template. |
| template.name | string | Required | Exact approved template name, from Settings → WhatsApp templates. |
| template.language | string | Required | The locale the template was approved in, e.g. en, en_US, hi. Must match exactly — WhatsApp looks up a template by name and language, so the wrong code fails even when the name is right. |
| template.bodyParams | string[] | optional | Values for the placeholders in the template's own body — the intro text shown abovethe cards. Separate from each card's values. |
| template.cards | object[] | Required | One entry per approved card, in order. cards[0] describes the first card. |
Card object
Every card in a template shares the same approved structure, so if one card needs an image, all of them do.
| Field | Type | Required | Description |
|---|---|---|---|
| headerImage | string | optional | Public https:// URL — required when the card's header was approved as IMAGE. |
| headerVideo | string | optional | Public https:// URL — required for a VIDEO card header. |
| bodyParams | string[] | optional | Values for this card's own {{1}}, {{2}}... placeholders. Numbering restarts on every card. |
| buttonParams | object[] | optional | Same shape as a template-level button parameter, but index counts the buttons on this card from 0. |
Example request
A three-card carousel, each card with an image header and two body placeholders.
curl -X POST 'https://api.bigradar.io/api/public/v1/messages' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"to": "919876543210",
"type": "template",
"template": {
"name": "summer_sale",
"language": "en",
"bodyParams": ["15OFF", "15"],
"cards": [
{
"headerImage": "https://cdn.example.com/card-1.jpg",
"bodyParams": ["15OFF", "15"]
},
{
"headerImage": "https://cdn.example.com/card-2.jpg",
"bodyParams": ["15OFF", "15"]
},
{
"headerImage": "https://cdn.example.com/card-3.jpg",
"bodyParams": ["15OFF", "15"]
}
]
}
}'Cards with buttons
Card buttons follow the same rules as template-level ones, except index is scoped to the card — the first button of card 2 is index: 0, not a running count across the carousel. This is what makes each card link to a different product.
curl -X POST 'https://api.bigradar.io/api/public/v1/messages' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"to": "919876543210",
"type": "template",
"template": {
"name": "summer_sale",
"language": "en",
"bodyParams": ["15OFF", "15"],
"cards": [
{
"headerImage": "https://cdn.example.com/card-1.jpg",
"bodyParams": ["15OFF", "15"],
"buttonParams": [
{ "index": 0, "text": "sku-1001" },
{ "index": 1, "payload": "add_to_cart_1001" }
]
},
{
"headerImage": "https://cdn.example.com/card-2.jpg",
"bodyParams": ["20OFF", "20"],
"buttonParams": [
{ "index": 0, "text": "sku-1002" },
{ "index": 1, "payload": "add_to_cart_1002" }
]
}
]
}
}'Response · 200
{
"success": true,
"message": "Template message sent successfully",
"data": {
"message_id": "wamid.HBgM...",
"conversation_id": "a1b2c3d4-...",
"to": "919876543210",
"status": "queued",
"timestamp": "2026-06-25T12:30:45Z"
}
}Errors
Card-level failures name the card in field, so you can map an error straight back to the entry that caused it.
| Code | Status | Means |
|---|---|---|
| invalid_card_count | 400 | You sent more or fewer cards than the template was approved with. Every card needs an entry. |
| missing_header_media | 400 | A card is missing its image or video. The field names which one, e.g. template.cards[1].headerImage. |
| missing_template_params | 400 | A card has fewer body values than it has placeholders. |
| unexpected_cards | 400 | You sent cards for a template that has no carousel. |
| unsupported_card_header | 400 | A card header is neither IMAGE nor VIDEO — not sendable from the API. |
| template_not_found | 404 | No template with that name on this workspace. Check spelling and case. |
| template_not_approved | 409 | The template exists but Meta has not approved it yet. |
| whatsapp_not_connected | 409 | No WhatsApp Business account is connected. Connect one in the dashboard. |
Check what each card needs
GET /templates returns a cards array for carousel templates, describing each card in the same order you must send them.
{
"name": "summer_sale",
"status": "APPROVED",
"bodyParamCount": 2,
"sendable": true,
"cards": [
{
"cardIndex": 0,
"headerFormat": "IMAGE",
"headerField": "headerImage",
"bodyParamCount": 2,
"buttons": []
}
]
}