# Carruseles multimedia de WhatsApp

Un carrusel multimedia es un conjunto de dos a diez tarjetas que el destinatario desliza una junto a otra, cada una con su propia imagen o video, su propio texto corto y sus propios botones. Úsalo para mostrar varios elementos a la vez, como un puñado de productos, en lugar de enviar un mensaje por cada elemento.

## Enviar un carrusel

Establece `interactive.type` en `carousel`, con un `body_text` a nivel de mensaje y un array `cards` de 2 a 10 entradas:

**TypeScript**

```typescript
const msg = await bird.whatsapp.send({
  to: "+16505551234",
  from: "+13124495648",
  interactive: {
    type: "carousel",
    body_text: "Here are two of our latest arrivals, each under $25:",
    cards: [
      {
        header: { type: "image", url: "https://cdn.example.com/plants/blue-echeveria.jpeg" },
        buttons: [
          {
            type: "cta_url",
            cta_url: { text: "Buy now", url: "https://shop.example.com/blue-echeveria" },
          },
        ],
      },
      {
        header: { type: "image", url: "https://cdn.example.com/plants/zebra-haworthia.jpeg" },
        buttons: [
          {
            type: "cta_url",
            cta_url: { text: "Buy now", url: "https://shop.example.com/zebra-haworthia" },
          },
        ],
      },
    ],
  },
});
console.log(msg.id, msg.status);
```

Examples: [TypeScript](/es-es/documentacion/guides/whatsapp/message-types/interactive/carousels.ts.md) · [Python](/es-es/documentacion/guides/whatsapp/message-types/interactive/carousels.py.md) · [Go](/es-es/documentacion/guides/whatsapp/message-types/interactive/carousels.go.md) · [PHP](/es-es/documentacion/guides/whatsapp/message-types/interactive/carousels.php.md) · [CLI](/es-es/documentacion/guides/whatsapp/message-types/interactive/carousels.cli.md) · [MCP](/es-es/documentacion/guides/whatsapp/message-types/interactive/carousels.mcp.md) · [cURL](/es-es/documentacion/guides/whatsapp/message-types/interactive/carousels.curl.md)

`from` es obligatorio en cada mensaje de servicio: un número que tu espacio de trabajo posee, no uno gestionado por Bird. La forma completa añade el texto propio de una tarjeta, un segundo botón de respuesta rápida y una cita de un mensaje anterior:

```json
{
  "to": "+16505551234",
  "from": "+13124495648",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "interactive": {
    "type": "carousel",
    "body_text": "Here are two of our latest arrivals, each under $25:",
    "cards": [
      {
        "header": { "type": "image", "url": "https://cdn.example.com/plants/blue-echeveria.jpeg" },
        "body_text": "Blue Echeveria. Powdery blue leaves.",
        "buttons": [
          { "type": "quick_reply", "quick_reply": { "slug": "buy-echeveria", "text": "Buy" } },
          { "type": "quick_reply", "quick_reply": { "slug": "info-echeveria", "text": "Details" } }
        ]
      },
      {
        "header": { "type": "image", "url": "https://cdn.example.com/plants/zebra-haworthia.jpeg" },
        "body_text": "Zebra Haworthia. White stripes on deep green leaves.",
        "buttons": [
          { "type": "quick_reply", "quick_reply": { "slug": "buy-haworthia", "text": "Buy" } },
          { "type": "quick_reply", "quick_reply": { "slug": "info-haworthia", "text": "Details" } }
        ]
      }
    ]
  },
  "tags": [{ "name": "category", "value": "catalog" }],
  "metadata": { "order_id": "A-1" }
}
```

