Product Carousels
A product card carousel shows products from your Meta catalog as swipeable cards. Each card’s image, title, and price come from the catalog — you send product IDs instead of card content, and you choose which products to show at send time.
POST /v1/whatsapp/sendTwo fields make a send a product carousel:
| Field | Type | Required | Description |
|---|---|---|---|
catalog_id | string | ✓ | The Meta catalog the products belong to. A top-level field, not per card. |
product_retailer_id | string | ✓ | Set on each card in variables.cards — the retailer ID of the product shown on that card. Send 2–10 of them, at consecutive positions starting at "1". |
Example
cURL
curl -X POST https://api.bahasha.app/v1/whatsapp/send \
-H "Authorization: Bearer bh_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"to": "+254700000000",
"phone_number_id": "123456789",
"template_name": "succulents_carousel",
"language_code": "en_US",
"catalog_id": "194836987003835",
"variables": {
"body": { "name": "Pablo" },
"cards": {
"1": { "product_retailer_id": "vrpj01fvwp", "buttons": { "1": "summer sale" } },
"2": { "product_retailer_id": "va2l5ioeat" },
"3": { "product_retailer_id": "sqpjv0mgde" }
}
}
}'The response is the standard send response — see Send a Message.
How many cards get sent
Card count is a send-time decision. Unlike a media carousel, a product carousel template approved with 2 cards can send anywhere from 2 to 10 cards — one per position in variables.cards. Cards beyond the approved ones reuse the first card’s structure, which WhatsApp requires to be identical across cards anyway.
That means the same approved template can show two products in one send and eight in the next, with no template edit and no re-approval.
Because the card at each position is the product you named there, positions must run consecutively from "1" — {"1": …, "2": …, "3": …}. A gap would leave a card with no product, so it is rejected rather than silently shifting the rest.
Requirements and errors
All of these return 400:
| Condition | Message |
|---|---|
| Fewer than 2 products | Select at least 2 products to show on the carousel cards. |
| More than 10 products | A carousel can show at most 10 products. |
catalog_id missing | catalog_id is required when sending a product card carousel template. Send it at the top level of the request, not inside variables. |
| A gap in the card positions | Carousel card positions must start at 1 and run consecutively (1, 2, 3, …). |
| Only some cards name a product | Every carousel card must have a product_retailer_id, or none of them. |
| A position that is not a whole number ≥ 1 | Carousel card positions must be whole numbers starting at 1. Received "…". |
Every product_retailer_id must exist in the catalog named by catalog_id; a single send cannot mix catalogs.
Card variables and buttons
Product cards can carry variables just like media cards — set body and buttons on the same card alongside product_retailer_id. The keys, the card positions, and the URL button rules are all identical. See Carousels.
Media does not apply
Product carousels ignore media_url and media_id on the card headers — each card’s image comes from the product in your catalog. Update the product in Meta Commerce Manager to change what a card shows.
What is not supported yet
Product carousels are the only catalog-backed template you can send through this API. Multi-Product Message (MPM), Single-Product Message (SPM), and catalog templates are not supported. Send those from the Bahasha Dashboard .