> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wppfy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Enviar menú interactivo (botones, carrusel, lista o encuesta)

> Este endpoint ofrece una interfaz unificada para el envío de cuatro tipos principales de mensajes interactivos:
- Botones: Para acciones rápidas y directas
- Carrusel de botones: Para una lista horizontal de botones con imágenes
- Listas: Para menús organizados en secciones
- Encuestas: Para recopilar opiniones y votaciones

**Soporte para campos de seguimiento**: Este endpoint también admite `track_source` y `track_id` documentados en la tag **"Enviar Mensaje"**.

## Estructura base del payload

Todas las solicitudes siguen esta estructura base:

```json
{
  "number": "5511999999999",
  "type": "button|button_legacy|list|poll|carousel",
  "text": "Texto principal da mensagem",
  "choices": ["opções baseadas no tipo escolhido"],
  "footerText": "Texto do rodapé (opcional para botões e listas)",
  "listButton": "Texto do botão (para listas)",
  "selectableCount": "Número de opções selecionáveis (apenas para enquetes)"
}
```

## Tipos de mensajes interactivos

### 1. Botones (type: "button")

Crea botones interactivos con diferentes funcionalidades de acción.

#### Campos específicos
- `footerText`: Texto opcional mostrado debajo del mensaje principal
- `choices`: Array de opciones que se convertirán en botones

#### Formatos de botones
Cada botón puede configurarse usando `|` (pipe) o `\n` (salto de línea) como separadores:

- **Botón de respuesta**:
  - `"texto|id"` o
  - `"texto\nid"` o
  - `"texto"` (el ID será igual al texto)

- **Botón de copia**:
  - `"texto|copy:código"` o
  - `"texto\ncopy:código"`

- **Botón de llamada**:
  - `"texto|call:+5511999999999"` o
  - `"texto\ncall:+5511999999999"`

- **Botón de URL**:
  - `"texto|https://exemplo.com"` o
  - `"texto|url:https://exemplo.com"`

#### Botones con imagen, video o documento
El encabezado del botón puede llevar una imagen, un video o un documento en `file`, por URL o base64, como en
`/send/media`. El tipo se obtiene del propio archivo; para forzarlo, envíe `mimetype`: `image`, `video`, `document` o el MIME type del archivo (por ejemplo, `video/mp4`). El documento usa el
nombre de `docName`; sin él, el nombre del archivo.

El audio no se admite en el botón: WhatsApp no tiene audio en el encabezado, y la API responde `400`. Envíe el audio antes,
con `/send/media`. Sin `mimetype`, la API reconoce el audio por la extensión de la URL o por el inicio del base64; en una
URL sin extensión, indique el `mimetype`.

```json
{
  "number": "5511999999999",
  "type": "button",
  "text": "Escolha um produto:",
  "file": "https://exemplo.com/produto1.jpg",
  "choices": [
    "Produto A|prod_a",
    "Mais Info|https://exemplo.com/produto-a",
    "Produto B|prod_b",
    "Ligar|call:+5511999999999"
  ],
  "footerText": "Produtos em destaque"
}
```

```json
{
  "number": "5511999999999",
  "type": "button",
  "text": "Tabela de preços de outubro",
  "file": "https://exemplo.com/tabela.pdf",
  "docName": "Tabela de preços.pdf",
  "choices": ["Quero comprar|comprar", "Falar com vendedor|vendedor"]
}
```

Si el medio no se descarga o no se sube a WhatsApp, el botón se envía sin él.

#### Botones en formato legado (type: "button_legacy")

Use `button_legacy` solo cuando necesite enviar los botones de respuesta del
formato anterior. El formato de `choices` es:

- `"texto|id"`
- `"texto\nid"`
- `"texto|reply:id"`
- `"texto"` — el propio texto se usará como ID

Este modo crea solo botones de respuesta. Las acciones de URL, llamada y copia y
el medio en `file` siguen disponibles en el formato actual `type: "button"`.

```json
{
  "number": "5511999999999",
  "type": "button_legacy",
  "text": "Deseja continuar?",
  "choices": [
    "Sim|confirmar",
    "Não|reply:cancelar"
  ],
  "footerText": "Escolha uma opção"
}
```

#### Ejemplo completo
```json
{
  "number": "5511999999999",
  "type": "button",
  "text": "Como podemos ajudar?",
  "choices": [
    "Suporte Técnico|suporte",
    "Fazer Pedido|pedido",
    "Nosso Site|https://exemplo.com",
    "Falar Conosco|call:+5511999999999"
  ],
  "footerText": "Escolha uma das opções abaixo"
}
```

#### Limitaciones y compatibilidad
> **Importante**: Al combinar botones de respuesta con otros tipos (call, url, copy) en el mismo mensaje, se mostrará el aviso: "No es posible mostrar este mensaje en WhatsApp Web. Abra WhatsApp en su teléfono para verlo."

### 2. Listas (type: "list")

Crea menús organizados en secciones con elementos seleccionables.

#### Campos específicos
- `listButton`: Texto del botón que abre la lista
- `footerText`: Texto opcional del pie de página
- `choices`: Array con las secciones y los elementos de la lista

#### Formato de las choices
- `"[Título da Seção]"`: Inicia una nueva sección
- `"texto|id|descrição"`: Elemento de la lista con:
  - texto: Etiqueta del elemento
  - id: Identificador único, opcional
  - descrição: Texto descriptivo adicional y opcional