`in_reply_to_message_id` cita un mensaje anterior en la misma conversación. Consulta en el hub [citar un mensaje para correlacionar una respuesta](/docs/guides/whatsapp/message-types/interactive#quoting-a-message-to-correlate-a-reply) para ver cómo funciona la resolución y qué puede omitir.

Un carrusel no admite encabezado ni pie a nivel de mensaje: el `body_text` del mensaje es el único texto por encima de las tarjetas. Consulta la sección de [botones](/docs/guides/whatsapp/message-types/interactive#buttons) del hub para ver la forma de botón compartida que reutilizan las tarjetas de este tipo.

## Tarjetas

Cada tarjeta lleva su propio encabezado multimedia, su propio texto corto y sus propios botones:

- **`header`** es obligatorio en cada tarjeta, y solo puede ser `image` o `video`: sin texto ni encabezado de documento, a diferencia de los otros tipos interactivos.
- **`body_text`** es opcional. Aparece debajo del multimedia de la tarjeta, con un límite más corto que el cuerpo de un mensaje, y permite como máximo dos saltos de línea.
- **`buttons`** es obligatorio: un botón `cta_url` o hasta tres botones `quick_reply`, nunca una mezcla en la misma tarjeta.

Las tarjetas se muestran de izquierda a derecha en el orden en que aparecen en el array `cards`. Una tarjeta no tiene pie ni campo de índice propio; su posición en el array es su posición en el carrusel.

## Todas las tarjetas llevan los mismos botones

Cada tarjeta de un carrusel debe llevar **los mismos tipos de botón, la misma cantidad y en el mismo orden**. Un carrusel en el que la tarjeta 1 tiene un botón `cta_url` y la tarjeta 2 tiene dos botones `quick_reply` se rechaza, al igual que un carrusel en el que todas las tarjetas tienen dos botones `quick_reply` pero en un orden distinto.

La razón es cómo WhatsApp renderiza el mensaje: un carrusel es una vista de tarjeta con un diseño compartido, no un conjunto de tarjetas con diseño independiente. Una tarjeta con una fila de botones diferente rompería ese diseño compartido, por lo que WhatsApp exige que todas coincidan y Bird lo comprueba antes de crear o cobrar el envío. Una discrepancia devuelve [E15059](/docs/api/errors/E15059).

Las etiquetas de los botones son una regla aparte, y su alcance es diferente: una etiqueta debe ser única **dentro de una tarjeta**, no en todo el carrusel. "Buy now" en cada una de las diez tarjetas es válido; "Buy now" dos veces en la misma tarjeta devuelve [E15056](/docs/api/errors/E15056).

## Límites

| Campo                                                  | Restricción                                                               |
| ------------------------------------------------------ | ------------------------------------------------------------------------- |
| `cards`                                                | 2 a 10 entradas                                                           |
| `header` de tarjeta                                    | obligatorio en cada tarjeta; solo `image` o `video`                       |
| `header.url` de tarjeta                                | obligatorio, sin longitud máxima                                          |
| `body_text` de tarjeta                                 | opcional, de 1 a 160 caracteres, máximo 2 saltos de línea                 |
| `buttons` de tarjeta                                   | 1 a 3 entradas: un `cta_url`, o hasta tres `quick_reply`, nunca mezclados |
| Etiqueta de botón (`quick_reply.text`, `cta_url.text`) | obligatorio, de 1 a 20 caracteres, único dentro de la tarjeta             |
| `quick_reply.slug`                                     | obligatorio, de 1 a 256 caracteres                                        |
| `cta_url.url`                                          | obligatorio, de 1 a 2000 caracteres                                       |
| `body_text` del mensaje                                | obligatorio, de 1 a 1024 caracteres                                       |
| Encabezado y pie del mensaje                           | no permitidos en un carrusel: sin `header`, sin `footer_text`             |

Bird limita los botones `quick_reply` a tres por tarjeta. Meta no indica un límite numérico, solo que una tarjeta acepta un botón de enlace o uno o más botones de respuesta, así que este tope es propio de Bird, no de WhatsApp.

## Leer la respuesta

Solo un botón de tarjeta `quick_reply` produce una respuesta. Al pulsarlo, llega como su propio mensaje entrante con `interactive_reply`:

```json
{
  "id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
  "direction": "inbound",
  "from": { "phone_number": "+16505551234" },
  "to": { "phone_number": "+13124495648" },
  "status": "received",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "interactive_reply": {
    "type": "button",
    "button": {
      "slug": "buy-echeveria",
      "text": "Buy"
    }
  },
  "created_at": "2026-08-25T09:04:11Z"
}
```

El `slug` que estableciste en el botón pulsado vuelve tal cual en `interactive_reply.button.slug`, la misma forma que produce una pulsación de botones de respuesta. Ves esta respuesta a través de la lista de mensajes o `GET /v1/whatsapp/messages/{id}`; consulta en el hub [leer una respuesta](/docs/guides/whatsapp/message-types/interactive#reading-a-reply) para ver esa ruta completa.

Un botón `cta_url` en una tarjeta abre su enlace en el navegador del destinatario y no envía nada de vuelta, igual que un [botón de enlace](/docs/guides/whatsapp/message-types/interactive/cta-url-buttons) independiente.

## Carruseles libres y carruseles de plantilla

Esta página cubre el carrusel libre que envías en línea con `interactive.type: "carousel"`, entregable solo dentro de una ventana de servicio al cliente abierta y nunca revisado por Meta. [Plantillas de WhatsApp](/docs/guides/whatsapp/templates) tiene su propio carrusel separado: un componente de plantilla creado una vez, enviado a Meta para aprobación y enviado por slug como cualquier otra plantilla, incluso fuera de la ventana. Los dos comparten la palabra "carousel" y el rango de 2 a 10 tarjetas de Meta, y nada más: formas de transmisión distintas, rutas de revisión distintas, y la cantidad de tarjetas de un carrusel de plantilla se fija en la aprobación de la plantilla en lugar de elegirse por envío. Si estás explorando plantillas y ves "carousel" ahí, ese es el tipo de plantilla, no esta página.

## Límites y casos extremos

- **La ventana de servicio al cliente debe estar abierta.** Un carrusel es un mensaje de servicio, entregable solo dentro de una ventana abierta; consulta en el hub [ventana de servicio al cliente](/docs/guides/whatsapp/message-types#the-customer-service-window). La comprobación de la ventana falla como abierta, así que un `202` no es prueba de que la ventana estuviera realmente abierta cuando se despacha el envío.
- **`from` debe ser un número que tu espacio de trabajo posee.** Omitirlo, o indicar un número que no sea un remitente conectado, se rechaza antes de crear el envío.
- **El multimedia de la tarjeta debe ser accesible públicamente cuando se despacha el envío.** Bird no almacena ni redirige el archivo: WhatsApp obtiene el `url` de cada tarjeta por sí mismo, en el momento del envío, así que una URL firmada debe durar más que el envío.
- **Una URL multimedia de tarjeta que WhatsApp no puede obtener se acepta, luego falla de forma asíncrona, y aun así se cobra.** La validación de solicitud de Bird solo comprueba que el `url` de una tarjeta sea un URI bien formado, no que WhatsApp pueda alcanzarlo ni que use `https`. Un archivo demasiado grande, un 404, un host irresolvible o un tipo de archivo incorrecto vuelven como `202` en la aceptación, luego `whatsapp.accepted`, luego `whatsapp.sent`, luego `whatsapp.failed`, con `media_rejected` en el `last_error` del mensaje y el costo del envío ya cobrado sin vía de reembolso. Prueba la URL de cada tarjeta antes de enviar, ya que una rota no se detecta hasta después del hecho.
- **Todas las tarjetas deben llevar los mismos botones.** Consulta [Todas las tarjetas llevan los mismos botones](#todas-las-tarjetas-llevan-los-mismos-botones) más arriba; esta es la única regla de carrusel que el esquema de la solicitud no puede expresar por sí solo, por lo que se comprueba por separado y devuelve [E15059](/docs/api/errors/E15059) en lugar de un error de validación genérico.
- **Sin encabezado ni pie a nivel de mensaje.** El único texto de un carrusel por encima de las tarjetas es `body_text`; no hay dónde colocar letra pequeña como lo hacen los otros tipos con `footer_text`.
- **La respuesta no incluye índice de tarjeta.** La pulsación de `quick_reply` en una tarjeta solo reporta `{slug, text}`, la misma forma que una pulsación de botones de respuesta, sin un campo que indique de qué tarjeta provino. Si necesitas saber qué tarjeta se pulsó, codifica la tarjeta en el `slug` de cada botón, por ejemplo `buy-echeveria` en lugar de un `buy` simple.
- **Un botón de tarjeta `cta_url` no genera ningún evento entrante.** Si necesitas saber que se interactuó con una tarjeta, usa botones `quick_reply` en esa tarjeta, o rastrea el clic en tu propia URL de destino.

Aparte de E15059, el único error interactivo específico de un carrusel es [E15056](/docs/api/errors/E15056) por una etiqueta de botón repetida en una tarjeta. Una cita que no se resuelve hace fallar la solicitud antes de crear o cobrar nada: `404` [`E15071`](/docs/api/errors/E15071) cuando el id no corresponde a ningún mensaje de este espacio de trabajo, `422` [`E15072`](/docs/api/errors/E15072) cuando corresponde a uno que no se puede citar. Para los errores que cualquier envío de WhatsApp puede encontrar, como una ventana cerrada, un remitente faltante o inválido, o un destinatario inválido, consulta en el hub [errores](/docs/guides/whatsapp/message-types/interactive#errors) y [Enviar mensajes de WhatsApp](/docs/guides/whatsapp/sending-whatsapp).

## Próximos pasos

- [Mensajes interactivos de WhatsApp](/docs/guides/whatsapp/message-types/interactive): lo que comparten los seis tipos interactivos
- [Plantillas de WhatsApp](/docs/guides/whatsapp/templates): para un carrusel que se envía fuera de la ventana de servicio al cliente
- [Enviar mensajes de WhatsApp](/docs/guides/whatsapp/sending-whatsapp): la envoltura de la solicitud, el modelo `202` y reintentos seguros

## Related resources

- [Connecting WhatsApp to Bird: from buying a number to a live channel](/learn/whatsapp/connecting-whatsapp-to-bird) (video)
- [What is the 24-hour customer service window on WhatsApp?](/explained/whatsapp/what-is-the-24-hour-customer-service-window) (answer)
- [WhatsApp message builder](/tools/whatsapp-message-builder) (tool)
- [WhatsApp](/products/whatsapp) (product)

[Get an implementation brief](/learn/workspace?topic=whatsapp)
