# Carrossel

Cartões lado a lado, que o contato arrasta para o lado. Cada cartão tem uma mídia, um texto e os seus botões. Serve para vitrine de produtos, planos ou opções com foto.

- `text`: o texto que vai acima dos cartões.
- `cards[]`: os cartões, na ordem em que aparecem.
  - `type`: a mídia do cartão (`image`, `video` ou `document`). Com `url` e sem `type`, vale `image`.
  - `url` ou `base64`: o arquivo. Use um dos dois; `filename` dá o nome do documento.
  - `text`: o texto do cartão, abaixo da mídia. Aceita quebra de linha.
  - `choices[]`: os botões do cartão. Sem `action` (ou `action: reply`), o botão responde: o contato toca e chega um `message.received` com `interactive_reply`, e o `option_id` é o `id` do botão (sem `id`, vale o `title`). Com `action: url`, abre o link em `value`; `call` liga para o número em `value`; `copy` copia o código em `value`. Esses três não geram evento: nada chega ao WhatsApp da inbox.

Nos botões, `title`, `id` e `value` não aceitam aspas, `\` nem quebra de linha. Use `id` diferente em cada botão de resposta, mesmo entre cartões: o clique diz qual botão foi tocado, não qual cartão.

Só no WhatsApp Web. Na API oficial, no Telegram, no Instagram e no Messenger, responde `501` com `unsupported_for_channel`.

## Canais

| Canal | Funciona | Observação |
|---|---|---|
| WhatsApp (Web) | Sim |  |
| WhatsApp (API oficial) | Não |  |
| Instagram | Não |  |
| Messenger | Não |  |
| Telegram | Não |  |

## Pedido

`POST /messages` com `"type": "carousel"`. [Testar](/endpoint/post/messages)

```json
{
  "to": "5511999999999",
  "type": "carousel",
  "text": "Nossos destaques",
  "cards": [
    {
      "type": "image",
      "url": "https://loja.exemplo/xyz.jpg",
      "text": "Smartphone XYZ\nR$ 1.999",
      "choices": [
        {
          "id": "comprar_xyz",
          "title": "Comprar"
        },
        {
          "title": "Ver no site",
          "action": "url",
          "value": "https://loja.exemplo/xyz"
        }
      ]
    },
    {
      "type": "image",
      "url": "https://loja.exemplo/fone.jpg",
      "text": "Fone ABC\nR$ 299",
      "choices": [
        {
          "id": "comprar_fone",
          "title": "Comprar"
        },
        {
          "title": "Falar com vendedor",
          "action": "call",
          "value": "+5511888888888"
        }
      ]
    }
  ]
}
```

### Na uazapi

`POST /send/carousel`, que continua funcionando. Os botões do cartão (`choices`) têm o mesmo formato das outras opções; a mídia do cartão (`type`, `url`) vai solta no próprio cartão. Na uazapi o link ia no `id` com `type: URL`; na Orkesio vai em `value` com `action: url`. A resposta é a própria mensagem, igual ao `message.sent`.

```lado-a-lado
{
  "uazapi (POST /send/carousel)": {
    "number": "5511999999999",
    "text": "Nossos destaques",
    "carousel": [
      {
        "text": "Smartphone XYZ\nR$ 1.999",
        "image": "https://loja.exemplo/xyz.jpg",
        "buttons": [
          {
            "id": "comprar_xyz",
            "text": "Comprar",
            "type": "REPLY"
          },
          {
            "id": "https://loja.exemplo/xyz",
            "text": "Ver no site",
            "type": "URL"
          }
        ]
      },
      {
        "text": "Fone ABC\nR$ 299",
        "image": "https://loja.exemplo/fone.jpg",
        "buttons": [
          {
            "id": "comprar_fone",
            "text": "Comprar",
            "type": "REPLY"
          },
          {
            "id": "+5511888888888",
            "text": "Falar com vendedor",
            "type": "CALL"
          }
        ]
      }
    ]
  },
  "Orkesio (POST /messages)": {
    "to": "5511999999999",
    "type": "carousel",
    "text": "Nossos destaques",
    "cards": [
      {
        "type": "image",
        "url": "https://loja.exemplo/xyz.jpg",
        "text": "Smartphone XYZ\nR$ 1.999",
        "choices": [
          {
            "id": "comprar_xyz",
            "title": "Comprar"
          },
          {
            "title": "Ver no site",
            "action": "url",
            "value": "https://loja.exemplo/xyz"
          }
        ]
      },
      {
        "type": "image",
        "url": "https://loja.exemplo/fone.jpg",
        "text": "Fone ABC\nR$ 299",
        "choices": [
          {
            "id": "comprar_fone",
            "title": "Comprar"
          },
          {
            "title": "Falar com vendedor",
            "action": "call",
            "value": "+5511888888888"
          }
        ]
      }
    ]
  }
}
```

## Resposta

A própria mensagem (`OrkesioMessage`), no formato do `message.sent` e da busca. No WhatsApp Web volta na hora com `status: queued`: por padrão o envio vai pela fila (com `options.async: false`, espera o envio e volta a mensagem enviada). É o pedido no formato da mensagem: o arquivo, a miniatura e a prévia do link chegam no `message.sent`. Na API oficial volta depois que a Meta aceita, com `status: pending`. O resultado chega em `message.status` (a falha também em `message.failed`).

```json
{
  "id": "3EB05DCE1D4036FCE241C6",
  "chat_id": "5511999999999@s.whatsapp.net",
  "author": {
    "id": "5511888888888@s.whatsapp.net",
    "phone": "5511888888888"
  },
  "direction": "out",
  "sent_by": "api",
  "sent_at": "2026-10-17T12:00:00.000Z",
  "type": "carousel",
  "text": "Nossos destaques",
  "cards": [
    {
      "type": "image",
      "mime_type": "image/jpeg",
      "text": "Smartphone XYZ\nR$ 1.999",
      "choices": [
        {
          "id": "comprar_xyz",
          "title": "Comprar"
        },
        {
          "title": "Ver no site",
          "action": "url",
          "value": "https://loja.exemplo/xyz"
        }
      ]
    },
    {
      "type": "image",
      "mime_type": "image/jpeg",
      "text": "Fone ABC\nR$ 299",
      "choices": [
        {
          "id": "comprar_fone",
          "title": "Comprar"
        },
        {
          "title": "Falar com vendedor",
          "action": "call",
          "value": "+5511888888888"
        }
      ]
    }
  ],
  "category": "unsent",
  "status": "queued"
}
```

### Na uazapi

O `content` da uazapi é o proto do WhatsApp; aqui vai resumido (`...`).

```lado-a-lado
{
  "uazapi": {
    "id": "5511888888888:3EB05DCE1D4036FCE241C6",
    "messageid": "3EB05DCE1D4036FCE241C6",
    "chatid": "5511999999999@s.whatsapp.net",
    "fromMe": true,
    "messageType": "InteractiveMessage",
    "messageTimestamp": 1792238400000,
    "text": "Nossos destaques",
    "content": {
      "body": {
        "text": "Nossos destaques"
      },
      "carouselMessage": {
        "cards": [
          "..."
        ]
      }
    },
    "wasSentByApi": true,
    "response": {
      "status": "success",
      "message": "Message sent successfully"
    }
  },
  "Orkesio": {
    "id": "3EB05DCE1D4036FCE241C6",
    "chat_id": "5511999999999@s.whatsapp.net",
    "author": {
      "id": "5511888888888@s.whatsapp.net",
      "phone": "5511888888888"
    },
    "direction": "out",
    "sent_by": "api",
    "sent_at": "2026-10-17T12:00:00.000Z",
    "type": "carousel",
    "text": "Nossos destaques",
    "cards": [
      {
        "type": "image",
        "mime_type": "image/jpeg",
        "text": "Smartphone XYZ\nR$ 1.999",
        "choices": [
          {
            "id": "comprar_xyz",
            "title": "Comprar"
          },
          {
            "title": "Ver no site",
            "action": "url",
            "value": "https://loja.exemplo/xyz"
          }
        ]
      },
      {
        "type": "image",
        "mime_type": "image/jpeg",
        "text": "Fone ABC\nR$ 299",
        "choices": [
          {
            "id": "comprar_fone",
            "title": "Comprar"
          },
          {
            "title": "Falar com vendedor",
            "action": "call",
            "value": "+5511888888888"
          }
        ]
      }
    ],
    "category": "unsent",
    "status": "queued"
  }
}
```

## No webhook

O que chega no seu webhook (ou em `GET /events`) depois do envio.

### message.sent

Quando o carrossel sai, com os cartões. [O evento `message.sent`](/webhook/message.sent)

```json
{
  "id": "evt_01JAB3K9ZQ7V0M4T8R2X6WYD5H",
  "type": "message.sent",
  "created_at": "2026-10-17T12:00:00.000Z",
  "inbox": {
    "id": "r0269625d29bfbd",
    "name": "loja",
    "phone": "5511888888888",
    "channel": "whatsapp_web"
  },
  "data": {
    "message": {
      "id": "3EB05DCE1D4036FCE241C6",
      "chat_id": "5511999999999@s.whatsapp.net",
      "author": {
        "id": "5511888888888@s.whatsapp.net",
        "phone": "5511888888888"
      },
      "direction": "out",
      "sent_by": "api",
      "sent_at": "2026-10-17T12:00:00.000Z",
      "category": "conversation",
      "type": "carousel",
      "text": "Nossos destaques",
      "cards": [
        {
          "type": "image",
          "mime_type": "image/jpeg",
          "text": "Smartphone XYZ\nR$ 1.999",
          "choices": [
            {
              "id": "comprar_xyz",
              "title": "Comprar"
            },
            {
              "title": "Ver no site",
              "action": "url",
              "value": "https://loja.exemplo/xyz"
            }
          ]
        },
        {
          "type": "image",
          "mime_type": "image/jpeg",
          "text": "Fone ABC\nR$ 299",
          "choices": [
            {
              "id": "comprar_fone",
              "title": "Comprar"
            },
            {
              "title": "Falar com vendedor",
              "action": "call",
              "value": "+5511888888888"
            }
          ]
        }
      ]
    },
    "chat": {
      "id": "5511999999999@s.whatsapp.net",
      "lid": "123456789012345@lid",
      "type": "direct"
    }
  }
}
```

### message.status

`sent`, `delivered`, `read` e `played` (áudio e voz), um evento por mudança; `failed` se o envio falhar. [O evento `message.status`](/webhook/message.status)

```json
{
  "id": "evt_01JAB3K9ZQ7V0M4T8R2X6WYD6J",
  "type": "message.status",
  "created_at": "2026-10-17T12:00:05.000Z",
  "inbox": {
    "id": "r0269625d29bfbd",
    "name": "loja",
    "phone": "5511888888888",
    "channel": "whatsapp_web"
  },
  "data": {
    "chat": {
      "id": "5511999999999@s.whatsapp.net",
      "lid": "123456789012345@lid",
      "type": "direct"
    },
    "status": "delivered",
    "at": "2026-10-17T12:00:05.000Z",
    "messages": [
      {
        "id": "3EB05DCE1D4036FCE241C6"
      }
    ]
  }
}
```

## Quando o contato responde

### message.received

O contato tocou no botão **Comprar** do primeiro cartão. `kind` é `template_button` (é assim que o WhatsApp manda o clique no carrossel) e `reply_to` é o id do carrossel. [O evento `message.received`](/webhook/message.received)

```json
{
  "id": "evt_01JAB3M2K8P4R6T8V0X2Z4B6D8",
  "type": "message.received",
  "created_at": "2026-10-17T12:03:00.000Z",
  "inbox": {
    "id": "r0269625d29bfbd",
    "name": "loja",
    "phone": "5511888888888",
    "channel": "whatsapp_web"
  },
  "data": {
    "message": {
      "id": "AC1FACA14F3FA7A19DB5FB19D7035506",
      "chat_id": "5511999999999@s.whatsapp.net",
      "author": {
        "id": "5511999999999@s.whatsapp.net",
        "phone": "5511999999999",
        "lid": "123456789012345@lid",
        "name": "Maria"
      },
      "direction": "in",
      "sent_at": "2026-10-17T12:03:00.000Z",
      "category": "conversation",
      "type": "interactive_reply",
      "kind": "template_button",
      "option_id": "comprar_xyz",
      "text": "Comprar",
      "reply_to": "3EB05DCE1D4036FCE241C6"
    },
    "chat": {
      "id": "5511999999999@s.whatsapp.net",
      "lid": "123456789012345@lid",
      "type": "direct"
    }
  }
}
```