#### Ejemplo completo
```json
{
  "number": "5511999999999",
  "type": "list",
  "text": "Catálogo de Produtos",
  "choices": [
    "[Eletrônicos]",
    "Smartphones|phones|Últimos lançamentos",
    "Notebooks|notes|Modelos 2024",
    "[Acessórios]",
    "Fones|fones|Bluetooth e com fio",
    "Capas|cases|Proteção para seu device"
  ],
  "listButton": "Ver Catálogo",
  "footerText": "Preços sujeitos a alteração"
}
```

### 3. Encuestas (type: "poll")

Crea encuestas interactivas para votación.

#### Campos específicos
- `selectableCount`: Número de opciones que pueden seleccionarse (predeterminado: 1)
- `choices`: Array simple con las opciones de voto

#### Ejemplo completo
```json
{
  "number": "5511999999999",
  "type": "poll",
  "text": "Qual horário prefere para atendimento?",
  "choices": [
    "Manhã (8h-12h)",
    "Tarde (13h-17h)",
    "Noite (18h-22h)"
  ],
  "selectableCount": 1
}
```

### 4. Carousel (type: "carousel")

Crea un carrusel de tarjetas con imágenes y botones interactivos.

#### Campos específicos
- `choices`: Array con los elementos del carrusel en el siguiente orden:
  - `[Texto do cartão]`: Texto de la tarjeta entre corchetes
  - `{URL ou base64 da imagem}`: Imagen entre llaves
  - Botones de la tarjeta (uno por línea):
    - `"texto|copy:código"` para botón de copiar
    - `"texto|https://url"` para botón de enlace
    - `"texto|call:+número"` para botón de llamada

#### Ejemplo completo
```json
{
  "number": "5511999999999",
  "type": "carousel",
  "text": "Conheça nossos produtos",
  "choices": [
    "[Smartphone XYZ\nO mais avançado smartphone da linha]",
    "{https://exemplo.com/produto1.jpg}",
    "Copiar Código|copy:PROD123",
    "Ver no Site|https://exemplo.com/xyz",
    "Fale Conosco|call:+5511999999999",
    "[Notebook ABC\nO notebook ideal para profissionais]",
    "{https://exemplo.com/produto2.jpg}",
    "Copiar Código|copy:NOTE456",
    "Comprar Online|https://exemplo.com/abc",
    "Suporte|call:+5511988888888"
  ]
}
```

> **Nota**: Creamos otro endpoint para carrusel: `/send/carousel`; funciona de la misma forma, pero con otro formato de payload. Elija el que le resulte más sencillo.

## Términos de uso

Los recursos de botones interactivos y listas pueden ser descontinuados en cualquier momento sin previo aviso. No nos responsabilizamos por cualquier cambio o indisponibilidad de estos recursos.

### Alternativas y compatibilidad

Considerando la naturaleza dinámica de estos recursos, nuestro endpoint fue diseñado para facilitar la migración entre diferentes tipos de mensajes (botones, listas y encuestas).

Recomendamos crear sus flujos de forma flexible, preparados para alternar entre los diferentes tipos.

En caso de descontinuación de algún recurso, podrá migrar fácilmente a otro tipo de mensaje solo cambiando el campo "type" en el payload, manteniendo la misma estructura de choices.




## OpenAPI

````yaml /openapi-es.json post /send/menu
openapi: 3.1.0
info:
  title: WppFy -  WhatsApp API
  version: 1.0.0
  description: >
    API para la gestión de instancias de WhatsApp y comunicaciones.


    ## Recomendación Importante: WhatsApp Business

    **Se RECOMIENDA ENCARECIDAMENTE usar cuentas de WhatsApp Business** en lugar
    de WhatsApp normal para la integración; WhatsApp normal puede presentar
    inconsistencias, desconexiones, limitaciones e inestabilidad durante el uso
    con nuestra API.


    ## Autenticación

    - Los endpoints regulares requieren un header 'token' con el token de la
    instancia


    ## Estados de la Instancia

    Las instancias pueden estar en los siguientes estados:

    - `disconnected`: Desconectado de WhatsApp

    - `connecting`: En proceso de conexión

    - `connected`: Conectado y autenticado con éxito
servers:
  - url: https://api.wppfy.com
security:
  - token: []
