What WhatsApp Catalogs Are
A catalog is an inventory of products or services that you upload to Meta and connect to your WhatsApp account hierarchy. Each item has details such as name, description, price, images, and availability. Items can be products (physical or digital goods with a price, SKU, and images) or services (appointments, consultations, subscriptions).
Once a catalog is connected, you can share its items in chat. Customers browse products, view details, add items to a cart, and send you an order without leaving WhatsApp. Catalog commerce has four stages:
- Inventory upload. Upload product data to Meta through the Commerce API or Meta Commerce Manager.
- Commerce configuration. Turn the cart and the catalog storefront on or off per business phone number (see Commerce Settings).
- Product sharing. Send catalog, single-product, multi-product, or carousel messages (see Product Message Formats).
- Customer responses. Questions about a product and submitted carts arrive as
messageswebhooks (see Orders and Product Inquiries).
Catalog Setup and Policies
If the business already has a Meta catalog, connect it to the WhatsApp account hierarchy instead of creating a new one. Otherwise create a catalog with the Commerce API or in Meta Commerce Manager. You can connect one catalog per WhatsApp account hierarchy, and that catalog serves every business phone number in the hierarchy.
- WhatsApp automatically reviews items added to a connected catalog. A policy-violating item is flagged and the business is pointed to the WhatsApp Commerce Policies. Appeal disapproved items in Meta Commerce Manager.
- WhatsApp users can report a product they received in a message, which triggers a review of that product.
- Never send messages that violate the Commerce and Business Policies. Single- and multi-product messages also follow the existing enforcement and data-sharing rules for product catalogs.
- Businesses based in India must comply with India's online selling laws. The Business Compliance API returns the compliance details for a business phone number.
Commerce Settings
The shopping cart and the catalog storefront are set per business phone number. By default the cart is enabled and the storefront icon is hidden for every number in a WhatsApp account hierarchy.
| Setting | Request | Effect |
|---|---|---|
| Cart | POST /<PHONE_NUMBER_ID>/whatsapp_commerce_settings?is_cart_enabled=true | Default true. When false, customers still see products and details, but no cart buttons appear in any view. |
| Catalog | POST /<PHONE_NUMBER_ID>/whatsapp_commerce_settings?is_catalog_visible=true | Default false. When true, the storefront icon and catalog buttons appear in chat and business profile views. |
| Read both | GET /<PHONE_NUMBER_ID>/whatsapp_commerce_settings | Returns data: [{ "is_cart_enabled": true, "is_catalog_visible": true, "id": "<ID>" }] |
Both POST calls return { "success": true }. When the catalog is disabled, the storefront icon, catalog buttons, and the catalog preview on the business profile disappear, and wa.me/c/ links and the View catalog button in catalog link messages show an Invalid catalog link warning when tapped.
Shopping Cart and Product Updates
When the cart is enabled, customers can add several products while browsing and send them to you as one order.
- There is one cart per chat thread between you and a customer, and it lives on one device. Carts do not sync across a customer's linked devices, even though product messages do.
- A cart has no expiry. It stays in the thread until the customer sends it, then it is cleared and they can start a new one.
- Customers can add up to 99 units of each item, with no limit on the number of distinct items.
- A sent cart can't be edited. To change an order, the customer sends a new cart. You can't send a cart to a customer.
- Product messages sent through the Cloud API don't show a shopping cart icon in the chat header, unlike product messages sent from the WhatsApp Business app.
- The product detail page shows product images only. Videos and GIFs on a product are not displayed.
Messages show the catalog's current data, so update an item in the catalog rather than resending:
| Change | What the customer sees |
|---|---|
| Price, title, description, or image | Screens showing the product update once the customer's client learns about the change |
| Item no longer available | Removed from any cart that holds it, with the dialog "One or more items in your cart have been updated"; otherwise shown as unavailable in the product message |
Product Message Formats
Each format exists as an interactive message, which you can send only inside an open customer service window, and as a marketing template, which you can send at any time.
| Format | Interactive message | Template |
|---|---|---|
| Catalog | interactive.type: "catalog_message" | Catalog template with a CATALOG button |
| Single product | interactive.type: "product" | Single-product (SPM) template with a product header and spm button |
| Multi-product (up to 30 items) | interactive.type: "product_list" | Multi-product (MPM) template with an MPM button |
| Product carousel (up to 10 cards) | interactive.type: "carousel" with product cards | Product card carousel template |
| Catalog link | wa.me/c/<PHONE_NUMBER> in a text message | (none) |
Meta also offers checkout button templates for India-based businesses, which let WhatsApp users with Indian numbers buy one or more products without leaving WhatsApp.
Catalog Messages (catalog_message)
A catalog message shows a product thumbnail header image, your body text, a fixed text header and sub-header, and a View catalog button that opens the catalog inside WhatsApp.
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "16505551234",
"type": "interactive",
"interactive": {
"type": "catalog_message",
"body": { "text": "Hello! Thanks for your interest. Ordering is easy. Just visit our catalog and add items to purchase." },
"action": {
"name": "catalog_message",
"parameters": { "thumbnail_product_retailer_id": "2lc20305pt" }
},
"footer": { "text": "Best grocery deals on WhatsApp!" }
}
}
| Field | Limit | Notes |
|---|---|---|
body.text | 1024 chars | Required |
footer.text | 60 chars | Optional |
action.parameters.thumbnail_product_retailer_id | n/a | Optional. Item SKU (Content ID in Commerce Manager) whose image becomes the header. Without parameters, the first catalog item's image is used. |
Catalog Link Messages
To link to the whole catalog, put https://wa.me/c/ followed by your business phone number with country code (for example https://wa.me/c/15555455657) in a normal text message. Set text.preview_url to true to render catalog thumbnails for the link. If the catalog is disabled, the link shows an Invalid catalog link warning.
Single-Product Messages (product)
A single-product message shows one catalog item with its image, title, and price, plus optional body and footer text and a View button that opens the product detail page.
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "16505551234",
"type": "interactive",
"interactive": {
"type": "product",
"body": { "text": "This one is back in stock." },
"footer": { "text": "Ships tomorrow." },
"action": {
"catalog_id": "<CATALOG_ID>",
"product_retailer_id": "<PRODUCT_SKU>"
}
}
}
action.catalog_idandaction.product_retailer_idare required.bodyandfooterare optional, and there is no header.- If the item doesn't match a product in the catalog, the API returns an error and the message is not sent.
- Minimum app versions: iOS 2.21.210, Android 2.21.19, and the web client. An older app shows the user a delivery-failed notice and you get a failed status webhook (see Error 131026).
- Customers can forward the message and reopen it in the same thread.
Multi-Product Messages (product_list)
A multi-product message shows up to 30 products from your catalog, organized into sections. Customers browse the list, open product details, add items to the cart, and send the order.
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "16505551234",
"type": "interactive",
"interactive": {
"type": "product_list",
"header": { "type": "text", "text": "Your usual order" },
"body": { "text": "Tap to reorder in one go." },
"footer": { "text": "Prices include VAT." },
"action": {
"catalog_id": "<CATALOG_ID>",
"sections": [
{
"title": "Breakfast",
"product_items": [
{ "product_retailer_id": "<PRODUCT_SKU_1>" },
{ "product_retailer_id": "<PRODUCT_SKU_2>" }
]
}
]
}
}
}
header(typetext),body, andactionwithcatalog_idandsectionsare required;footeris optional. Each section has atitleand aproduct_itemsarray ofproduct_retailer_idvalues.- If none of the items match the catalog, the API returns an error and nothing is sent. If at least one matches, the message is sent, unmatched items are dropped, and you get an error asking you to update the catalog.
- Minimum app versions: iOS 2.21.100, Android 2.21.9.15, and the web client. Older apps behave as for single-product messages.
- The message syncs across a customer's linked devices, but the cart stays on one device. Customers can forward it and reopen it in the thread.
Product Carousel Messages
A product carousel is the carousel interactive type with product cards instead of media cards. It shows your body text above 2 to 10 horizontally scrollable product cards, each opening the product's detail page.
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "16505551234",
"type": "interactive",
"interactive": {
"type": "carousel",
"body": { "text": "Check out our featured products!" },
"action": {
"cards": [
{ "card_index": 0, "type": "product", "action": { "product_retailer_id": "abc123xyz", "catalog_id": "123456789" } },
{ "card_index": 1, "type": "product", "action": { "product_retailer_id": "def456uvw", "catalog_id": "123456789" } }
]
}
}
}
body.textis required (1024 chars). Don't add a header, footer, or buttons.- Send at least 2 and at most 10 cards. Each
card_indexis 0 to 9 and must be unique. - Every card has
type: "product"withproduct_retailer_idandcatalog_id, and all cards must use the samecatalog_id.
Product Templates
Product templates are MARKETING templates, so you can send them outside the customer service window. Each needs a catalog with inventory connected to the account, and goes through template review like any other template (see Templates).
| Template | Components at creation | Send-time parameters |
|---|---|---|
| Catalog | BODY (1024 chars, variables allowed), optional FOOTER (60 chars), BUTTONS with one { "type": "CATALOG", "text": "View catalog" } | button component with sub_type: "CATALOG", index: 0, and an action parameter holding an optional thumbnail_product_retailer_id |
| Multi-product (MPM) | HEADER with format: "TEXT" (60 chars, one variable), BODY (1024 chars), optional FOOTER (60 chars), BUTTONS with one { "type": "MPM", "text": "View items" } | Header and body parameters if the template has variables, plus a button component with sub_type: "mpm", index: 0, and an action holding thumbnail_product_retailer_id and sections (up to 10 sections, titles up to 24 chars, up to 30 products in total) |
| Single-product (SPM) | header with format: "product", body (160 chars, variables allowed), optional footer (60 chars), buttons with one { "type": "spm", "text": "View" }. parameter_format may be named or positional (the default) | header parameter { "type": "product", "product": { "product_retailer_id": "<ID>", "catalog_id": "<CATALOG_ID>" } }, plus body parameters |
| Product card carousel | body (1024 chars, variables allowed) and a carousel component with exactly two cards, each a product header plus one spm View button or one url button (label 25 chars, URL 2000 chars with one variable at the end). All cards must share the same components | A carousel component with 2 to 10 cards, each with a card_index and a header product parameter as above. A template approved with two cards can send up to 10 |
- MPM and SPM template messages need WhatsApp 2.22.24 or later on the recipient's device, and recipients can't forward them.
- Product cards with a View button keep the purchase in WhatsApp and trigger order webhooks. A
urlbutton opens your site in the browser, so the order happens outside WhatsApp and no order webhook is sent. - Carousel body variables support the
text,currency, anddate_timetypes and count toward the 1024-character body limit.
Example MPM template send, with a header variable, a body variable, and two sections:
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "16505551234",
"type": "template",
"template": {
"name": "abandoned_cart",
"language": { "code": "en_US" },
"components": [
{ "type": "header", "parameters": [{ "type": "text", "text": "Pablo" }] },
{ "type": "body", "parameters": [{ "type": "text", "text": "10OFF" }] },
{
"type": "button",
"sub_type": "mpm",
"index": 0,
"parameters": [
{
"type": "action",
"action": {
"thumbnail_product_retailer_id": "2lc20305pt",
"sections": [
{ "title": "Popular Bundles", "product_items": [{ "product_retailer_id": "2lc20305pt" }, { "product_retailer_id": "nseiw1x3ch" }] },
{ "title": "Premium Packages", "product_items": [{ "product_retailer_id": "n6k6x0y7oe" }] }
]
}
}
]
}
]
}
}
Orders and Product Inquiries
Customer responses to product messages arrive on the messages webhook field, like any inbound message. Sent, delivered, and read statuses arrive as normal status webhooks.
Questions about a product. A customer can reply in the thread, or tap Message business while viewing a product. The resulting text message webhook includes a context object with a referred_product that identifies the catalog and product they were viewing.
Orders. When a customer sends their cart, you get a message with type: "order":
{
"from": "16505551234",
"id": "wamid.HBgLMTY1MDM4Nzk0MzkVAgASGBQzQTMxNzA1QzNENEI4ODY0OTY2MAA=",
"timestamp": "1683223069",
"type": "order",
"order": {
"catalog_id": "1537566713439863",
"text": "Love these!",
"product_items": [
{
"product_retailer_id": "n6k6x0y7oe",
"quantity": 1,
"item_price": 99.99,
"currency": "USD"
}
]
}
}
| Field | Meaning |
|---|---|
order.catalog_id | Catalog the order came from |
order.text | Text the customer sent with the order, if any |
product_items[].product_retailer_id | Item SKU (Content ID in Commerce Manager) |
product_items[].quantity | Units ordered of that item |
product_items[].item_price | Item price |
product_items[].currency | Item currency |
The order is only a request. WhatsApp shows the customer an "Order via catalog" confirmation with an estimated total, and the next steps are yours, such as asking for a delivery address or sending payment options.
Products a customer sends you. When a customer sends you a single product from your catalog, you get an interactive message with interactive.type: "product":
{
"from": "16505551234",
"id": "wamid.HBgLMTY1MDM4Nzk0MzkVAgASGBQzQTZBQzg0MzQ4QjRCM0NGNkVGOAA=",
"timestamp": "1750025136",
"type": "interactive",
"interactive": {
"type": "product",
"product": {
"retailer_id": "2lc20305pt",
"title": "Classic T-Shirt",
"description": "100% cotton, unisex fit",
"currency_code": "USD",
"price_amount": 1000,
"sale_price_amount": 800,
"url": "https://example.com/products/classic-t-shirt"
}
}
}
retailer_id is the item SKU (Content ID in Commerce Manager). price_amount and sale_price_amount are whole numbers equal to the price times 1,000, so 1000 is 1.00 USD; divide by 1,000. sale_price_amount is only present when the product is on sale.
Dualhook Boundary
Dualhook does not create, upload, or connect catalogs, and it does not change commerce settings. The Runtime API has no catalog or whatsapp_commerce_settings routes, and Dualhook's Embedded Signup does not request catalog access. Manage inventory in Meta Commerce Manager, connect the catalog to the WhatsApp account there or in WhatsApp Manager, and change cart and catalog visibility with the Commerce Settings API from your own Meta app.
You can send every product message on this page through the Runtime API /messages route, which passes the interactive or template object to Meta unchanged. The dashboard has no message composer, so the sends come from your own backend.
The Runtime API template route can create catalog (CATALOG button) and multi-product (MPM button) templates, with the uppercase enum values it requires. It rejects single-product templates (PRODUCT header, SPM button) and product card carousels, because it accepts only HEADER, BODY, FOOTER, and BUTTONS components. Create those in WhatsApp Manager or with your own Meta app, then send them through /messages like any approved template. The dashboard template editor can't build any product template, and won't save edits to or copies of synced ones.
Orders, product questions, and products customers send you are messages webhooks, so Meta sends them straight to your endpoint through Webhook Override. Dualhook does not receive, store, or process orders.
Most Dualhook connections are Coexistence numbers. Meta's Coexistence feature table keeps the WhatsApp Business app's catalog and orders working in the app, but they are not synchronized to Cloud API (see WhatsApp Coexistence Limitations).