# Carrosséis de mídia WhatsApp

Um carrossel de mídia é um conjunto de dois a dez cards que o destinatário desliza lado a lado, cada um com sua própria imagem ou vídeo, seu próprio texto curto e seus próprios botões. Use-o para mostrar vários itens de uma vez, como um punhado de produtos, em vez de enviar uma mensagem por item.

## Enviar um carrossel

Defina `interactive.type` como `carousel`, com um `body_text` no nível da mensagem e um 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](/pt-br/documentacao/guides/whatsapp/message-types/interactive/carousels.ts.md) · [Python](/pt-br/documentacao/guides/whatsapp/message-types/interactive/carousels.py.md) · [Go](/pt-br/documentacao/guides/whatsapp/message-types/interactive/carousels.go.md) · [PHP](/pt-br/documentacao/guides/whatsapp/message-types/interactive/carousels.php.md) · [CLI](/pt-br/documentacao/guides/whatsapp/message-types/interactive/carousels.cli.md) · [MCP](/pt-br/documentacao/guides/whatsapp/message-types/interactive/carousels.mcp.md) · [cURL](/pt-br/documentacao/guides/whatsapp/message-types/interactive/carousels.curl.md)

`from` é obrigatório em toda mensagem de serviço: um número que seu espaço de trabalho possui, não um gerenciado por Bird. A forma completa adiciona o texto próprio do card, um segundo botão de resposta rápida e a citação de uma mensagem 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 uma mensagem anterior na mesma conversa. Consulte a seção [citar uma mensagem para correlacionar uma resposta](/docs/guides/whatsapp/message-types/interactive#quoting-a-message-to-correlate-a-reply) do hub para saber como a resolução funciona e o que ela pode perder.

Um carrossel não aceita header nem footer no nível da mensagem: o `body_text` da mensagem é o único texto acima dos cards. Consulte a seção [botões](/docs/guides/whatsapp/message-types/interactive#buttons) do hub para ver a forma compartilhada de botão que os cards desse tipo reutilizam.

## Cards

Cada card carrega seu próprio header de mídia, seu próprio texto curto e seus próprios botões:

- **`header`** é obrigatório em todo card, e aceita apenas `image` ou `video`: sem texto e sem header de documento, diferente dos outros tipos interativos.
- **`body_text`** é opcional. Fica abaixo da mídia do card, com limite menor que o corpo de uma mensagem, e permite no máximo duas quebras de linha.
- **`buttons`** é obrigatório: um botão `cta_url` ou até três botões `quick_reply`, nunca uma combinação no mesmo card.

Os cards são renderizados da esquerda para a direita na ordem em que aparecem no array `cards`. Um card não tem footer nem campo de índice próprio; sua posição no array é sua posição no carrossel.

## Todo card carrega os mesmos botões

Todo card em um carrossel deve carregar **os mesmos tipos de botão, o mesmo número deles e na mesma ordem**. Um carrossel em que o card 1 tem um botão `cta_url` e o card 2 tem dois botões `quick_reply` é recusado, assim como um carrossel em que todo card tem dois botões `quick_reply` mas em ordem diferente.

O motivo é como WhatsApp renderiza a mensagem: um carrossel é uma visualização de card com layout compartilhado, não um conjunto de cards com layouts independentes. Um card com uma linha de botões diferente quebraria esse layout compartilhado, então WhatsApp exige que todos os cards sejam iguais e Bird verifica isso antes que o envio seja criado ou cobrado. Uma incompatibilidade retorna [E15059](/docs/api/errors/E15059).

Os rótulos dos botões são uma regra separada, com escopo diferente: um rótulo deve ser único **dentro de um card**, não em todo o carrossel. "Buy now" em cada um dos dez cards é válido; "Buy now" duas vezes no mesmo card retorna [E15056](/docs/api/errors/E15056).

## Limites

| Campo                                                | Limite                                                                    |
| ---------------------------------------------------- | ------------------------------------------------------------------------- |
| `cards`                                              | 2 a 10 entradas                                                           |
| Card `header`                                        | obrigatório em todo card; apenas `image` ou `video`                       |
| Card `header.url`                                    | obrigatório, sem limite máximo de tamanho                                 |
| Card `body_text`                                     | opcional, 1 a 160 caracteres, no máximo 2 quebras de linha                |
| Card `buttons`                                       | 1 a 3 entradas: um `cta_url`, ou até três `quick_reply`, nunca misturados |
| Rótulo do botão (`quick_reply.text`, `cta_url.text`) | obrigatório, 1 a 20 caracteres, único dentro do card                      |
| `quick_reply.slug`                                   | obrigatório, 1 a 256 caracteres                                           |
| `cta_url.url`                                        | obrigatório, 1 a 2.000 caracteres                                         |
| Message `body_text`                                  | obrigatório, 1 a 1.024 caracteres                                         |
| Header e footer da mensagem                          | não permitidos em um carrossel: sem `header`, sem `footer_text`           |

Bird limita botões `quick_reply` a três por card. A própria Meta não define um limite numérico, apenas que um card aceita um botão de link ou um ou mais botões de resposta, então esse teto é de Bird, não de WhatsApp.

## Lendo a resposta

Apenas um botão `quick_reply` em um card produz uma resposta. Um toque nele chega como sua própria mensagem de entrada, carregando `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"
}
```

O `slug` que você definiu no botão tocado retorna tal qual em `interactive_reply.button.slug`, a mesma forma que um toque em botões de resposta produz. Você vê essa resposta pela lista de mensagens ou por `GET /v1/whatsapp/messages/{id}`; consulte a seção [lendo uma resposta](/docs/guides/whatsapp/message-types/interactive#reading-a-reply) do hub para o caminho completo.

Um botão `cta_url` em um card abre o link no navegador do destinatário e não envia nada de volta, da mesma forma que um [botão de link](/docs/guides/whatsapp/message-types/interactive/cta-url-buttons) avulso.

## Carrosséis livres e carrosséis de template

Esta página cobre o carrossel livre que você envia inline com `interactive.type: "carousel"`, entregável apenas dentro de uma janela de atendimento ao cliente aberta e nunca revisado pela Meta. [Templates WhatsApp](/docs/guides/whatsapp/templates) tem seu próprio carrossel separado: um componente de template criado uma vez, enviado à Meta para aprovação e enviado por slug como qualquer outro template, inclusive fora da janela. Os dois compartilham a palavra "carousel" e a faixa de 2 a 10 cards da Meta, e nada mais: formatos de transmissão diferentes, caminhos de revisão diferentes, e a quantidade de cards de um carrossel de template é fixada na aprovação do template, não escolhida a cada envio. Se você estiver navegando por templates e vir "carousel" lá, esse é o tipo de template, não esta página.

## Limites e casos extremos

- **A janela de atendimento ao cliente precisa estar aberta.** Um carrossel é uma mensagem de serviço, entregável apenas dentro de uma janela aberta; consulte a seção [janela de atendimento ao cliente](/docs/guides/whatsapp/message-types#the-customer-service-window) do hub. A verificação da janela falha de forma aberta, então um `202` não é prova de que a janela estava de fato aberta quando o envio é feito.
- **`from` deve ser um número que seu espaço de trabalho possui.** Omiti-lo, ou informar um número que não é um remetente conectado, é rejeitado antes que o envio seja criado.
- **A mídia do card precisa estar acessível publicamente quando o envio é despachado.** Bird não armazena nem faz proxy do arquivo: WhatsApp busca o `url` de cada card no momento do envio, então uma URL assinada precisa durar mais que o envio.
- **Uma URL de mídia do card que WhatsApp não consegue buscar é aceita, depois falha de forma assíncrona, e ainda assim é cobrada.** A validação de solicitação de Bird verifica apenas se o `url` de um card é um URI bem formado, não se WhatsApp consegue acessá-lo ou se ele usa `https`. Um arquivo grande demais, um 404, um host irresolvível ou o tipo de arquivo errado retornam como `202` no aceite, depois `whatsapp.accepted` depois `whatsapp.sent` depois `whatsapp.failed`, com `media_rejected` no `last_error` da mensagem e o custo do envio já cobrado sem caminho de reembolso. Teste a URL de cada card antes de enviar, pois uma URL quebrada só é detectada depois do fato.
- **Todo card deve carregar os mesmos botões.** Veja [Todo card carrega os mesmos botões](#todo-card-carrega-os-mesmos-botões) acima; esta é a única regra de carrossel que o schema da solicitação não consegue expressar sozinho, então é verificada separadamente e retorna [E15059](/docs/api/errors/E15059) em vez de um erro genérico de validação.
- **Sem header ou footer no nível da mensagem.** O único texto de um carrossel acima dos cards é `body_text`; não há onde colocar texto pequeno da forma que os outros tipos usam `footer_text`.
- **A resposta não traz índice do card.** Um toque em `quick_reply` de um card reporta apenas `{slug, text}`, a mesma forma de um toque em botões de resposta, sem campo indicando de qual card veio. Se você precisa saber qual card foi tocado, codifique o card no `slug` de cada botão, como `buy-echeveria` em vez de um simples `buy`.
- **Um botão `cta_url` em um card não gera evento de entrada.** Se você precisa saber que houve interação com um card, use botões `quick_reply` nesse card, ou rastreie o clique na sua própria URL de destino.

Além de E15059, o único erro interativo específico de um carrossel é [E15056](/docs/api/errors/E15056) para um rótulo de botão repetido em um card. Uma citação que não resolve falha a solicitação antes que qualquer coisa seja criada ou cobrada: `404` [`E15071`](/docs/api/errors/E15071) quando o id não corresponde a nenhuma mensagem que esse espaço de trabalho possui, `422` [`E15072`](/docs/api/errors/E15072) quando corresponde a uma que não pode ser citada. Para os erros que qualquer envio WhatsApp pode encontrar, uma janela fechada, um remetente ausente ou inválido, ou um destinatário inválido, consulte as seções [erros](/docs/guides/whatsapp/message-types/interactive#errors) e [Enviando mensagens WhatsApp](/docs/guides/whatsapp/sending-whatsapp) do hub.

## Próximos passos

- [Mensagens interativas WhatsApp](/docs/guides/whatsapp/message-types/interactive): o que todos os seis tipos interativos compartilham
- [Templates WhatsApp](/docs/guides/whatsapp/templates): para um carrossel enviado fora da janela de atendimento ao cliente
- [Enviando mensagens WhatsApp](/docs/guides/whatsapp/sending-whatsapp): o envelope da solicitação, o modelo `202` e novas tentativas seguras

## 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)