tags:
  - name: Instancia
    description: >
      Operaciones relacionadas con el ciclo de vida de una instancia, como
      conectar,

      desconectar y verificar el estado.
  - name: Proxy
    description: >
      WppFy opera con un proxy interno por defecto.

      Puede mantener este valor predeterminado, configurar un proxy propio
      mediante `proxy_url` o usar su celular Android como proxy instalando la
      app en https://github.com/WppFy/silver_proxy_apk (APK directo:
      https://github.com/WppFy/silver_proxy_apk/raw/refs/heads/main/silver_proxy.apk).

      Si no se envía nada, se sigue usando el proxy interno. Las IPs son
      brasileñas; para clientes internacionales, considere un proxy de la región
      del cliente.
  - name: Perfil
    description: >
      Operaciones relacionadas con el perfil de la instancia de WhatsApp, como
      cambiar

      el nombre y la imagen de perfil.
  - name: Business
    description: >
      ⚠️ **EXPERIMENTAL** - Endpoints aún no probados por completo.


      Operaciones relacionadas con el perfil comercial de WhatsApp Business.

      Permite consultar y actualizar datos del perfil comercial como
      descripción,

      dirección, email, categorías y gestionar el catálogo de productos.


      **Requisitos:**

      - La cuenta conectada actualmente debe ser una cuenta **WhatsApp
      Business**

      - Las cuentas personales de WhatsApp no tienen perfil comercial


      **Nota:** Estos endpoints pueden no funcionar como se espera.

      Reporte los problemas encontrados.
  - name: Llamadas
    description: |
      Operaciones relacionadas con llamadas por WhatsApp.
      Permite realizar y rechazar llamadas de forma programática.
  - name: Enviar Mensaje
    description: >
      Endpoints para el envío de mensajes de WhatsApp con diferentes tipos de
      contenido.


      ## Campos Opcionales Comunes


      Todos los endpoints de envío de mensajes soportan los siguientes campos
      opcionales:


      - **`delay`** *(integer)*: Retraso en milisegundos antes del envío
        - Durante el retraso aparecerá "Escribiendo..." o "Grabando audio..." según el tipo
        - Ejemplo: `5000` (5 segundos)

      - **`readchat`** *(boolean)*: Marcar el chat como leído después del envío
        - Quita el contador de mensajes no leídos del chat
        - Ejemplo: `true`

      - **`readmessages`** *(boolean)*: Marcar los últimos mensajes recibidos
      como leídos
        - Marca los últimos 10 mensajes **recibidos** (no enviados por usted) como leídos
        - Útil para confirmar la lectura de mensajes pendientes antes de responder
        - A diferencia de `readchat`, que solo quita el contador de no leídos
        - Ejemplo: `true`

      - **`replyid`** *(string)*: ID del mensaje a responder
        - Crea una respuesta vinculada al mensaje original
        - El soporte varía según el tipo de mensaje
        - Ejemplo: `"3A12345678901234567890123456789012"`

      - **`mentions`** *(string)*: Números a mencionar (solo para envíos en
      grupos)
        - Números específicos: `"5511999999999,5511888888888"`
        - Mencionar a todos: `"all"`

      - **`forward`** *(boolean)*: Marca el mensaje como reenviado en WhatsApp
        - Agrega el indicador "Reenviado" al mensaje
        - Ejemplo: `true`

      - **`track_source`** *(string)*: Origen del rastreo del mensaje
        - Identifica el sistema o la fuente que está enviando el mensaje
        - Útil para integraciones (ej.: "chatwoot", "crm", "chatbot")
        - Ejemplo: `"chatwoot"`

      - **`track_id`** *(string)*: ID para el rastreo del mensaje
        - Identificador libre para dar seguimiento al mensaje en sistemas externos
        - Permite correlacionar mensajes entre diferentes plataformas
        - **Nota**: El sistema acepta valores duplicados; no hay validación de unicidad
        - Use el mismo ID en varios mensajes si tiene sentido para su integración
        - Ejemplo: `"msg_123456789"`

      ### Envío a Grupos

      - **`number`** *(string)*: Para enviar un mensaje a un grupo, use el ID
      del grupo que termina en `@g.us`
        - Ejemplo: `"120363012345678901@g.us"`
        - **Cómo obtener el ID del grupo:**
          - Use el `chatid` del webhook recibido cuando alguien envía un mensaje en el grupo
          - Use el endpoint `GET /group/list` para listar todos los grupos y sus IDs

      ## Placeholders Disponibles


      Todos los endpoints de envío de mensajes soportan placeholders dinámicos
      para personalización automática:


      ### Campos de Nombre

      - **`{{name}}`**: Nombre consolidado del chat, usando la primera opción
      disponible:
        1. Nombre del lead (`lead_name`)
        2. Nombre completo del lead (`lead_fullName`)
        3. Nombre del contacto en WhatsApp (`wa_contactName`)
        4. Nombre del perfil de WhatsApp (`wa_name`)

      - **`{{first_name}}`**: Primera palabra válida del nombre consolidado
      (mínimo 2 caracteres)


      ### Campos de WhatsApp

      - **`{{wa_name}}`**: Nombre del perfil de WhatsApp

      - **`{{wa_contactName}}`**: Nombre del contacto tal como está guardado en
      WhatsApp


      ### Campos del Lead

      - **`{{lead_name}}`**: Nombre del lead

      - **`{{lead_fullName}}`**: Nombre completo del lead

      - **`{{lead_personalid}}`**: ID personal (CPF, CNPJ, etc)

      - **`{{lead_email}}`**: Email del lead

      - **`{{lead_status}}`**: Estado actual del lead

      - **`{{lead_notes}}`**: Anotaciones del lead

      - **`{{lead_assignedAttendant_id}}`**: ID del agente asignado


      ### Campos Personalizados

      Los campos agregados mediante custom fields son accesibles usando
      `{{lead_field01}}` a `{{lead_field20}}` o usando `{{nomedocampo}}`
      definido en `/instance/updateFieldsMap`.


      ### Ejemplo de Uso

      ```

      ¡Hola {{name}}! Vi que usted trabaja en {{company}}.

      ¿Su email {{lead_email}} es correcto?

      ```


      **💡 Consejo**: Use `/chat/find` para buscar los datos del chat y ver los
      campos disponibles antes de enviar mensajes con placeholders.
  - name: Mensaje Async
    description: >
      Controles operativos de la cola interna de envío asíncrono usada cuando un
      endpoint de envío recibe `async=true`.


      Esta sección sirve para:

      - consultar el estado actual de la cola async

      - configurar el delay entre mensajes enviados con `async=true`

      - limpiar el backlog pendiente y cancelar mensajes aún no concluidos


      Alcance:

      - cubre solo la cola interna de mensajes directos async

      - no modifica mensajes ya enviados correctamente
  - name: Acciones en el mensaje y Búsqueda
  - name: Chats
  - name: Contactos
  - name: Bloqueos
  - name: Etiquetas
  - name: Grupos y Comunidades
  - name: Newsletters y Canales
    description: >
      Operaciones para la lectura y el seguimiento de canales de WhatsApp
      (newsletters).


      Casos de uso principales:

      - listar posts ya publicados en un canal

      - editar posts recientes de un canal

      - eliminar posts recientes de un canal

      - consultar views y reacciones de los posts

      - integrar canales sin necesidad de persistir los mensajes localmente


      Observaciones:

      - `/newsletter/messages` devuelve el contenido de los posts

      - `/newsletter/messages/edit` edita el contenido de posts recientes

      - `/newsletter/messages/delete` elimina posts recientes

      - las views (`viewsCount`) y reactions (`reactionCounts`) vienen en cada
      post de `/newsletter/messages`, no por evento de webhook

      - `/newsletter/updates` está obsoleta: WhatsApp no responde y la API
      devuelve 504

      - los newsletters usan rutas propias y no deben usar `/message/edit` ni
      `/message/delete`
  - name: Respuestas Rápidas
    description: >
      Gestión de respuestas rápidas para agilizar la atención.


      **⚠️ Importante**: Este recurso solo es útil si utiliza un sistema
      frontend/interfaz

      personalizada para registrar y utilizar las respuestas. La API solo
      almacena las respuestas, 

      pero no las aplica automáticamente.


      ### Cómo funciona:

      - **Crear**: Registre respuestas predefinidas con títulos y contenido

      - **Listar**: Recupere todas las respuestas registradas para mostrarlas en
      su interfaz

      - **Usar**: Su sistema frontend puede usar estas respuestas para agilizar
      la escritura


      ### Casos de uso:

      - Interfaces web personalizadas de atención

      - Apps móviles con sugerencias de respuesta

      - Sistemas CRM con plantillas de mensaje

      - Herramientas de productividad para agentes


      **No es un chatbot**: Para respuestas automáticas, use los recursos de
      Chatbot.
  - name: CRM
    description: >
      Sistema completo de gestión de relaciones con clientes integrado a la API.


      **💾 Almacenamiento interno**: Todos los datos de los leads se guardan
      directamente en la API,

      eliminando la necesidad de bases de datos externas. Su aplicación puede
      enfocarse solo

      en la interfaz y la lógica de negocio.


      ### Recursos disponibles:

      - **📋 20+ campos personalizables**: Nombre, teléfono, email, empresa,
      observaciones, etc.

      - **🏷️ Sistema de etiquetas**: Organice y categorice sus contactos

      - **🔍 Búsqueda avanzada**: Filtre por cualquier campo o etiqueta

      - **📊 Historial completo**: Todas las interacciones se registran
      automáticamente


      ### 🎯 Placeholders en mensajes:

      Use variables dinámicas en los mensajes para la personalización
      automática:


      ```

      ¡Hola {{nombre}}! Vi que trabaja en {{empresa}}.

      ¿Su email {{email}} es correcto?

      Observaciones: {{observaciones}}

      ```


      ### Flujo típico:

      1. **Captura**: Los leads llegan vía WhatsApp o formularios

      2. **Enriquecimiento**: Agregue datos usando `/chat/editLead`

      3. **Segmentación**: Organice con etiquetas

      4. **Comunicación**: Envíe mensajes personalizados con placeholders

      5. **Seguimiento**: El historial se guarda automáticamente


      **Ideal para**: Ventas, marketing, atención, calificación de leads
  - name: Integración con Chatwoot
    description: >
      **🚧 INTEGRACIÓN BETA - Sistema de integración con Chatwoot para atención
      unificada**


      **⚠️ AVISO**: Esta integración está en fase BETA. Úsela bajo su propio
      riesgo. Recomendamos realizar pruebas en un entorno no productivo antes de
      usarla en producción.


      Esta categoría contiene recursos para configurar y gestionar la
      integración con Chatwoot, una plataforma de atención al cliente
      open-source. La integración permite centralizar las conversaciones de
      WhatsApp en Chatwoot.


      ### Recursos disponibles:

      - 🔧 **Configuración Completa**: Configure URL, tokens y credenciales de
      Chatwoot

      - 📬 **Sincronización Bidireccional**: Los mensajes nuevos entre WhatsApp
      y Chatwoot se sincronizan automáticamente

      - 📱 **Gestión de Contactos**: Sincronización automática de nombres y
      teléfonos

      - 🔄 **Actualización LID→PN**: Migración automática de Local ID a Phone
      Number

      - 🏷️ **Nombres Inteligentes**: Sistema de nombres con tilde (~) para
      actualización automática

      - 🚫 **Separación de Grupos**: Opción para ignorar grupos en la
      sincronización

      - 👤 **Firma de Mensajes**: Identificación del agente en los mensajes
      enviados

      - 🔗 **Webhook Automático**: URL generada automáticamente para configurar
      en Chatwoot


      ### 🏷️ Sistema de Nombres Inteligentes:

      - **Nombres con tilde (~)**: Se actualizan automáticamente cuando el
      contacto modifica su nombre en WhatsApp

      - **Nombres específicos**: Para un nombre fijo, quite la tilde (~) del
      nombre en Chatwoot

      - **Ejemplo**: "~Juan Pérez" = automático, "Juan Pérez" = fijo

      - **Migración LID→PN**: Sin duplicación de conversaciones durante la
      transición

      - **Respuestas nativas**: Aparecen directamente en Chatwoot sin marcas
      externas


      ### ⚠️ Limitaciones conocidas:

      - **Sincronización del historial**: No implementada - solo se sincronizan
      los mensajes nuevos


      ### Casos de uso:

      - Atención centralizada en Chatwoot

      - Equipos de soporte con múltiples agentes

      - Integración con CRM mediante Chatwoot

      - Centralización de canales de comunicación

      - Gestión automática de contactos y nombres


      **Ideal para**: Empresas con equipos de atención, call centers, soporte
      técnico (en entorno de pruebas)


      **Requiere**: Instancia de Chatwoot configurada, tokens de API y entorno
      de pruebas


      **🚧 Recuerde**: Integración en BETA - las funcionalidades pueden cambiar
      sin previo aviso
  - name: Server-Sent Events (SSE)
paths:
  /send/menu:
    post:
      tags:
        - Enviar Mensaje
      summary: Enviar menú interactivo (botones, carrusel, lista o encuesta)
      description: >
        Este endpoint ofrece una interfaz unificada para el envío de cuatro
        tipos principales de mensajes interactivos:

        - Botones: Para acciones rápidas y directas

        - Carrusel de botones: Para una lista horizontal de botones con imágenes

        - Listas: Para menús organizados en secciones

        - Encuestas: Para recopilar opiniones y votaciones


        **Soporte para campos de seguimiento**: Este endpoint también admite
        `track_source` y `track_id` documentados en la tag **"Enviar Mensaje"**.


        ## Estructura base del payload


        Todas las solicitudes siguen esta estructura base:


        ```json

        {
          "number": "5511999999999",
          "type": "button|button_legacy|list|poll|carousel",
          "text": "Texto principal da mensagem",
          "choices": ["opções baseadas no tipo escolhido"],
          "footerText": "Texto do rodapé (opcional para botões e listas)",
          "listButton": "Texto do botão (para listas)",
          "selectableCount": "Número de opções selecionáveis (apenas para enquetes)"
        }

        ```


        ## Tipos de mensajes interactivos


        ### 1. Botones (type: "button")


        Crea botones interactivos con diferentes funcionalidades de acción.


        #### Campos específicos

        - `footerText`: Texto opcional mostrado debajo del mensaje principal

        - `choices`: Array de opciones que se convertirán en botones


        #### Formatos de botones

        Cada botón puede configurarse usando `|` (pipe) o `\n` (salto de línea)
        como separadores:


        - **Botón de respuesta**:
          - `"texto|id"` o
          - `"texto\nid"` o
          - `"texto"` (el ID será igual al texto)

        - **Botón de copia**:
          - `"texto|copy:código"` o
          - `"texto\ncopy:código"`

        - **Botón de llamada**:
          - `"texto|call:+5511999999999"` o
          - `"texto\ncall:+5511999999999"`

        - **Botón de URL**:
          - `"texto|https://exemplo.com"` o
          - `"texto|url:https://exemplo.com"`

        #### Botones con imagen, video o documento

        El encabezado del botón puede llevar una imagen, un video o un documento
        en `file`, por URL o base64, como en

        `/send/media`. El tipo se obtiene del propio archivo; para forzarlo,
        envíe `mimetype`: `image`, `video`, `document` o el MIME type del
        archivo (por ejemplo, `video/mp4`). El documento usa el

        nombre de `docName`; sin él, el nombre del archivo.


        El audio no se admite en el botón: WhatsApp no tiene audio en el
        encabezado, y la API responde `400`. Envíe el audio antes,

        con `/send/media`. Sin `mimetype`, la API reconoce el audio por la
        extensión de la URL o por el inicio del base64; en una

        URL sin extensión, indique el `mimetype`.


        ```json

        {
          "number": "5511999999999",
          "type": "button",
          "text": "Escolha um produto:",
          "file": "https://exemplo.com/produto1.jpg",
          "choices": [
            "Produto A|prod_a",
            "Mais Info|https://exemplo.com/produto-a",
            "Produto B|prod_b",
            "Ligar|call:+5511999999999"
          ],
          "footerText": "Produtos em destaque"
        }

        ```


        ```json

        {
          "number": "5511999999999",
          "type": "button",
          "text": "Tabela de preços de outubro",
          "file": "https://exemplo.com/tabela.pdf",
          "docName": "Tabela de preços.pdf",
          "choices": ["Quero comprar|comprar", "Falar com vendedor|vendedor"]
        }

        ```


        Si el medio no se descarga o no se sube a WhatsApp, el botón se envía
        sin él.


        #### Botones en formato legado (type: "button_legacy")


        Use `button_legacy` solo cuando necesite enviar los botones de respuesta
        del

        formato anterior. El formato de `choices` es:


        - `"texto|id"`

        - `"texto\nid"`

        - `"texto|reply:id"`

        - `"texto"` — el propio texto se usará como ID


        Este modo crea solo botones de respuesta. Las acciones de URL, llamada y
        copia y

        el medio en `file` siguen disponibles en el formato actual `type:
        "button"`.


        ```json

        {
          "number": "5511999999999",
          "type": "button_legacy",
          "text": "Deseja continuar?",
          "choices": [
            "Sim|confirmar",
            "Não|reply:cancelar"
          ],
          "footerText": "Escolha uma opção"
        }

        ```


        #### Ejemplo completo

        ```json

        {
          "number": "5511999999999",
          "type": "button",
          "text": "Como podemos ajudar?",
          "choices": [
            "Suporte Técnico|suporte",
            "Fazer Pedido|pedido",
            "Nosso Site|https://exemplo.com",
            "Falar Conosco|call:+5511999999999"
          ],
          "footerText": "Escolha uma das opções abaixo"
        }

        ```


        #### Limitaciones y compatibilidad

        > **Importante**: Al combinar botones de respuesta con otros tipos
        (call, url, copy) en el mismo mensaje, se mostrará el aviso: "No es
        posible mostrar este mensaje en WhatsApp Web. Abra WhatsApp en su
        teléfono para verlo."


        ### 2. Listas (type: "list")


        Crea menús organizados en secciones con elementos seleccionables.


        #### Campos específicos

        - `listButton`: Texto del botón que abre la lista

        - `footerText`: Texto opcional del pie de página

        - `choices`: Array con las secciones y los elementos de la lista


        #### Formato de las choices

        - `"[Título da Seção]"`: Inicia una nueva sección

        - `"texto|id|descrição"`: Elemento de la lista con:
          - texto: Etiqueta del elemento
          - id: Identificador único, opcional
          - descrição: Texto descriptivo adicional y opcional

        #### Ejemplo completo

        ```json

        {
          "number": "5511999999999",
          "type": "list",
          "text": "Catálogo de Produtos",
          "choices": [
            "[Eletrônicos]",
            "Smartphones|phones|Últimos lançamentos",
            "Notebooks|notes|Modelos 2024",
            "[Acessórios]",
            "Fones|fones|Bluetooth e com fio",
            "Capas|cases|Proteção para seu device"
          ],
          "listButton": "Ver Catálogo",
          "footerText": "Preços sujeitos a alteração"
        }

        ```


        ### 3. Encuestas (type: "poll")


        Crea encuestas interactivas para votación.


        #### Campos específicos

        - `selectableCount`: Número de opciones que pueden seleccionarse
        (predeterminado: 1)

        - `choices`: Array simple con las opciones de voto


        #### Ejemplo completo

        ```json

        {
          "number": "5511999999999",
          "type": "poll",
          "text": "Qual horário prefere para atendimento?",
          "choices": [
            "Manhã (8h-12h)",
            "Tarde (13h-17h)",
            "Noite (18h-22h)"
          ],
          "selectableCount": 1
        }

        ```


        ### 4. Carousel (type: "carousel")


        Crea un carrusel de tarjetas con imágenes y botones interactivos.


        #### Campos específicos

        - `choices`: Array con los elementos del carrusel en el siguiente orden:
          - `[Texto do cartão]`: Texto de la tarjeta entre corchetes
          - `{URL ou base64 da imagem}`: Imagen entre llaves
          - Botones de la tarjeta (uno por línea):
            - `"texto|copy:código"` para botón de copiar
            - `"texto|https://url"` para botón de enlace
            - `"texto|call:+número"` para botón de llamada

        #### Ejemplo completo

        ```json

        {
          "number": "5511999999999",
          "type": "carousel",
          "text": "Conheça nossos produtos",
          "choices": [
            "[Smartphone XYZ\nO mais avançado smartphone da linha]",
            "{https://exemplo.com/produto1.jpg}",
            "Copiar Código|copy:PROD123",
            "Ver no Site|https://exemplo.com/xyz",
            "Fale Conosco|call:+5511999999999",
            "[Notebook ABC\nO notebook ideal para profissionais]",
            "{https://exemplo.com/produto2.jpg}",
            "Copiar Código|copy:NOTE456",
            "Comprar Online|https://exemplo.com/abc",
            "Suporte|call:+5511988888888"
          ]
        }

        ```


        > **Nota**: Creamos otro endpoint para carrusel: `/send/carousel`;
        funciona de la misma forma, pero con otro formato de payload. Elija el
        que le resulte más sencillo.


        ## Términos de uso


        Los recursos de botones interactivos y listas pueden ser descontinuados
        en cualquier momento sin previo aviso. No nos responsabilizamos por
        cualquier cambio o indisponibilidad de estos recursos.


        ### Alternativas y compatibilidad


        Considerando la naturaleza dinámica de estos recursos, nuestro endpoint
        fue diseñado para facilitar la migración entre diferentes tipos de
        mensajes (botones, listas y encuestas).


        Recomendamos crear sus flujos de forma flexible, preparados para
        alternar entre los diferentes tipos.


        En caso de descontinuación de algún recurso, podrá migrar fácilmente a
        otro tipo de mensaje solo cambiando el campo "type" en el payload,
        manteniendo la misma estructura de choices.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: >-
                    ID del chat al que se enviará el mensaje. Puede ser un
                    número de teléfono en formato internacional, un ID de grupo
                    (`@g.us`), un ID de usuario (con `@s.whatsapp.net` o
                    `@lid`).
                  example: '5511999999999'
                type:
                  type: string
                  description: >-
                    Tipo del menú. Use button para el formato actual y
                    button_legacy solo para botones de respuesta en el formato
                    anterior.
                  enum:
                    - button
                    - button_legacy
                    - list
                    - poll
                    - carousel
                  example: list
                text:
                  type: string
                  description: Texto principal (acepta placeholders)
                  example: 'Elija una opción:'
                footerText:
                  type: string
                  description: Texto del pie de página (opcional)
                  example: Menú de servicios
                listButton:
                  type: string
                  description: Texto del botón principal
                  example: Ver opciones
                selectableCount:
                  type: integer
                  description: Número máximo de opciones seleccionables (para encuestas)
                  example: 1
                choices:
                  type: array
                  description: Lista de opciones. Use [Título] para secciones en listas
                  items:
                    type: string
                  example:
                    - '[Eletrônicos]'
                    - Smartphones|phones|Últimos lançamentos
                    - Notebooks|notes|Modelos 2024
                    - '[Acessórios]'
                    - Fones|fones|Bluetooth e com fio
                    - Capas|cases|Proteção para seu device
                file:
                  type: string
                  description: >-
                    Medio del encabezado (type: button): imagen, video o
                    documento, por URL o base64, como en `/send/media`. El audio
                    devuelve `400`.
                  example: https://exemplo.com/produto1.jpg
                mimetype:
                  type: string
                  description: >-
                    Fuerza el tipo del `file` (opcional): `image`, `video`,
                    `document` o el MIME type del archivo, como `video/mp4`. Sin
                    él, el tipo se obtiene del archivo; cualquier otro valor
                    responde `400`.
                  example: video/mp4
                docName:
                  type: string
                  description: >-
                    Nombre del archivo cuando el `file` es un documento. Sin él,
                    el nombre del archivo.
                  example: Lista de precios.pdf
                replyid:
                  type: string
                  description: ID del mensaje al que se responderá
                  example: 3EB0538DA65A59F6D8A251
                mentions:
                  type: string
                  description: Números a mencionar (separados por coma)
                  example: 5511999999999,5511888888888
                readchat:
                  type: boolean
                  description: Marca la conversación como leída después del envío
                  example: true
                readmessages:
                  type: boolean
                  description: Marca los últimos mensajes recibidos como leídos
                  example: true
                delay:
                  type: integer
                  description: >-
                    Retraso en milisegundos antes del envío; durante el retraso
                    aparecerá 'Escribiendo...'
                  example: 1000
                track_source:
                  type: string
                  description: Origen de rastreo del mensaje
                  example: chatwoot
                track_id:
                  type: string
                  description: >-
                    ID para el seguimiento del mensaje (acepta valores
                    duplicados)
                  example: msg_123456789
                async:
                  type: boolean
                  description: >-
                    Si es true, envía el mensaje de forma asíncrona mediante la
                    cola interna
                  example: false
              required:
                - number
                - type
                - text
                - choices
            examples:
              button:
                summary: Botones de respuesta
                value:
                  number: '5511999999999'
                  type: button
                  text: Como podemos ajudar?
                  choices:
                    - Suporte|suporte
                    - Fazer pedido|pedido
              list:
                summary: Lista de opciones
                value:
                  number: '5511999999999'
                  type: list
                  text: Escolha uma categoria
                  listButton: Ver opções
                  choices:
                    - '[Atendimento]'
                    - Suporte|suporte|Falar com o suporte
                    - Financeiro|financeiro|Falar com o financeiro
              poll:
                summary: Encuesta de opción única
                value:
                  number: '5511999999999'
                  type: poll
                  text: Qual horário prefere?
                  selectableCount: 1
                  choices:
                    - Manhã
                    - Tarde
      responses:
        '200':
          description: Menú enviado correctamente
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Message'
                  - type: object
                    properties:
                      response:
                        type: object
                        properties:
                          status:
                            type: string
                            example: success
                          message:
                            type: string
                            example: Menú enviado correctamente
        '400':
          description: Solicitud inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Faltan campos obligatorios o tipo de menú inválido
        '401':
          description: No autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Token inválido
        '429':
          description: Límite de solicitudes excedido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Límite de solicitudes excedido
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Error al enviar el menú
components:
  schemas:
    Message:
      type: object
      description: Representa un mensaje intercambiado en el sistema
      properties:
        id:
          type: string
          format: uuid
          description: >-
            ID único interno del mensaje (formato r + 7 caracteres hex
            aleatorios)
        messageid:
          type: string
          description: ID original del mensaje en el proveedor
        chatid:
          type: string
          description: ID de la conversación relacionada
        sender:
          type: string
          description: ID del remitente del mensaje
        senderName:
          type: string
          description: Nombre visible del remitente
        isGroup:
          type: boolean
          description: Indica si es un mensaje de grupo
          default: false
        fromMe:
          type: boolean
          description: Indica si el mensaje fue enviado por el usuario
          default: false
        messageType:
          type: string
          description: Tipo de contenido del mensaje
        source:
          type: string
          description: Plataforma de origen del mensaje
        messageTimestamp:
          type: integer
          description: Timestamp original del mensaje en milisegundos
          default: 0
        status:
          type: string
          description: >
            Estado del ciclo de vida del mensaje.

            Ejemplos comunes: `Queued`, `Canceled`, `Failed`, `Sent`,
            `Delivered`, `Read`.

            En mensajes de grupo, sigue al participante más avanzado:
            `Delivered` cuando al menos uno lo recibió, `Read` cuando al menos
            uno lo leyó y `Played` cuando al menos uno lo escuchó.
        text:
          type: string
          description: Texto original del mensaje
          default: ''
        quoted:
          type: string
          description: ID del mensaje citado/respondido
          default: ''
        edited:
          type: string
          description: Historial de ediciones del mensaje
          default: ''
        reaction:
          type: string
          description: ID del mensaje al que se reaccionó
          default: ''
        vote:
          type: string
          description: Datos de votación de encuestas y listas
          default: ''
        convertOptions:
          type: string
          description: Conversión de opciones del mensaje, lista, encuesta y botones
          default: ''
        buttonOrListid:
          type: string
          description: ID del botón o elemento de lista seleccionado
          default: ''
        owner:
          type: string
          description: Propietario del mensaje
          default: ''
        error:
          type: string
          description: Mensaje de error en caso de que el envío haya fallado
          default: ''
        content:
          description: Contenido bruto del mensaje (JSON serializado o texto)
          oneOf:
            - type: object
              additionalProperties: true
            - type: string
              description: Texto sin procesar cuando no es JSON
        wasSentByApi:
          type: boolean
          description: Indica si el mensaje fue enviado vía API
        pinned:
          type: boolean
          description: >-
            Mensaje fijado en la conversación (fijar y desfijar también llegan
            en `messages_update`, tipos `Pinned` y `Unpinned`)
        sendFunction:
          type: string
          description: Función usada para enviar el mensaje (cuando se envía vía API)
        sendPayload:
          description: >-
            Payload utilizado en el envío cuando está disponible. Los datos de
            medios en base64 se omiten.
          oneOf:
            - type: object
              additionalProperties: true
            - type: string
              description: Texto sin procesar cuando no es JSON
        fileURL:
          type: string
          description: URL o referencia de archivo del mensaje
        callPeer:
          type: object
          description: >-
            Contacto conocido asociado a una llamada, cuando está disponible en
            `messageType: call`.
          properties:
            jid:
              type: string
            name:
              type: string
            imagePreviewUrl:
              type: string
        send_folder_id:
          type: string
          description: Carpeta asociada al envío (cuando corresponda)
        track_source:
          type: string
          description: Origen de rastreo
        track_id:
          type: string
          description: ID de seguimiento (puede repetirse)
        ai_metadata:
          type: object
          description: >-
            Registro de una ronda de la IA. El completo (solicitud al modelo,
            respuesta y `outcome`) queda una sola vez, en el último mensaje del
            contacto al que respondió la ronda, incluso cuando no salió nada
            (error, respuesta descartada). Cada mensaje enviado por la IA lleva
            solo `agent_id` y `turn` (el `id` de ese mensaje del contacto).
          properties:
            agent_id:
              type: string
              description: ID del agente de IA responsable
            turn:
              type: string
              description: >-
                En el mensaje enviado por la IA: el `id` del mensaje del
                contacto donde está el registro completo de la ronda.
            flow_id:
              type: string
              description: >-
                Mensaje enviado por un flujo: el `id` del flujo. El mensaje
                enviado por la IA incluye el `agent_id`.
            request:
              type: object
              description: Datos de la solicitud a la API de IA
              properties:
                messages:
                  type: array
                  description: Historial de mensajes enviados a la API
                tools:
                  type: array
                  description: Herramientas disponibles para el agente
                options:
                  type: object
                  description: Opciones de configuración de la API
                  properties:
                    model:
                      type: string
                    temperature:
                      type: number
                    maxTokens:
                      type: integer
                    topP:
                      type: number
                    frequencyPenalty:
                      type: number
                    presencePenalty:
                      type: number
            response:
              type: object
              description: Respuesta de la API de IA
              properties:
                choices:
                  type: array
                  description: Resultados devueltos por la API
                toolResults:
                  type: array
                  description: Resultados de la ejecución de herramientas
                error:
                  type: string
                  description: Mensaje de error, si lo hay
            outcome:
              type: object
              description: Lo que la ronda hizo realmente (solo en el registro completo).
              properties:
                status:
                  type: string
                  enum:
                    - sent
                    - cancelled
                    - error
                    - empty
                  description: >-
                    `sent`: se envió algo; `cancelled`: descartada (la
                    conversación se pausó, comenzó un flujo o se alcanzó el
                    límite de respuestas por hora); `error`: el proveedor falló;
                    `empty`: nada que enviar.
                texts:
                  type: integer
                  description: Mensajes de texto enviados.
                audio:
                  type: boolean
                  description: Respondió con audio.
                menus:
                  type: integer
                  description: Menús enviados.
                files:
                  type: integer
                  description: Archivos (mensajes registrados) enviados.
                handoff:
                  type: string
                  description: '`chamar_humano`: el resumen para quien atienda.'
                lead:
                  type: array
                  items:
                    type: string
                  description: >-
                    `atualizar_lead`: lo que se guardó en el CRM (`lead_email =
                    ana@exemplo.com; column = Agendado`).
                detail:
                  type: string
                  description: Por qué fue descartada, o el error.
        sender_pn:
          description: JID PN resuelto del remitente (cuando esté disponible)
          oneOf:
            - type: string
            - type: 'null'
        sender_lid:
          description: LID original del remitente (cuando esté disponible)
          oneOf:
            - type: string
            - type: 'null'
        sender_image_preview_url:
          type: string
          format: uri
          description: >-
            URL temporal de vista previa del remitente, cuando se conoce. La
            hidratación de esta versión completa los mensajes recibidos en
            grupos; el campo puede omitirse. No provoca consulta de foto a
            WhatsApp en el listado.
  securitySchemes:
    token:
      name: token
      type: apiKey
      in: header

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.