openapi: 3.1.0
info:
  title: Zaptos - WhatsApp API
  version: 2.0.1
  x-logo:
    url: /zaptos-logo.png
  description: >
    API para gerenciamento de instâncias do WhatsApp e comunicações.


    ## ⚠️ Recomendação Importante: WhatsApp Business

    **É ALTAMENTE RECOMENDADO usar contas do WhatsApp Business** em vez do WhatsApp normal para integração, o WhatsApp
    normal pode apresentar inconsistências, desconexões, limitações e instabilidades durante o uso com a nossa API.


    ## Autenticação

    - Endpoints regulares requerem um header 'token' com o token da instância

    - Endpoints administrativos requerem um header 'admintoken'


    ## Estados da Instância

    As instâncias podem estar nos seguintes estados:

    - `disconnected`: Desconectado do WhatsApp

    - `connecting`: Em processo de conexão

    - `connected`: Conectado e autenticado com sucesso


    ## Limites de Uso

    - O servidor possui um limite máximo de instâncias conectadas

    - Quando o limite é atingido, novas tentativas receberão erro 429
servers:
  - url: https://api.zaptos.com.br
    description: Servidor da API zaptos
components:
  securitySchemes:
    token:
      name: token
      type: apiKey
      in: header
    admintoken:
      name: admintoken
      type: apiKey
      in: header
      description: Token de administrador para endpoints administrativos
  schemas:
    Instance:
      type: object
      description: Representa uma instância do WhatsApp
      properties:
        id:
          type: string
          format: uuid
          description: ID único gerado automaticamente
        token:
          type: string
          description: Token de autenticação da instância
        status:
          type: string
          description: Status atual da conexão
        paircode:
          type: string
          description: Código de pareamento
        qrcode:
          type: string
          description: QR Code em base64 para autenticação
        name:
          type: string
          description: Nome da instância
        profileName:
          type: string
          description: Nome do perfil WhatsApp
        profilePicUrl:
          type: string
          format: uri
          description: URL da foto do perfil
        isBusiness:
          type: boolean
          description: Indica se é uma conta business
        plataform:
          type: string
          description: Plataforma de origem (iOS/Android/Web)
        systemName:
          type: string
          description: Nome do sistema operacional
        owner:
          type: string
          description: Proprietário da instância
        current_presence:
          type: string
          description: Status atual de presença da instância (campo não persistido)
          enum:
            - available
            - unavailable
          example: available
        lastDisconnect:
          type: string
          format: date-time
          description: Data/hora da última desconexão
        lastDisconnectReason:
          type: string
          description: Motivo da última desconexão
        adminField01:
          type: string
          description: Campo administrativo 01
        adminField02:
          type: string
          description: Campo administrativo 02
        openai_apikey:
          type: string
          description: Chave da API OpenAI
        chatbot_enabled:
          type: boolean
          description: Habilitar chatbot automático
        chatbot_ignoreGroups:
          type: boolean
          description: Ignorar mensagens de grupos
        chatbot_stopConversation:
          type: string
          description: Palavra-chave para parar conversa
        chatbot_stopMinutes:
          type: integer
          description: Por quanto tempo ficará pausado o chatbot ao usar stop conversation
        chatbot_stopWhenYouSendMsg:
          type: integer
          description: Por quanto tempo ficará pausada a conversa quando você enviar mensagem manualmente
        fieldsMap:
          type: object
          description: Mapa de campos customizados da instância (quando presente)
          additionalProperties: true
        currentTime:
          type: string
          description: Horário atual retornado pelo backend
        created:
          type: string
          format: date-time
          description: Data de criação da instância
        updated:
          type: string
          format: date-time
          description: Data da última atualização
      example:
        id: i91011ijkl
        token: abc123xyz
        status: connected
        paircode: 1234-5678
        qrcode: data:image/png;base64,iVBORw0KGg...
        name: Instância Principal
        profileName: Loja ABC
        profilePicUrl: https://example.com/profile.jpg
        isBusiness: true
        plataform: Android
        systemName: zaptos
        owner: user@example.com
        lastDisconnect: '2025-01-24T14:00:00Z'
        lastDisconnectReason: Network error
        adminField01: custom_data
        openai_apikey: sk-...xyz
        chatbot_enabled: true
        chatbot_ignoreGroups: true
        chatbot_stopConversation: parar
        chatbot_stopMinutes: 60
        created: '2025-01-24T14:00:00Z'
        updated: '2025-01-24T14:30:00Z'
        currentPresence: available
    Webhook:
      type: object
      description: Configuração completa de webhook com filtros e opções avançadas
      properties:
        id:
          type: string
          format: uuid
          description: ID único gerado automaticamente
        enabled:
          type: boolean
          description: Webhook ativo/inativo
          default: false
        url:
          type: string
          format: uri
          description: URL de destino dos eventos
        events:
          type: array
          items:
            type: string
            enum:
              - connection
              - history
              - messages
              - messages_update
              - newsletter_messages
              - call
              - contacts
              - presence
              - groups
              - labels
              - chats
              - chat_labels
              - blocks
              - sender
          description: Tipos de eventos monitorados
        addUrlTypesMessages:
          type: boolean
          description: Incluir na URLs o tipo de mensagem
          default: false
        addUrlEvents:
          type: boolean
          description: Incluir na URL o nome do evento
          default: false
        excludeMessages:
          type: array
          items:
            type: string
            enum:
              - wasSentByApi
              - wasNotSentByApi
              - fromMeYes
              - fromMeNo
              - isGroupYes
              - isGroupNo
          description: Filtros para excluir tipos de mensagens
      required:
        - url
        - events
      example:
        id: wh_9a8b7c6d5e
        enabled: true
        url: https://webhook.cool/example
        events:
          - messages
          - newsletter_messages
          - connection
        addUrlTypesMessages: false
        addUrlEvents: false
        excludeMessages: []
    Chat:
      type: object
      description: Representa uma conversa/chamado no sistema
      properties:
        id:
          type: string
          description: ID único da conversa (r + 7 bytes aleatórios em hex)
        wa_fastid:
          type: string
          description: Identificador rápido do WhatsApp
        wa_chatid:
          type: string
          description: ID completo do chat no WhatsApp
        wa_chatlid:
          type: string
          description: LID do chat no WhatsApp (quando disponível)
        wa_archived:
          type: boolean
          description: Indica se o chat está arquivado
          default: false
        wa_contactName:
          type: string
          description: |
            Nome salvo nos contatos pelo dono da conta/instância.
            Só existe quando o número estiver salvo na agenda/contatos.
          default: ''
        wa_name:
          type: string
          description: |
            Nome definido pelo usuário no perfil do WhatsApp ("push name").
            Vem do perfil do contato e pode não estar disponível dependendo do contexto ou da origem dos dados.
          default: ''
        name:
          type: string
          description: >
            Nome resolvido pelo sistema como fallback.

            Normalmente consolida o melhor valor disponível entre dados internos, nome vindo do WhatsApp e nome salvo
            nos contatos.

            Por isso, costuma ter maior chance de vir preenchido.
          default: ''
        image:
          type: string
          description: URL da imagem do chat
          default: ''
        imagePreview:
          type: string
          description: URL da miniatura da imagem
          default: ''
        wa_ephemeralExpiration:
          type: integer
          format: int64
          description: Tempo de expiração de mensagens efêmeras
          default: 0
        wa_isBlocked:
          type: boolean
          description: Indica se o contato está bloqueado
          default: false
        wa_isGroup:
          type: boolean
          description: Indica se é um grupo
          default: false
        wa_isGroup_admin:
          type: boolean
          description: Indica se o usuário é admin do grupo
          default: false
        wa_isGroup_announce:
          type: boolean
          description: Indica se é um grupo somente anúncios
          default: false
        wa_isGroup_community:
          type: boolean
          description: Indica se é uma comunidade
          default: false
        wa_isGroup_member:
          type: boolean
          description: Indica se é membro do grupo
          default: false
        wa_isPinned:
          type: boolean
          description: Indica se o chat está fixado
          default: false
        wa_label:
          type: array
          description: Labels do chat
          items:
            type: string
        wa_notes:
          type: string
          description: Anotações internas do chat sincronizadas via app state
          default: ''
        wa_lastMessageTextVote:
          type: string
          description: Texto/voto da última mensagem
          default: ''
        wa_lastMessageType:
          type: string
          description: Tipo da última mensagem
          default: ''
        wa_lastMsgTimestamp:
          type: integer
          format: int64
          description: Timestamp da última mensagem
          default: 0
        wa_lastMessageSender:
          type: string
          description: Remetente da última mensagem
          default: ''
        wa_muteEndTime:
          type: integer
          format: int64
          description: Timestamp do fim do silenciamento
          default: 0
        owner:
          type: string
          description: Dono da instância
          default: ''
        wa_unreadCount:
          type: integer
          format: int64
          description: Contador de mensagens não lidas
          default: 0
        phone:
          type: string
          description: Número de telefone
          default: ''
        common_groups:
          type: string
          description: 'Grupos em comum separados por vírgula, formato: (nome_grupo)id_grupo'
          default: ''
          example: Grupo Família(120363123456789012@g.us),Trabalho(987654321098765432@g.us)
        lead_name:
          type: string
          description: Nome do lead
          default: ''
        lead_fullName:
          type: string
          description: Nome completo do lead
          default: ''
        lead_email:
          type: string
          description: Email do lead
          default: ''
        lead_personalid:
          type: string
          description: Documento de identificação
          default: ''
        lead_status:
          type: string
          description: Status do lead
          default: ''
        lead_tags:
          type: array
          description: Tags do lead
          items:
            type: string
        lead_notes:
          type: string
          description: Anotações sobre o lead
          default: ''
        lead_isTicketOpen:
          type: boolean
          description: Indica se tem ticket aberto
          default: false
        lead_assignedAttendant_id:
          type: string
          description: ID do atendente responsável
          default: ''
        lead_kanbanOrder:
          type: integer
          format: int64
          description: Ordem no kanban
          default: 0
        lead_field01:
          type: string
          default: ''
        lead_field02:
          type: string
          default: ''
        lead_field03:
          type: string
          default: ''
        lead_field04:
          type: string
          default: ''
        lead_field05:
          type: string
          default: ''
        lead_field06:
          type: string
          default: ''
        lead_field07:
          type: string
          default: ''
        lead_field08:
          type: string
          default: ''
        lead_field09:
          type: string
          default: ''
        lead_field10:
          type: string
          default: ''
        lead_field11:
          type: string
          default: ''
        lead_field12:
          type: string
          default: ''
        lead_field13:
          type: string
          default: ''
        lead_field14:
          type: string
          default: ''
        lead_field15:
          type: string
          default: ''
        lead_field16:
          type: string
          default: ''
        lead_field17:
          type: string
          default: ''
        lead_field18:
          type: string
          default: ''
        lead_field19:
          type: string
          default: ''
        lead_field20:
          type: string
          default: ''
        chatbot_agentResetMemoryAt:
          type: integer
          format: int64
          description: Timestamp do último reset de memória
          default: 0
        chatbot_lastTrigger_id:
          type: string
          description: ID do último gatilho executado
          default: ''
        chatbot_lastTriggerAt:
          type: integer
          format: int64
          description: Timestamp do último gatilho
          default: 0
        chatbot_disableUntil:
          type: integer
          format: int64
          description: Timestamp até quando chatbot está desativado
          default: 0
    Message:
      type: object
      description: Representa uma mensagem trocada no sistema
      properties:
        id:
          type: string
          format: uuid
          description: ID único interno da mensagem (formato r + 7 caracteres hex aleatórios)
        messageid:
          type: string
          description: ID original da mensagem no provedor
        chatid:
          type: string
          description: ID da conversa relacionada
        sender:
          type: string
          description: ID do remetente da mensagem
        senderName:
          type: string
          description: Nome exibido do remetente
        isGroup:
          type: boolean
          description: Indica se é uma mensagem de grupo
          default: false
        fromMe:
          type: boolean
          description: Indica se a mensagem foi enviada pelo usuário
          default: false
        messageType:
          type: string
          description: Tipo de conteúdo da mensagem
        source:
          type: string
          description: Plataforma de origem da mensagem
        messageTimestamp:
          type: integer
          description: Timestamp original da mensagem em milissegundos
          default: 0
        status:
          type: string
          description: |
            Status do ciclo de vida da mensagem.
            Exemplos comuns: `Queued`, `Canceled`, `Failed`, `Sent`, `Delivered`, `Read`.
        text:
          type: string
          description: Texto original da mensagem
          default: ''
        quoted:
          type: string
          description: ID da mensagem citada/respondida
          default: ''
        edited:
          type: string
          description: Histórico de edições da mensagem
          default: ''
        reaction:
          type: string
          description: ID da mensagem reagida
          default: ''
        vote:
          type: string
          description: Dados de votação de enquete e listas
          default: ''
        convertOptions:
          type: string
          description: Conversão de opções da mensagem, lista, enquete e botões
          default: ''
        buttonOrListid:
          type: string
          description: ID do botão ou item de lista selecionado
          default: ''
        owner:
          type: string
          description: Dono da mensagem
          default: ''
        error:
          type: string
          description: Mensagem de erro caso o envio tenha falhado
          default: ''
        content:
          description: Conteúdo bruto da mensagem (JSON serializado ou texto)
          oneOf:
            - type: object
              additionalProperties: true
            - type: string
              description: Texto bruto quando não for JSON
        wasSentByApi:
          type: boolean
          description: Indica se a mensagem foi enviada via API
        sendFunction:
          type: string
          description: Função usada para enviar a mensagem (quando enviada via API)
        sendPayload:
          description: Payload enviado (texto/JSON serializado)
          oneOf:
            - type: object
              additionalProperties: true
            - type: string
              description: Texto bruto quando não for JSON
        fileURL:
          type: string
          description: URL ou referência de arquivo da mensagem
        send_folder_id:
          type: string
          description: Pasta associada ao envio (quando aplicável)
        track_source:
          type: string
          description: Origem de rastreamento
        track_id:
          type: string
          description: ID de rastreamento (pode repetir)
        ai_metadata:
          type: object
          description: Metadados do processamento por IA
          properties:
            agent_id:
              type: string
              description: ID do agente de IA responsável
            request:
              type: object
              description: Dados da requisição à API de IA
              properties:
                messages:
                  type: array
                  description: Histórico de mensagens enviadas para a API
                tools:
                  type: array
                  description: Ferramentas disponíveis para o agente
                options:
                  type: object
                  description: Opções de configuração da API
                  properties:
                    model:
                      type: string
                    temperature:
                      type: number
                    maxTokens:
                      type: integer
                    topP:
                      type: number
                    frequencyPenalty:
                      type: number
                    presencePenalty:
                      type: number
            response:
              type: object
              description: Resposta da API de IA
              properties:
                choices:
                  type: array
                  description: Resultados retornados pela API
                toolResults:
                  type: array
                  description: Resultados da execução de ferramentas
                error:
                  type: string
                  description: Mensagem de erro, se houver
        sender_pn:
          type: string
          description: JID PN resolvido do remetente (quando disponível)
        sender_lid:
          type: string
          description: LID original do remetente (quando disponível)
    Label:
      type: object
      description: Representa uma etiqueta/categoria no sistema
      properties:
        id:
          type: string
          format: uuid
          description: ID único da etiqueta
        name:
          type: string
          description: Nome da etiqueta
        color:
          type: integer
          description: Índice numérico da cor (0-19)
          minimum: 0
          maximum: 19
          example: 2
        colorHex:
          type: string
          description: Cor hexadecimal correspondente ao índice
          enum:
            - '#ff9484'
            - '#64c4ff'
            - '#fed428'
            - '#dfaef0'
            - '#9ab6c1'
            - '#56ccb4'
            - '#fe9dfe'
            - '#d3a91f'
            - '#6f7bcf'
            - '#d8e651'
            - '#01d0e2'
            - '#ffc5c7'
            - '#92ceac'
            - '#f64847'
            - '#00a1f2'
            - '#83e421'
            - '#ffae04'
            - '#b4ebff'
            - '#9ba6ff'
            - '#9568cf'
          example: '#fed428'
        labelid:
          type: string
          description: ID da label no WhatsApp (quando sincronizada)
        owner:
          type: string
          description: Dono da etiqueta
        created:
          type: string
          format: date-time
          description: Data de criação
        updated:
          type: string
          format: date-time
          description: Data da última atualização
      example:
        id: l121314mnop
        name: Cliente VIP
        color: 2
        colorHex: '#fed428'
        created: '2025-01-24T14:35:00.000Z'
        updated: '2025-01-24T15:00:00.000Z'
    Attendant:
      type: object
      description: Modelo de atendente do sistema
      properties:
        id:
          type: string
          format: uuid
          description: ID único gerado automaticamente
        name:
          type: string
          description: Nome do atendente
          default: ''
        phone:
          type: string
          description: Número de telefone
          default: ''
        email:
          type: string
          format: email
          description: Endereço de e-mail
          default: ''
        department:
          type: string
          description: Departamento de atuação
          default: ''
        customField01:
          type: string
          description: Campo personalizável 01
          default: ''
        customField02:
          type: string
          description: Campo personalizável 02
          default: ''
        owner:
          type: string
          description: Responsável pelo cadastro
          default: ''
        created:
          type: string
          format: date-time
          description: Data de criação automática
        updated:
          type: string
          format: date-time
          description: Data de atualização automática
      example:
        id: r1234abcd
        name: João da Silva
        phone: '+5511999999999'
        email: joao@empresa.com
        department: Suporte Técnico
        customField01: 'Turno: Manhã'
        customField02: 'Nível: 2'
        owner: admin
        created: '2025-01-24T13:52:19.000Z'
        updated: '2025-01-24T13:52:19.000Z'
    MessageQueueFolder:
      type: object
      description: Pasta para organização de campanhas de mensagens em massa
      properties:
        id:
          type: string
          description: Identificador único
        info:
          type: string
          description: Informações adicionais sobre a pasta
        status:
          type: string
          description: Status atual da pasta
          example: ativo
        scheduled_for:
          type: integer
          format: int64
          description: Timestamp Unix para execução agendada
        delayMax:
          type: integer
          format: int64
          description: Atraso máximo entre mensagens em milissegundos
        delayMin:
          type: integer
          format: int64
          description: Atraso mínimo entre mensagens em milissegundos
        log_delivered:
          type: integer
          format: int64
          description: Contagem de mensagens entregues
        log_failed:
          type: integer
          format: int64
          description: Contagem de mensagens com falha
        log_played:
          type: integer
          format: int64
          description: Contagem de mensagens reproduzidas (para áudio/vídeo)
        log_read:
          type: integer
          format: int64
          description: Contagem de mensagens lidas
        log_sucess:
          type: integer
          format: int64
          description: Contagem de mensagens enviadas com sucesso
        log_total:
          type: integer
          format: int64
          description: Contagem total de mensagens
        owner:
          type: string
          description: Identificador do proprietário da instância
        created:
          type: string
          format: date-time
          description: Data e hora de criação
        updated:
          type: string
          format: date-time
          description: Data e hora da última atualização
    QuickReply:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: ID único da resposta rápida
        onWhatsApp:
          type: boolean
          description: Indica se a resposta veio do WhatsApp (não pode ser editada/excluída)
          default: false
        docName:
          type: string
          description: Nome de documento associado (quando aplicável)
          default: ''
        file:
          type: string
          description: Caminho ou conteúdo do arquivo associado
          default: ''
        shortCut:
          type: string
          description: Atalho para acionar a resposta
        text:
          type: string
          description: Conteúdo da mensagem pré-definida
        type:
          type: string
          description: Tipo da resposta rápida (texto/documento/outros)
        owner:
          type: string
          description: Dono da resposta rápida
        created:
          type: string
          format: date-time
          description: Data de criação
        updated:
          type: string
          format: date-time
          description: Data da última atualização
      required:
        - shortCut
        - text
    Group:
      type: object
      description: Representa um grupo/conversa coletiva
      properties:
        JID:
          type: string
          format: jid
          description: Identificador único do grupo
          example: jid8@g.us
        OwnerJID:
          type: string
          format: jid
          description: JID do proprietário do grupo
          example: 1232@s.whatsapp.net
        OwnerPN:
          type: string
          format: jid
          description: Número/LID do proprietário (quando disponível)
        Name:
          type: string
          description: Nome do grupo
          example: Grupo de Suporte
        NameSetAt:
          type: string
          format: date-time
          description: Data da última alteração do nome
        NameSetBy:
          type: string
          format: jid
          description: JID do usuário que definiu o nome
        NameSetByPN:
          type: string
          format: jid
          description: LID/PN de quem definiu o nome
        Topic:
          type: string
          description: Descrição do grupo
        TopicID:
          type: string
          description: ID interno da descrição
        TopicSetAt:
          type: string
          format: date-time
          description: Data da última alteração da descrição
        TopicSetBy:
          type: string
          format: jid
          description: JID de quem alterou a descrição
        TopicSetByPN:
          type: string
          format: jid
          description: LID/PN de quem alterou a descrição
        TopicDeleted:
          type: boolean
          description: Indica se a descrição foi apagada
        IsLocked:
          type: boolean
          description: |
            Indica se apenas administradores podem editar informações do grupo
            - true = apenas admins podem editar
            - false = todos podem editar
          example: true
        IsAnnounce:
          type: boolean
          description: Indica se apenas administradores podem enviar mensagens
        AnnounceVersionID:
          type: string
          description: Versão da configuração de anúncios
        IsEphemeral:
          type: boolean
          description: Indica se as mensagens são temporárias
        DisappearingTimer:
          type: integer
          description: Tempo em segundos para desaparecimento de mensagens
          minimum: 0
        IsIncognito:
          type: boolean
          description: Indica se o grupo é incognito
        IsParent:
          type: boolean
          description: Indica se é um grupo pai (comunidade)
        IsJoinApprovalRequired:
          type: boolean
          description: Indica se requer aprovação para novos membros
        LinkedParentJID:
          type: string
          format: jid
          description: JID da comunidade vinculada
        IsDefaultSubGroup:
          type: boolean
          description: Indica se é um subgrupo padrão da comunidade
        DefaultMembershipApprovalMode:
          type: string
          description: Modo padrão de aprovação de membros (quando comunidade)
        GroupCreated:
          type: string
          format: date-time
          description: Data de criação do grupo
        CreatorCountryCode:
          type: string
          description: Código do país do criador
        ParticipantVersionID:
          type: string
          description: Versão da lista de participantes
        Participants:
          type: array
          items:
            $ref: '#/GroupParticipant'
          description: Lista de participantes do grupo
        MemberAddMode:
          type: string
          enum:
            - admin_add
            - all_member_add
          description: Modo de adição de novos membros
        AddressingMode:
          type: string
          enum:
            - pn
            - lid
          description: Endereçamento preferido do grupo
        OwnerCanSendMessage:
          type: boolean
          description: Verifica se é possível você enviar mensagens
        OwnerIsAdmin:
          type: boolean
          description: Verifica se você adminstrador do grupo
        DefaultSubGroupId:
          type: string
          description: Se o grupo atual for uma comunidade, nesse campo mostrará o ID do subgrupo de avisos
        invite_link:
          type: string
          description: Link de convite para entrar no grupo
        request_participants:
          type: string
          description: Lista de solicitações de entrada, separados por vírgula
    GroupParticipant:
      type: object
      description: Participante de um grupo
      properties:
        JID:
          type: string
          format: jid
          description: Identificador do participante
        LID:
          type: string
          format: jid
          description: Identificador local do participante
        PhoneNumber:
          type: string
          format: jid
          description: Número do participante (quando disponível)
        IsAdmin:
          type: boolean
          description: Indica se é administrador
        IsSuperAdmin:
          type: boolean
          description: Indica se é super administrador
        DisplayName:
          type: string
          description: Nome exibido no grupo (para usuários anônimos)
        Error:
          type: integer
          description: Código de erro ao adicionar participante
          minimum: 0
        AddRequest:
          type: object
          description: Informações da solicitação de entrada
          properties:
            Code:
              type: string
              description: Código da solicitação
            Expiration:
              type: string
              format: date-time
              description: Data de expiração da solicitação
    WebhookEvent:
      type: object
      required:
        - event
        - instance
        - data
      properties:
        event:
          type: string
          enum:
            - message
            - status
            - presence
            - group
            - connection
          description: Tipo do evento recebido
        instance:
          type: string
          description: ID da instância que gerou o evento
        data:
          type: object
          description: |
            Payload do evento enviado pelo webhook. O formato varia conforme o tipo do evento
            (messages, messages_update, connection, presence, etc) e segue o que o backend envia
            em `callHook` (map[string]interface{}). Consulte os exemplos de cada evento específico.
          additionalProperties: true
security:
  - token: []
tags:
  - name: Admininstração
    description: |
      Endpoints para **administração geral** do sistema.
      Requerem um `admintoken` para autenticação.
  - name: Instancia
    description: |
      Operações relacionadas ao ciclo de vida de uma instância, como conectar,
      desconectar e verificar o status.
  - name: Proxy
    description: >
      A zaptos opera com um proxy interno como padrão.

      Você pode manter esse padrão, configurar um proxy próprio via `proxy_url` ou usar seu celular android como proxy
      instalando o app em https://github.com/zaptos/silver_proxy_apk (APK direto:
      https://github.com/zaptos/silver_proxy_apk/raw/refs/heads/main/silver_proxy.apk).

      Se nada for enviado, seguimos no proxy interno. IPs são brasileiros; para clientes internacionais, considere um
      proxy da região do cliente.
  - name: Perfil
    description: |
      Operações relacionadas ao perfil da conta do WhatsApp atualmente conectada, como alterar
      nome e imagem de perfil.
  - name: Business
    description: |
      ⚠️ **EXPERIMENTAL** - Endpoints ainda não testados completamente.

      Operações relacionadas ao perfil comercial do WhatsApp Business.
      Permite consultar e atualizar dados do perfil comercial como descrição,
      endereço, email, categorias e gerenciar o catálogo de produtos.

      **Requisitos:**
      - A conta atualmente conectada deve ser uma conta **WhatsApp Business**
      - Contas pessoais do WhatsApp não possuem perfil comercial

      **Nota:** Estes endpoints podem não funcionar como esperado.
      Reporte problemas encontrados.
  - name: Chamadas
    description: |
      Operações relacionadas a chamadas peloWhatsApp.
      Permite realizar e rejeitar chamadas programaticamente.
  - name: Webhooks e SSE
  - name: Enviar Mensagem
    description: >
      Endpoints para envio de mensagens do WhatsApp com diferentes tipos de conteúdo.


      ## Campos Opcionais Comuns


      Todos os endpoints de envio de mensagem suportam os seguintes campos opcionais:


      - **`delay`** *(integer)*: Atraso em milissegundos antes do envio
        - Durante o atraso aparecerá "Digitando..." ou "Gravando áudio..." dependendo do tipo
        - Exemplo: `5000` (5 segundos)

      - **`readchat`** *(boolean)*: Marcar chat como lido após envio
        - Remove o contador de mensagens não lidas do chat
        - Exemplo: `true`

      - **`readmessages`** *(boolean)*: Marcar últimas mensagens recebidas como lidas
        - Marca as últimas 10 mensagens **recebidas** (não enviadas por você) como lidas
        - Útil para confirmar leitura de mensagens pendentes antes de responder
        - Diferente do `readchat` que apenas remove contador de não lidas
        - Exemplo: `true`

      - **`replyid`** *(string)*: ID da mensagem para responder
        - Cria uma resposta vinculada à mensagem original
        - Suporte varia por tipo de mensagem

      - **`viewOnce`** *(boolean)*: Recomendado quando quiser mídia de visualização única
        - Use em `/send/media` com `type` compatível (`image`, `video`, `videoplay`, `ptv`, `audio`, `myaudio`, `ptt`)
        - Nos demais endpoints de envio, o campo é aceito, mas é ignorado silenciosamente
        - Exemplo: `"3A12345678901234567890123456789012"`

      - **`mentions`** *(string)*: Números para mencionar (apenas para envio em grupos)
        - Números específicos: `"5511999999999,5511888888888"`
        - Mencionar todos: `"all"`

      - **`forward`** *(boolean)*: Marca a mensagem como encaminhada no WhatsApp
        - Adiciona o indicador "Encaminhada" na mensagem
        - Exemplo: `true`

      - **`track_source`** *(string)*: Origem do rastreamento da mensagem
        - Identifica o sistema ou fonte que está enviando a mensagem
        - Útil para integrações (ex: "chatwoot", "crm", "chatbot")
        - Exemplo: `"chatwoot"`

      - **`track_id`** *(string)*: ID para rastreamento da mensagem
        - Identificador livre para acompanhar a mensagem em sistemas externos
        - Permite correlacionar mensagens entre diferentes plataformas
        - **Nota**: O sistema aceita valores duplicados - não há validação de unicidade
        - Use o mesmo ID em várias mensagens se fizer sentido para sua integração
        - Exemplo: `"msg_123456789"`

      - **`async`** *(boolean)*: Envia pela fila interna sem bloquear a requisição
        - Resposta 200 indica que a mensagem entrou na fila; o envio real pode falhar depois
        - Em caso de falha, pesquise em `/message/find` com `status=failed`

      ## Diagnóstico de limites do WhatsApp


      Em alguns casos, o WhatsApp pode recusar novas conversas por regras próprias de volume, qualidade ou limitação
      temporária.


      Quando isso acontecer, a resposta de erro pode incluir:

      - `error_source: "whatsapp_server"`

      - `provider: "whatsapp"`

      - `provider_code: 463`

      - `error_key`

      - `message`

      - `message_ptbr`

      - `provider_message`

      - `provider_message_ptbr`

      - `diagnostics_endpoint`

      - `details.new_chat_message_capping`

      - `details.reachout_timelock`


      Para consultar o estado atual desses limites para a conta atualmente conectada, use:

      - `GET /instance/wa_messages_limits`


      ### Envio para Grupos

      - **`number`** *(string)*: Para enviar mensagem para grupo, use o ID do grupo que termina com `@g.us`
        - Exemplo: `"120363012345678901@g.us"`
        - **Como obter o ID do grupo:**
          - Use o `chatid` do webhook recebido quando alguém envia mensagem no grupo
          - Use o endpoint `GET /group/list` para listar todos os grupos e seus IDs

      ## Placeholders Disponíveis


      Todos os endpoints de envio de mensagem suportam placeholders dinâmicos para personalização automática:


      ### Campos de Nome

      - **`{{name}}`**: Nome consolidado do chat, usando a primeira opção disponível:
        1. Nome do lead (`lead_name`)
        2. Nome completo do lead (`lead_fullName`)
        3. Nome do contato no WhatsApp (`wa_contactName`)
        4. Nome do perfil do WhatsApp (`wa_name`)

      - **`{{first_name}}`**: Primeira palavra válida do nome consolidado (mínimo 2 caracteres)


      ### Campos do WhatsApp

      - **`{{wa_name}}`**: Nome do perfil do WhatsApp

      - **`{{wa_contactName}}`**: Nome do contato como salvo no WhatsApp


      ### Campos do Lead

      - **`{{lead_name}}`**: Nome do lead

      - **`{{lead_fullName}}`**: Nome completo do lead

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

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

      - **`{{lead_status}}`**: Status atual do lead

      - **`{{lead_notes}}`**: Anotações do lead

      - **`{{lead_assignedAttendant_id}}`**: ID do atendente designado


      ### Campos Personalizados

      Campos adicionados via custom fields são acessíveis usando `{{lead_field01}}` à `{{lead_field20}}` ou usar
      `{{nomedocampo}}` definido em `/instance/updateFieldsMap`.


      ### Exemplo de Uso

      ```

      Olá {{name}}! Vi que você trabalha na {{company}}.

      Seu email {{lead_email}} está correto?

      ```


      **💡 Dica**: Use `/chat/find` para buscar dados do chat e ver os campos disponíveis antes de enviar mensagens com
      placeholders.
  - name: Mensagem Async
    description: |
      Controles operacionais da fila interna de envio assíncrono usada quando um endpoint de envio recebe `async=true`.

      Esta seção serve para:
      - consultar o estado atual da fila async
      - limpar backlog pendente e cancelar mensagens ainda não concluídas

      Escopo:
      - cobre apenas a fila interna de mensagens diretas async
      - não cobre campanhas do sender (`/sender/*`)
      - não altera mensagens já enviadas com sucesso
  - name: Ações na mensagem e Buscar
  - name: Chats
  - name: Contatos
  - name: Bloqueios
  - name: Etiquetas
  - name: Grupos e Comunidades
  - name: Newsletters e Canais
    description: |
      Operações para leitura e acompanhamento de canais do WhatsApp (newsletters).

      Casos de uso principais:
      - listar posts já publicados em um canal
      - editar posts recentes de um canal
      - deletar posts recentes de um canal
      - consultar updates de engajamento dos posts
      - integrar canais sem necessidade de persistir as mensagens localmente

      Observações:
      - `/newsletter/messages` retorna o conteúdo dos posts
      - `/newsletter/messages/edit` edita o conteúdo de posts recentes
      - `/newsletter/messages/delete` apaga posts recentes
      - `/newsletter/updates` retorna updates dos posts, como views e reactions
      - views e reactions de canal devem ser consultados por `/newsletter/updates`, não por evento de webhook
      - newsletters usam rotas próprias e não devem usar `/message/edit` ou `/message/delete`
  - name: Respostas Rápidas
    description: |
      Gerenciamento de respostas rápidas para agilizar o atendimento.

      **⚠️ Importante**: Este recurso tem serventia apenas se você utilizar um sistema frontend/interface
      personalizada para registrar e utilizar as respostas. A API apenas armazena as respostas, 
      mas não as aplica automaticamente.

      ### Como funciona:
      - **Criar**: Cadastre respostas pré-definidas com títulos e conteúdo
      - **Listar**: Recupere todas as respostas cadastradas para exibir na sua interface
      - **Usar**: Seu sistema frontend pode usar essas respostas para agilizar digitação

      ### Casos de uso:
      - Interfaces web personalizadas de atendimento
      - Apps mobile com sugestões de resposta
      - Sistemas CRM com templates de mensagem
      - Ferramentas de produtividade para atendentes

      **Não é um chatbot**: Para respostas automáticas, use os recursos de Chatbot.
  - name: CRM
    description: |
      Sistema completo de gestão de relacionamento com clientes integrado à API.

      **💾 Armazenamento interno**: Todos os dados dos leads ficam salvos diretamente na API,
      eliminando a necessidade de bancos de dados externos. Sua aplicação pode focar apenas
      na interface e lógica de negócio.

      ### Recursos disponíveis:
      - **📋 20+ campos personalizáveis**: Nome, telefone, email, empresa, observações, etc.
      - **🏷️ Sistema de etiquetas**: Organize e categorize seus contatos
      - **🔍 Busca avançada**: Filtre por qualquer campo ou etiqueta
      - **📊 Histórico completo**: Todas as interações ficam registradas automaticamente

      ### 🎯 Placeholders em mensagens:
      Use variáveis dinâmicas nas mensagens para personalização automática:

      ```
      Olá {{nome}}! Vi que você trabalha na {{empresa}}.
      Seu email {{email}} está correto?
      Observações: {{observacoes}}
      ```

      ### Fluxo típico:
      1. **Captura**: Leads chegam via WhatsApp ou formulários
      2. **Enriquecimento**: Adicione dados usando `/chat/editLead`
      3. **Segmentação**: Organize com etiquetas
      4. **Comunicação**: Envie mensagens personalizadas com placeholders
      5. **Acompanhamento**: Histórico fica salvo automaticamente

      **Ideal para**: Vendas, marketing, atendimento, qualificação de leads
  - name: Mensagem em massa
  - name: Integração Chatwoot
    description: >
      **🚧 INTEGRAÇÃO BETA - Sistema de integração com Chatwoot para atendimento unificado**


      **⚠️ AVISO**: Esta integração está em fase BETA. Use por sua conta e risco. Recomendamos testes em ambiente
      não-produtivo antes do uso em produção.


      Esta categoria contém recursos para configurar e gerenciar a integração com o Chatwoot, uma plataforma de
      atendimento ao cliente open-source. A integração permite centralizar conversas do WhatsApp no Chatwoot.


      ### Recursos disponíveis:

      - 🔧 **Configuração Completa**: Configure URL, tokens e credenciais do Chatwoot

      - 📬 **Sincronização Bidirecional**: Mensagens novas entre WhatsApp e Chatwoot são sincronizadas automaticamente

      - 📱 **Gerenciamento de Contatos**: Sincronização automática de nomes e telefones

      - 🔄 **Atualização LID→PN**: Migração automática de Local ID para Phone Number

      - 🏷️ **Nomes Inteligentes**: Sistema de nomes com til (~) para atualização automática

      - 🚫 **Separação de Grupos**: Opção para ignorar grupos na sincronização

      - 👤 **Assinatura de Mensagens**: Identificação do agente nas mensagens enviadas

      - 🔗 **Webhook Automático**: URL gerada automaticamente para configurar no Chatwoot


      ### 🏷️ Sistema de Nomes Inteligentes:

      - **Nomes com til (~)**: Atualizados automaticamente quando contato modifica nome no WhatsApp

      - **Nomes específicos**: Para nome fixo, remover til (~) do nome no Chatwoot

      - **Exemplo**: "~João Silva" = automático, "João Silva" = fixo

      - **Migração LID→PN**: Sem duplicação de conversas durante a transição

      - **Respostas nativas**: Aparecem diretamente no Chatwoot sem marcações externas


      ### ⚠️ Limitações conhecidas:

      - **Sincronização de histórico**: Não implementada - apenas mensagens novas são sincronizadas


      ### Casos de uso:

      - Atendimento centralizado no Chatwoot

      - Equipes de suporte com múltiplos agentes

      - Integração com CRM via Chatwoot

      - Centralização de canais de comunicação

      - Gestão automática de contatos e nomes


      **Ideal para**: Empresas com equipes de atendimento, call centers, suporte técnico (em ambiente de testes)


      **Requer**: Instância do Chatwoot configurada, tokens de API e ambiente de testes


      **🚧 Lembre-se**: Integração em BETA - funcionalidades podem mudar sem aviso prévio
paths:
  /instance/create:
    post:
      operationId: createInstance
      tags:
        - Admininstração
      summary: Criar Instancia
      security:
        - admintoken: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Nome da instância
                  example: minha-instancia
                systemName:
                  type: string
                  description: Nome do sistema (opcional, padrão 'zaptos' se não informado)
                  example: apilocal
                adminField01:
                  type: string
                  description: Campo administrativo 1 para metadados personalizados (opcional)
                  example: custom-metadata-1
                adminField02:
                  type: string
                  description: Campo administrativo 2 para metadados personalizados (opcional)
                  example: custom-metadata-2
              required:
                - name
      description: >
        Cria uma nova instância do WhatsApp. Para criar uma instância você precisa:


        1. Ter um admintoken válido

        2. Enviar pelo menos o nome da instância

        3. A instância será criada desconectada

        4. Será gerado um token único para autenticação


        Após criar a instância, guarde o token retornado pois ele será necessário

        para todas as outras operações.


        Estados possíveis da instância:


        - `disconnected`: Desconectado do WhatsApp

        - `connecting`: Em processo de conexão

        - `connected`: Conectado e autenticado


        Campos administrativos (adminField01/adminField02) são opcionais e podem ser usados para armazenar metadados
        personalizados. 

        OS valores desses campos são vísiveis para o dono da instancia via token, porém apenas o administrador da api
        (via admin token) pode editá-los.
      responses:
        '200':
          description: Sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Instance created successfully
                  instance:
                    $ref: ../schemas/instance.yaml#/Instance
                  connected:
                    type: boolean
                    example: false
                  loggedIn:
                    type: boolean
                    example: false
                  name:
                    type: string
                    example: minha-instancia
                  token:
                    type: string
                    example: 123e4567-e89b-12d3-a456-426614174000
                  info:
                    type: string
                    example: This instance will be automatically disconnected and deleted after 1 hour.
        '401':
          description: Token inválido/expirado
        '404':
          description: Instância não encontrada
        '500':
          description: Erro interno
  /instance/all:
    get:
      operationId: listAllInstances
      tags:
        - Admininstração
      summary: Listar todas as instâncias
      security:
        - admintoken: []
      description: |
        Retorna uma lista completa de todas as instâncias do sistema, incluindo:
        - ID e nome de cada instância
        - Status atual (disconnected, connecting, connected)
        - Data de criação
        - Última desconexão e motivo
        - Informações de perfil (se conectado)

        Requer permissões de administrador.
      responses:
        '200':
          description: Lista de instâncias retornada com sucesso
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: ../schemas/instance.yaml#/Instance
              example:
                - id: r183e2ef9597845
                  name: instancia-1
                  token: abc123xyz
                  status: connected
                  profileName: Meu WhatsApp
                  profilePicUrl: https://example.com/profile.jpg
                  isBusiness: true
                  plataform: Android
                  systemName: zaptos
                  owner: user@example.com
                  created: '2024-01-01T12:00:00.000Z'
                  updated: '2024-01-01T12:30:00.000Z'
                - id: r283e2ef9597846
                  name: instancia-2
                  token: def456xyz
                  status: disconnected
                  lastDisconnect: '2024-01-02T12:00:00.000Z'
                  lastDisconnectReason: manual disconnect
                  created: '2024-01-02T12:00:00.000Z'
                  updated: '2024-01-02T12:30:00.000Z'
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unauthorized
        '403':
          description: Token de administrador inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid AdminToken Header
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Internal server error
  /instance/connect:
    post:
      operationId: connectInstance
      tags:
        - Instancia
      summary: Conectar instância ao WhatsApp
      description: >
        Inicia o processo de conexão de uma instância ao WhatsApp. Este endpoint:

        1. Requer o token de autenticação da instância

        2. Recebe o número de telefone associado à conta WhatsApp

        3. Gera um QR code caso não passe o campo `phone`

        4. Ou Gera código de pareamento se passar o o campo `phone`

        5. Atualiza o status da instância para "connecting"


        O processo de conexão permanece pendente até que:

        - O QR code seja escaneado no WhatsApp do celular, ou

        - O código de pareamento seja usado no WhatsApp

        - Timeout de 2 minutos para QRCode seja atingido ou 5 minutos para o código de pareamento


        Use o endpoint /instance/status para monitorar o progresso da conexão.


        Estados possíveis da instância:

        - `disconnected`: Desconectado do WhatsApp

        - `connecting`: Em processo de conexão

        - `connected`: Conectado e autenticado


        Sincronização e armazenamento de mensagens:

        - Todas as mensagens recebidas da Meta durante a sincronização da conexão (leitura do QR code) são enviadas no
        evento `history` do webhook.

        - As mensagens dos últimos 7 dias são armazenadas no banco de dados e ficam acessíveis pelos endpoints: `POST
        /message/find` e `POST /chat/find`.

        - Depois que a instância conecta, todas as mensagens enviadas ou recebidas são armazenadas no banco de dados.

        - Mensagens mais antigas do que 7 dias são excluídas durante a madrugada.


        Exemplo de requisição:

        ```json

        {
          "phone": "5511999999999"
        }

        ```
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                phone:
                  type: string
                  description: >-
                    Número de telefone no formato internacional (ex: 5511999999999). Se informado, gera código de
                    pareamento. Se omitido, gera QR code.
                  example: '5511999999999'
                  pattern: ^\d{10,15}$
      responses:
        '200':
          description: Sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  connected:
                    type: boolean
                    description: Estado atual da conexão
                    example: false
                  loggedIn:
                    type: boolean
                    description: Estado do login
                    example: false
                  jid:
                    type:
                      - object
                      - 'null'
                    description: ID do WhatsApp (quando logado)
                    example: null
                  instance:
                    $ref: ../schemas/instance.yaml#/Instance
                    description: Detalhes completos da instância
        '401':
          description: Token inválido/expirado
        '404':
          description: Instância não encontrada
        '429':
          description: Limite de conexões simultâneas atingido
        '500':
          description: Erro interno
  /instance/disconnect:
    post:
      operationId: disconnectInstance
      tags:
        - Instancia
      summary: Desconectar instância
      description: |
        Desconecta a conta do WhatsApp atualmente conectada, encerrando a sessão atual.
        Esta operação:

        - Encerra a conexão ativa

        - Requer novo QR code para reconectar


        Diferenças entre desconectar e hibernar:

        - Desconectar: Encerra completamente a sessão, exigindo novo login

        - Hibernar: Mantém a sessão ativa, apenas pausa a conexão


        Use este endpoint para:

        1. Encerrar completamente uma sessão

        2. Forçar uma nova autenticação

        3. Limpar credenciais da sessão atual

        4. Reiniciar o processo de conexão


        Estados possíveis após desconectar:

        - `disconnected`: Desconectado do WhatsApp

        - `connecting`: Em processo de reconexão (após usar /instance/connect)
      responses:
        '200':
          description: Sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  instance:
                    $ref: ../schemas/instance.yaml#/Instance
                  response:
                    type: string
                    example: Disconnected
                  info:
                    type: string
                    example: >-
                      The device has been successfully disconnected from WhatsApp. A new QR code will be required for
                      the next connection.
        '401':
          description: Token inválido/expirado
        '404':
          description: Instância não encontrada
        '500':
          description: Erro interno
  /instance/reset:
    post:
      operationId: resetInstance
      tags:
        - Instancia
      summary: Reiniciar runtime da instância
      description: |
        Solicita um reset controlado do runtime da instância atual.

        Este endpoint é útil quando a sessão ficou presa, o envio não está progredindo
        ou a instância precisa forçar uma tentativa de recuperação sem apagar o registro
        da instância.

        Comportamentos possíveis:
        - inicia um novo reset quando a instância está apta
        - informa que um reset já está em andamento
        - informa que existe cooldown ativo entre resets
        - retorna erro quando a sessão não pode ser recuperada ou quando a política de
          reconexão bloqueia a operação

        A resposta sempre informa:
        - `instanceId`: ID da instância autenticada
        - `resetting`: se há reset em andamento no momento
        - `queuedRecoveryAttempted`: se houve tentativa de recuperação da fila interna
      security:
        - token: []
      responses:
        '200':
          description: Reset aceito, já em andamento ou em cooldown
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Instance reset started
                  resetting:
                    type: boolean
                    example: true
                  instanceId:
                    type: string
                    example: r183e2ef9597845
                  queuedRecoveryAttempted:
                    type: boolean
                    example: true
              examples:
                started:
                  summary: Reset iniciado
                  value:
                    response: Instance reset started
                    resetting: true
                    instanceId: r183e2ef9597845
                    queuedRecoveryAttempted: true
                inProgress:
                  summary: Reset já em andamento
                  value:
                    response: Instance reset already in progress
                    resetting: true
                    instanceId: r183e2ef9597845
                    queuedRecoveryAttempted: false
                cooldown:
                  summary: Cooldown ativo
                  value:
                    response: Instance reset cooldown active (8s remaining)
                    resetting: false
                    instanceId: r183e2ef9597845
                    queuedRecoveryAttempted: false
        '400':
          description: Payload JSON inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid payload
        '401':
          description: Token inválido, ausente ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '403':
          description: Reset bloqueado pela política de reconexão
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  resetting:
                    type: boolean
                    example: false
                  instanceId:
                    type: string
                  queuedRecoveryAttempted:
                    type: boolean
        '409':
          description: Sessão atual não é reconectável por reset
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  resetting:
                    type: boolean
                    example: false
                  instanceId:
                    type: string
                  queuedRecoveryAttempted:
                    type: boolean
        '500':
          description: Erro interno ao solicitar o reset
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: server not available
                  resetting:
                    type: boolean
                    example: false
                  instanceId:
                    type: string
                  queuedRecoveryAttempted:
                    type: boolean
  /instance/status:
    get:
      operationId: getInstanceStatus
      tags:
        - Instancia
      summary: Verificar status da instância
      description: |
        Retorna o status atual de uma instância, incluindo:
        - Estado da conexão (disconnected, connecting, connected)
        - QR code atualizado (se em processo de conexão)
        - Código de pareamento (se disponível)
        - Informações da última desconexão
        - Detalhes completos da instância

        Este endpoint é particularmente útil para:
        1. Monitorar o progresso da conexão
        2. Obter QR codes atualizados durante o processo de conexão
        3. Verificar o estado atual da instância
        4. Identificar problemas de conexão

        Estados possíveis:
        - `disconnected`: Desconectado do WhatsApp
        - `connecting`: Em processo de conexão (aguardando QR code ou código de pareamento)
        - `connected`: Conectado e autenticado com sucesso
      responses:
        '200':
          description: Sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  instance:
                    $ref: ../schemas/instance.yaml#/Instance
                  status:
                    type: object
                    properties:
                      connected:
                        type: boolean
                        description: Indica se está conectado ao WhatsApp
                      loggedIn:
                        type: boolean
                        description: Indica se está autenticado no WhatsApp
                      jid:
                        type:
                          - object
                          - 'null'
                        description: ID do WhatsApp quando conectado
              example:
                instance:
                  id: r183e2ef9597845
                  name: minha-instancia
                  status: connected
                  profileName: Meu WhatsApp
                  currentTime: '2024-01-25T12:00:00.000Z'
                status:
                  connected: true
                  loggedIn: true
                  jid:
                    user: '5511999999999'
                    agent: 0
                    device: 0
                    server: s.whatsapp.net
        '401':
          description: Token inválido/expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: instance info not found
        '404':
          description: Instância não encontrada
        '500':
          description: Erro interno
  /instance/wa_messages_limits:
    get:
      operationId: getWAMessageLimits
      tags:
        - Instancia
      summary: Consultar limites atuais de novas conversas no WhatsApp
      description: >
        Consulta o estado atual de limitação do WhatsApp para a conta atualmente conectada.


        Este endpoint é útil para:

        - diagnosticar erros de envio com `provider_code: 463`

        - verificar se o WhatsApp indica que a conta atualmente conectada pode iniciar novas conversas

        - exibir informações de suporte antes de campanhas ou envios de alto volume


        A resposta consolida duas fontes internas do WhatsApp:

        - `new_chat_message_capping`: limite de mensagens para iniciar novas conversas

        - `reachout_timelock`: restrição temporária para iniciar novas conversas


        Observações:

        - este endpoint depende de sessão ativa e conectada

        - se o WhatsApp não retornar os dados esperados, a resposta pode marcar os blocos como indisponíveis via
        `available: false` e `lookup_error`

        - `message` descreve o estado atual da conta atualmente conectada

        - `provider_message` detalha o motivo reportado pelo WhatsApp quando houver restrição ativa
      responses:
        '200':
          description: Diagnóstico atual dos limites de novas conversas da conta atualmente conectada
          content:
            application/json:
              schema:
                type: object
                properties:
                  provider:
                    type: string
                    example: whatsapp
                  reachable:
                    type: boolean
                    description: Indica se ao menos uma das consultas ao WhatsApp retornou dados úteis
                    example: true
                  can_send_new_messages:
                    type:
                      - boolean
                      - 'null'
                    description: |
                      Indica se o WhatsApp sinaliza que a conta atualmente conectada pode iniciar novas conversas.
                      Pode ser `null` quando não foi possível concluir o diagnóstico.
                    example: false
                  error_key:
                    type: string
                    description: Chave de erro derivada do diagnóstico atual
                    example: WHATSAPP_REACHOUT_TIMELOCK
                  message:
                    type: string
                    description: Mensagem técnica principal em inglês
                    example: >-
                      WhatsApp indicates that the currently connected account is under a temporary restriction for
                      starting new conversations. This is not an internal API error.
                  message_ptbr:
                    type: string
                    description: Mensagem principal traduzida para pt-BR
                    example: >-
                      O WhatsApp indica que a conta atualmente conectada está sob uma restrição temporária para iniciar
                      novas conversas. Isso não é um erro interno da API.
                  provider_message:
                    type: string
                    description: Motivo detalhado reportado pelo WhatsApp em inglês
                    example: >-
                      WhatsApp reported that the currently connected account is under a temporary restriction for
                      starting new conversations, usually related to sending volume or quality.
                  provider_message_ptbr:
                    type: string
                    description: Motivo detalhado reportado pelo WhatsApp em pt-BR
                    example: >-
                      O WhatsApp informou que a conta atualmente conectada está sob uma restrição temporária para
                      iniciar novas conversas, normalmente relacionada a volume ou qualidade de envios.
                  diagnostics_endpoint:
                    type: string
                    example: /instance/wa_messages_limits
                  new_chat_message_capping:
                    type: object
                    properties:
                      available:
                        type: boolean
                        example: true
                      status:
                        type: string
                        example: CAPPED
                      used_quota:
                        type: integer
                        example: 10
                      total_quota:
                        type: integer
                        example: 10
                      cycle_start:
                        type: string
                        format: date-time
                      cycle_end:
                        type: string
                        format: date-time
                      server_sent_at:
                        type: string
                        format: date-time
                      ote_status:
                        type: string
                        example: EXHAUSTED
                      mv_status:
                        type: string
                        example: ACTIVE
                      lookup_error:
                        type: string
                  reachout_timelock:
                    type: object
                    properties:
                      available:
                        type: boolean
                        example: true
                      active:
                        type: boolean
                        example: true
                      until:
                        type: string
                        format: date-time
                      enforcement_type:
                        type: string
                        example: BIZ_QUALITY
                      lookup_error:
                        type: string
              examples:
                restricted:
                  summary: Conta conectada com restrição ativa
                  value:
                    provider: whatsapp
                    reachable: true
                    can_send_new_messages: false
                    error_key: WHATSAPP_REACHOUT_TIMELOCK
                    message: >-
                      WhatsApp indicates that the currently connected account is under a temporary restriction for
                      starting new conversations. This is not an internal API error.
                    message_ptbr: >-
                      O WhatsApp indica que a conta atualmente conectada está sob uma restrição temporária para iniciar
                      novas conversas. Isso não é um erro interno da API.
                    provider_message: >-
                      WhatsApp reported that the currently connected account is under a temporary restriction for
                      starting new conversations, usually related to sending volume or quality.
                    provider_message_ptbr: >-
                      O WhatsApp informou que a conta atualmente conectada está sob uma restrição temporária para
                      iniciar novas conversas, normalmente relacionada a volume ou qualidade de envios.
                    diagnostics_endpoint: /instance/wa_messages_limits
                    new_chat_message_capping:
                      available: true
                      status: CAPPED
                      used_quota: 10
                      total_quota: 10
                      cycle_end: '2026-04-30T23:59:59Z'
                      ote_status: EXHAUSTED
                      mv_status: ACTIVE
                    reachout_timelock:
                      available: true
                      active: true
                      until: '2026-04-07T12:00:00Z'
                      enforcement_type: BIZ_QUALITY
                unrestricted:
                  summary: Conta conectada sem restrições
                  value:
                    provider: whatsapp
                    reachable: true
                    can_send_new_messages: true
                    message: >-
                      No WhatsApp restriction for starting new conversations was detected for the currently connected
                      account.
                    message_ptbr: >-
                      Nenhuma restrição de envio de novas conversas foi identificada no WhatsApp para a conta atualmente
                      conectada.
                    diagnostics_endpoint: /instance/wa_messages_limits
                    new_chat_message_capping:
                      available: true
                      status: NONE
                      used_quota: 2
                      total_quota: 10
                    reachout_timelock:
                      available: true
                      active: false
        '401':
          description: Token inválido ou ausente
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid token
        '500':
          description: Erro interno ao consultar os limites
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
  /instance/updateFieldsMap:
    post:
      operationId: updateFieldsMap
      tags:
        - CRM
      summary: Atualizar campos personalizados de leads
      description: |
        Atualiza os campos personalizados (custom fields) de uma instância. 
        Permite configurar até 20 campos personalizados para armazenamento de 
        informações adicionais sobre leads.

        Cada campo pode armazenar até 255 caracteres e aceita qualquer tipo de dado.

        Campos disponíveis:
        - lead_field01 a lead_field20

        Exemplo de uso:
        1. Armazenar informações adicionais sobre leads
        2. Criar campos personalizados para integração com outros sistemas
        3. Armazenar tags ou categorias personalizadas
        4. Manter histórico de interações com o lead

        Exemplo de requisição:
        ```json
        {
          "lead_field01": "nome",
          "lead_field02": "email",
          "lead_field03": "telefone",
          "lead_field04": "cidade",
          "lead_field05": "estado",
          "lead_field06": "idade",
          "lead_field07": "interesses",
          "lead_field08": "origem",
          "lead_field09": "status",
          "lead_field10": "valor",
          "lead_field11": "observacoes",
          "lead_field12": "ultima_interacao",
          "lead_field13": "proximo_contato",
          "lead_field14": "vendedor",
          "lead_field15": "produto_interesse",
          "lead_field16": "fonte_captacao",
          "lead_field17": "score",
          "lead_field18": "tags",
          "lead_field19": "historico",
          "lead_field20": "custom"
        }
        ```

        Exemplo de resposta:
        ```json
        {
          "success": true,
          "message": "Custom fields updated successfully",
          "instance": {
            "id": "r183e2ef9597845",
            "name": "minha-instancia",
            "fieldsMap": {
              "lead_field01": "nome",
              "lead_field02": "email",
              "lead_field03": "telefone",
              "lead_field04": "cidade",
              "lead_field05": "estado",
              "lead_field06": "idade",
              "lead_field07": "interesses",
              "lead_field08": "origem",
              "lead_field09": "status",
              "lead_field10": "valor",
              "lead_field11": "observacoes",
              "lead_field12": "ultima_interacao",
              "lead_field13": "proximo_contato",
              "lead_field14": "vendedor",
              "lead_field15": "produto_interesse",
              "lead_field16": "fonte_captacao",
              "lead_field17": "score",
              "lead_field18": "tags",
              "lead_field19": "historico",
              "lead_field20": "custom"
            }
          }
        }
        ```

        Erros comuns:
        - 400: Campos inválidos ou payload mal formatado
        - 401: Token inválido ou expirado
        - 404: Instância não encontrada
        - 500: Erro ao atualizar campos no banco de dados

        Restrições:
        - Cada campo pode ter no máximo 255 caracteres
        - Campos vazios serão mantidos com seus valores atuais
        - Apenas os campos enviados serão atualizados
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                lead_field01:
                  type: string
                  description: Campo personalizado 01
                  maxLength: 255
                lead_field02:
                  type: string
                  description: Campo personalizado 02
                  maxLength: 255
                lead_field03:
                  type: string
                  description: Campo personalizado 03
                  maxLength: 255
                lead_field04:
                  type: string
                  description: Campo personalizado 04
                  maxLength: 255
                lead_field05:
                  type: string
                  description: Campo personalizado 05
                  maxLength: 255
                lead_field06:
                  type: string
                  description: Campo personalizado 06
                  maxLength: 255
                lead_field07:
                  type: string
                  description: Campo personalizado 07
                  maxLength: 255
                lead_field08:
                  type: string
                  description: Campo personalizado 08
                  maxLength: 255
                lead_field09:
                  type: string
                  description: Campo personalizado 09
                  maxLength: 255
                lead_field10:
                  type: string
                  description: Campo personalizado 10
                  maxLength: 255
                lead_field11:
                  type: string
                  description: Campo personalizado 11
                  maxLength: 255
                lead_field12:
                  type: string
                  description: Campo personalizado 12
                  maxLength: 255
                lead_field13:
                  type: string
                  description: Campo personalizado 13
                  maxLength: 255
                lead_field14:
                  type: string
                  description: Campo personalizado 14
                  maxLength: 255
                lead_field15:
                  type: string
                  description: Campo personalizado 15
                  maxLength: 255
                lead_field16:
                  type: string
                  description: Campo personalizado 16
                  maxLength: 255
                lead_field17:
                  type: string
                  description: Campo personalizado 17
                  maxLength: 255
                lead_field18:
                  type: string
                  description: Campo personalizado 18
                  maxLength: 255
                lead_field19:
                  type: string
                  description: Campo personalizado 19
                  maxLength: 255
                lead_field20:
                  type: string
                  description: Campo personalizado 20
                  maxLength: 255
      responses:
        '200':
          description: Sucesso
          content:
            application/json:
              schema:
                $ref: ../schemas/instance.yaml#/Instance
        '401':
          description: Token inválido/expirado
        '404':
          description: Instância não encontrada
        '500':
          description: Erro interno
  /instance/updateInstanceName:
    post:
      operationId: updateInstanceName
      tags:
        - Instancia
      summary: Atualizar nome da instância
      description: |
        Atualiza o nome de uma instância WhatsApp existente.
        O nome não precisa ser único.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Novo nome para a instância
                  example: Minha Nova Instância 2024!@#
              required:
                - name
      responses:
        '200':
          description: Sucesso
          content:
            application/json:
              schema:
                $ref: ../schemas/instance.yaml#/Instance
        '401':
          description: Token inválido/expirado
        '404':
          description: Instância não encontrada
        '500':
          description: Erro interno
  /instance/updateAdminFields:
    post:
      operationId: updateAdminFields
      tags:
        - Admininstração
      summary: Atualizar campos administrativos
      security:
        - admintoken: []
      description: >
        Atualiza os campos administrativos (adminField01/adminField02) de uma instância.


        Campos administrativos são opcionais e podem ser usados para armazenar metadados personalizados. 

        Estes campos são persistidos no banco de dados e podem ser utilizados para integrações com outros sistemas ou
        para armazenamento de informações internas.

        OS valores desses campos são vísiveis para o dono da instancia via token, porém apenas o administrador da api
        (via admin token) pode editá-los.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: ID da instância
                  example: inst_123456
                adminField01:
                  type: string
                  description: Campo administrativo 1
                  example: clientId_456
                adminField02:
                  type: string
                  description: Campo administrativo 2
                  example: integration_xyz
              required:
                - id
      responses:
        '200':
          description: Campos atualizados com sucesso
          content:
            application/json:
              schema:
                $ref: ../schemas/instance.yaml#/Instance
        '401':
          description: Token de administrador inválido
        '404':
          description: Instância não encontrada
        '500':
          description: Erro interno
  /instance/proxy:
    get:
      operationId: getProxyConfig
      tags:
        - Proxy
      summary: Obter configuração de proxy da instância
      description: >
        A zaptos opera com um proxy interno como padrão.

        Observação: nossos IPs são brasileiros. Se você atende clientes internacionais, considere usar um proxy do
        país/região do seu cliente (via `proxy_url`).

        Você pode:
          (1) continuar no proxy interno padrão;
          (2) usar um proxy próprio informando `proxy_url`. Se nada for definido, seguimos no proxy interno; ou
          (3) usar seu celular android como proxy instalando o aplicativo disponibilizado pela zaptos em https://github.com/zaptos/silver_proxy_apk (APK direto: https://github.com/zaptos/silver_proxy_apk/raw/refs/heads/main/silver_proxy.apk).

        A resposta desse endpoint traz o estado atual do proxy e o último teste de conectividade.
      security:
        - token: []
      responses:
        '200':
          description: Configuração de proxy recuperada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  enabled:
                    type: boolean
                    description: Indica se o proxy está habilitado
                  proxy_url:
                    type: string
                    description: URL do proxy (mascarada na resposta)
                  last_test_at:
                    type: integer
                    description: Timestamp (ms) do último teste
                  last_test_error:
                    type: string
                    description: Último erro de teste (se houver)
                  validation_error:
                    type: boolean
                    description: Indica se o último teste resultou em erro
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unauthorized
        '500':
          description: Erro interno do servidor ao recuperar a configuração
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
    post:
      operationId: updateProxyConfig
      tags:
        - Proxy
      summary: Configurar ou alterar o proxy
      description: >
        Permite habilitar ou trocar para:

        - Um proxy próprio (`proxy_url`), usando sua infraestrutura ou o aplicativo de celular para proxy próprio.

        - O proxy interno padrão (nenhum `proxy_url` enviado).


        Se nada for enviado, seguimos no proxy interno. A URL é validada antes de salvar. A conexão pode ser reiniciada
        automaticamente para aplicar a mudança.


        Opcional: você pode usar seu celular android como proxy instalando o aplicativo disponibilizado pela zaptos em
        https://github.com/zaptos/silver_proxy_apk (APK direto:
        https://github.com/zaptos/silver_proxy_apk/raw/refs/heads/main/silver_proxy.apk).
      security:
        - token: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                enable:
                  type: boolean
                  description: Define se o proxy deve ser habilitado; se `false`, remove o proxy atual
                  default: true
                proxy_url:
                  type: string
                  description: URL do proxy a ser usado (obrigatória se `enable=true` e quiser usar um proxy próprio)
                  example: http://usuario:senha@ip:porta
              required:
                - enable
      responses:
        '200':
          description: Proxy configurado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  details:
                    type: string
                    example: Proxy configurado
                  proxy:
                    type: object
                    properties:
                      enabled:
                        type: boolean
                      proxy_url:
                        type: string
                        description: URL mascarada do proxy salvo
                      last_test_at:
                        type: integer
                        description: Timestamp (ms) do último teste
                      last_test_error:
                        type: string
                        description: Último erro de teste (se houver)
                      validation_error:
                        type: boolean
                        description: Indica se o último teste resultou em erro
                  restart_requested:
                    type: boolean
                    description: Indica se uma reinicialização da conexão foi solicitada para aplicar o proxy
        '400':
          description: Payload inválido ou falha na validação do proxy
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: 'Falha ao validar proxy: ...'
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unauthorized
        '500':
          description: Erro interno do servidor ao configurar o proxy
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
    delete:
      operationId: deleteProxyConfig
      tags:
        - Proxy
      summary: Remover o proxy configurado
      description: |
        Desativa e apaga o proxy personalizado, voltando ao comportamento padrão (proxy interno).
        Pode reiniciar a conexão para aplicar a remoção.
      security:
        - token: []
      responses:
        '200':
          description: Configuração de proxy removida com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  details:
                    type: string
                    example: Proxy removido
                  proxy:
                    type: object
                    properties:
                      enabled:
                        type: boolean
                  restart_requested:
                    type: boolean
                    description: Indica se a conexão foi reiniciada para aplicar a mudança
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unauthorized
        '500':
          description: Erro interno do servidor ao deletar a configuração de proxy
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
  /profile/name:
    post:
      operationId: updateProfileName
      tags:
        - Perfil
      summary: Altera o nome do perfil do WhatsApp
      description: |
        Altera o nome de exibição do perfil da conta do WhatsApp atualmente conectada.

        O endpoint realiza:
        - Atualiza o nome do perfil usando o WhatsApp AppState
        - Sincroniza a mudança com o servidor do WhatsApp
        - Retorna confirmação da alteração

        **Importante**: 
        - A conta do WhatsApp deve estar conectada
        - O nome será visível para todos os contatos
        - Pode haver um limite de alterações por período (conforme WhatsApp)
      security:
        - token: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
                  description: Novo nome do perfil do WhatsApp
                  example: Minha Empresa - Atendimento
                  maxLength: 25
      responses:
        '200':
          description: Nome do perfil alterado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Nome do perfil alterado com sucesso
                  profile:
                    type: object
                    properties:
                      name:
                        type: string
                        description: Novo nome do perfil
                        example: Minha Empresa - Atendimento
                      updated_at:
                        type: integer
                        description: Timestamp da alteração (Unix timestamp)
                        example: 1704067200
        '400':
          description: Dados inválidos na requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Nome muito longo ou inválido
        '401':
          description: Sem sessão ativa
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
        '403':
          description: Ação não permitida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Limite de alterações excedido ou conta com restrições
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Erro ao alterar nome do perfil
  /profile/image:
    post:
      operationId: updateProfileImage
      tags:
        - Perfil
      summary: Altera a imagem do perfil do WhatsApp
      description: |
        Altera a imagem de perfil da conta do WhatsApp atualmente conectada.

        O endpoint realiza:
        - Atualiza a imagem do perfil usando 
        - Processa a imagem (URL, base64 ou comando de remoção)
        - Sincroniza a mudança com o servidor do WhatsApp
        - Retorna confirmação da alteração

        **Importante**: 
        - A conta do WhatsApp deve estar conectada
        - A imagem será visível para todos os contatos
        - A imagem deve estar em formato JPEG e tamanho 640x640 pixels
      security:
        - token: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - image
              properties:
                image:
                  type: string
                  description: |
                    Imagem do perfil. Pode ser:
                    - URL da imagem (http/https)
                    - String base64 da imagem
                    - "remove" ou "delete" para remover a imagem atual
                  example: https://picsum.photos/640/640.jpg
                  oneOf:
                    - description: URL da imagem
                      example: https://picsum.photos/640/640.jpg
                    - description: Imagem em base64
                      example: >-
                        data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCdABmX/9k=
                    - description: Comando para remover imagem
                      example: remove
      responses:
        '200':
          description: Imagem do perfil alterada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Imagem do perfil alterada com sucesso
                  profile:
                    type: object
                    properties:
                      image_updated:
                        type: boolean
                        description: Indica se a imagem foi atualizada
                        example: true
                      image_removed:
                        type: boolean
                        description: Indica se a imagem foi removida
                        example: false
                      updated_at:
                        type: integer
                        description: Timestamp da alteração (Unix timestamp)
                        example: 1704067200
        '400':
          description: Dados inválidos na requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Formato de imagem inválido ou URL inacessível
        '401':
          description: Sem sessão ativa
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
        '403':
          description: Ação não permitida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Limite de alterações excedido ou conta com restrições
        '413':
          description: Imagem muito grande
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Imagem muito grande, tamanho máximo permitido excedido
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Erro ao alterar imagem do perfil
  /instance:
    delete:
      operationId: deleteInstance
      tags:
        - Instancia
      summary: Deletar instância
      description: |
        Remove a instância do sistema.
      security:
        - token: []
      responses:
        '200':
          description: Instância deletada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Instance Deleted
                  info:
                    type: string
                    example: O dispositivo foi desconectado com sucesso e a instância foi removida do banco de dados.
        '401':
          description: Falha na autenticação
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Não autorizado - Token inválido ou ausente
        '404':
          description: Instância não encontrada
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Instância não encontrada
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Falha ao deletar instância
  /instance/privacy:
    get:
      operationId: getInstancePrivacy
      tags:
        - Instancia
      summary: Buscar configurações de privacidade
      description: >
        Busca as configurações de privacidade atuais da conta do WhatsApp atualmente conectada.


        **Importante - Diferença entre Status e Broadcast:**


        - **Status**: Refere-se ao recado personalizado que aparece embaixo do nome do usuário (ex: "Disponível",
        "Ocupado", texto personalizado)

        - **Broadcast**: Refere-se ao envio de "stories/reels" (fotos/vídeos temporários)


        **Limitação**: As configurações de privacidade do broadcast (stories/reels) não estão disponíveis para alteração
        via API.


        Retorna todas as configurações de privacidade como quem pode:

        - Adicionar aos grupos

        - Ver visto por último

        - Ver status (recado embaixo do nome)

        - Ver foto de perfil

        - Receber confirmação de leitura

        - Ver status online

        - Fazer chamadas
      responses:
        '200':
          description: Configurações de privacidade obtidas com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  groupadd:
                    type: string
                    enum:
                      - all
                      - contacts
                      - contact_blacklist
                      - none
                    description: Quem pode adicionar aos grupos. Valores - all, contacts, contact_blacklist, none
                    example: contacts
                  last:
                    type: string
                    enum:
                      - all
                      - contacts
                      - contact_blacklist
                      - none
                    description: Quem pode ver visto por último. Valores - all, contacts, contact_blacklist, none
                    example: contacts
                  status:
                    type: string
                    enum:
                      - all
                      - contacts
                      - contact_blacklist
                      - none
                    description: Quem pode ver status (recado embaixo do nome). Valores - all, contacts, contact_blacklist, none
                    example: contacts
                  profile:
                    type: string
                    enum:
                      - all
                      - contacts
                      - contact_blacklist
                      - none
                    description: Quem pode ver foto de perfil. Valores - all, contacts, contact_blacklist, none
                    example: contacts
                  readreceipts:
                    type: string
                    enum:
                      - all
                      - none
                    description: Confirmação de leitura. Valores - all, none
                    example: all
                  online:
                    type: string
                    enum:
                      - all
                      - match_last_seen
                    description: Quem pode ver status online. Valores - all, match_last_seen
                    example: all
                  calladd:
                    type: string
                    enum:
                      - all
                      - known
                    description: Quem pode fazer chamadas. Valores - all, known
                    example: all
              examples:
                success:
                  summary: Configurações de privacidade obtidas
                  value:
                    groupadd: contacts
                    last: contacts
                    status: contacts
                    profile: contacts
                    readreceipts: all
                    online: all
                    calladd: all
        '401':
          description: Token de autenticação inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
    post:
      tags:
        - Instancia
      summary: Alterar configurações de privacidade
      description: >
        Altera uma ou múltiplas configurações de privacidade da conta do WhatsApp atualmente conectada de forma
        otimizada.


        **Importante - Diferença entre Status e Broadcast:**


        - **Status**: Refere-se ao recado personalizado que aparece embaixo do nome do usuário (ex: "Disponível",
        "Ocupado", texto personalizado)

        - **Broadcast**: Refere-se ao envio de "stories/reels" (fotos/vídeos temporários)


        **Limitação**: As configurações de privacidade do broadcast (stories/reels) não estão disponíveis para alteração
        via API.


        **Características:**

        - ✅ **Eficiência**: Altera apenas configurações que realmente mudaram

        - ✅ **Flexibilidade**: Pode alterar uma ou múltiplas configurações na mesma requisição

        - ✅ **Feedback completo**: Retorna todas as configurações atualizadas


        **Formato de entrada:**

        ```json

        {
          "groupadd": "contacts",
          "last": "none",
          "status": "contacts"
        }

        ```


        **Tipos de privacidade disponíveis:**

        - `groupadd`: Quem pode adicionar aos grupos

        - `last`: Quem pode ver visto por último

        - `status`: Quem pode ver status (recado embaixo do nome)

        - `profile`: Quem pode ver foto de perfil

        - `readreceipts`: Confirmação de leitura

        - `online`: Quem pode ver status online

        - `calladd`: Quem pode fazer chamadas


        **Valores possíveis:**

        - `all`: Todos

        - `contacts`: Apenas contatos

        - `contact_blacklist`: Contatos exceto bloqueados

        - `none`: Ninguém

        - `match_last_seen`: Corresponder ao visto por último (apenas para online)

        - `known`: Números conhecidos (apenas para calladd)
      operationId: setPrivacySetting
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                groupadd:
                  type: string
                  enum:
                    - all
                    - contacts
                    - contact_blacklist
                    - none
                  description: Quem pode adicionar aos grupos. Valores - all, contacts, contact_blacklist, none
                last:
                  type: string
                  enum:
                    - all
                    - contacts
                    - contact_blacklist
                    - none
                  description: Quem pode ver visto por último. Valores - all, contacts, contact_blacklist, none
                status:
                  type: string
                  enum:
                    - all
                    - contacts
                    - contact_blacklist
                    - none
                  description: Quem pode ver status (recado embaixo do nome). Valores - all, contacts, contact_blacklist, none
                profile:
                  type: string
                  enum:
                    - all
                    - contacts
                    - contact_blacklist
                    - none
                  description: Quem pode ver foto de perfil. Valores - all, contacts, contact_blacklist, none
                readreceipts:
                  type: string
                  enum:
                    - all
                    - none
                  description: Confirmação de leitura. Valores - all, none
                online:
                  type: string
                  enum:
                    - all
                    - match_last_seen
                  description: Quem pode ver status online. Valores - all, match_last_seen
                calladd:
                  type: string
                  enum:
                    - all
                    - known
                  description: Quem pode fazer chamadas. Valores - all, known
              minProperties: 1
              additionalProperties: false
            examples:
              single_setting:
                summary: Alterar uma configuração
                value:
                  groupadd: contacts
              multiple_settings:
                summary: Alterar múltiplas configurações
                value:
                  groupadd: contacts
                  last: none
                  status: contacts
                  profile: contacts
              privacy_strict:
                summary: Configuração mais restritiva
                value:
                  groupadd: none
                  last: none
                  status: contacts
                  profile: contacts
                  readreceipts: none
      responses:
        '200':
          description: Configuração de privacidade alterada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  groupadd:
                    type: string
                    enum:
                      - all
                      - contacts
                      - contact_blacklist
                      - none
                    description: Quem pode adicionar aos grupos. Valores - all, contacts, contact_blacklist, none
                  last:
                    type: string
                    enum:
                      - all
                      - contacts
                      - contact_blacklist
                      - none
                    description: Quem pode ver visto por último. Valores - all, contacts, contact_blacklist, none
                  status:
                    type: string
                    enum:
                      - all
                      - contacts
                      - contact_blacklist
                      - none
                    description: Quem pode ver status (recado embaixo do nome). Valores - all, contacts, contact_blacklist, none
                  profile:
                    type: string
                    enum:
                      - all
                      - contacts
                      - contact_blacklist
                      - none
                    description: Quem pode ver foto de perfil. Valores - all, contacts, contact_blacklist, none
                  readreceipts:
                    type: string
                    enum:
                      - all
                      - none
                    description: Confirmação de leitura. Valores - all, none
                  online:
                    type: string
                    enum:
                      - all
                      - match_last_seen
                    description: Quem pode ver status online. Valores - all, match_last_seen
                  calladd:
                    type: string
                    enum:
                      - all
                      - known
                    description: Quem pode fazer chamadas. Valores - all, known
              examples:
                success:
                  summary: Configurações atualizadas após alteração
                  value:
                    groupadd: contacts
                    last: contacts
                    status: contacts
                    profile: contacts
                    readreceipts: all
                    online: all
                    calladd: all
        '400':
          description: Dados de entrada inválidos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
              examples:
                no_valid_settings:
                  summary: Nenhuma configuração válida encontrada
                  value:
                    error: 'No valid privacy settings found. Use format: {"groupadd": "contacts", "last": "none"}'
                invalid_value_type:
                  summary: Valor deve ser string
                  value:
                    error: Value for groupadd must be a non-empty string
                invalid_privacy_type:
                  summary: Tipo de privacidade inválido
                  value:
                    error: >-
                      invalid privacy type: invalidtype. Valid types: groupadd, last, status, profile, readreceipts,
                      online, calladd
                invalid_privacy_value:
                  summary: Valor de privacidade inválido
                  value:
                    error: >-
                      invalid privacy value: invalidvalue. Valid values: all, contacts, contact_blacklist, none,
                      match_last_seen, known
        '401':
          description: Token de autenticação inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
              examples:
                no_session:
                  summary: Sem sessão ativa
                  value:
                    error: No session
                whatsapp_error:
                  summary: Erro do WhatsApp
                  value:
                    error: 'Failed to set privacy setting: context deadline exceeded'
  /instance/presence:
    post:
      operationId: updateInstancePresence
      tags:
        - Instancia
      summary: Atualizar status de presença da instância
      description: >
        Atualiza o status de presença global da conta do WhatsApp atualmente conectada. Este endpoint permite:

        1. Definir se a conta aparece como disponível ("online") ou indisponível

        2. Controlar o status de presença para todos os contatos

        3. Salvar o estado atual da presença para a conta conectada


        Tipos de presença suportados:

        - available: Marca a conta como disponível/online

        - unavailable: Marca a conta como indisponível/offline


        **Atenção**:

        - O status de presença pode ser temporariamente alterado para "available" (online) em algumas situações internas
        da API, e com isso o visto por último também pode ser atualizado.

        - Caso isso for um problema, considere alterar suas configurações de privacidade no WhatsApp para não mostrar o
        visto por último e/ou quem pode ver seu status "online".


        **⚠️ Importante - Limitação do Presence "unavailable"**:

        - **Quando a API é o único dispositivo ativo**: Confirmações de entrega/leitura (ticks cinzas/azuis) não são
        enviadas nem recebidas

        - **Impacto**: Eventos `message_update` com status de entrega podem não ser recebidos

        - **Solução**: Se precisar das confirmações, mantenha WhatsApp Web ou aplicativo móvel ativo ou use presence
        "available" 


        Exemplo de requisição:

        ```json

        {
          "presence": "available"
        }

        ```


        Exemplo de resposta:

        ```json

        {
          "response": "Presence updated successfully"
        }

        ```


        Erros comuns:

        - 401: Token inválido ou expirado

        - 400: Valor de presença inválido

        - 500: Erro ao atualizar presença
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                presence:
                  type: string
                  description: Status de presença da conta atualmente conectada
                  enum:
                    - available
                    - unavailable
                  example: available
              required:
                - presence
      responses:
        '200':
          description: Presença atualizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    description: Mensagem de confirmação
                    example: Presence updated successfully
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro
                    examples:
                      - Invalid payload
                      - Invalid presence value, use available or unavailable
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro de autenticação
                    example: client not found
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro interno
                    example: No session
  /instance/updateDelaySettings:
    post:
      operationId: updateDelaySettings
      tags:
        - Instancia
      summary: Delay na fila de mensagens
      description: |
        Configura o intervalo de tempo entre mensagens diretas (async=true).

        ### Detalhes
        - Configuração aplicada apenas para mensagens diretas (não afeta campanhas)
        - Delay mínimo (msg_delay_min): 0 ou mais segundos (0 = sem delay)
        - Delay máximo (msg_delay_max): se menor que min, será ajustado para o mesmo valor de min
        - Sistema ajusta automaticamente valores negativos para 0

        ### Exemplo
        ```json
        {
          "msg_delay_min": 0,
          "msg_delay_max": 2
        }
        ```
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                msg_delay_min:
                  type: integer
                  format: int64
                  minimum: 0
                  description: Delay mínimo em segundos (0 = sem delay)
                  example: 0
                msg_delay_max:
                  type: integer
                  format: int64
                  minimum: 0
                  description: Delay máximo em segundos
                  example: 2
              required:
                - msg_delay_min
                - msg_delay_max
      responses:
        '200':
          description: Sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  instance:
                    $ref: ../schemas/instance.yaml#/Instance
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid request payload
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to update delay settings
  /send/text:
    post:
      operationId: sendText
      tags:
        - Enviar Mensagem
      summary: Enviar mensagem de texto
      description: >
        Envia uma mensagem de texto para um contato, grupo ou canal/newsletter.


        ## Recursos Específicos


        - **Preview de links** com suporte a personalização automática ou customizada

        - **Formatação básica** do texto

        - **Substituição automática de placeholders** dinâmicos


        ## Envio para Newsletter


        Para enviar texto para um canal, use o mesmo campo `number`, mas informe o JID completo do canal:

        - Exemplo: `120363123456789012@newsletter`


        ```json

        {
          "number": "120363123456789012@newsletter",
          "text": "Post publicado no canal"
        }

        ```


        ## Campos Comuns


        Este endpoint suporta todos os **campos opcionais comuns** documentados na tag **"Enviar Mensagem"**, incluindo:

        `delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `forward`, `track_source`, `track_id`, placeholders
        e envio para grupos.


        ## Preview de Links


        ### Preview Automático

        ```json

        {
          "number": "5511999999999",
          "text": "Confira: https://exemplo.com",
          "linkPreview": true
        }

        ```


        ### Preview Personalizado

        ```json

        {
          "number": "5511999999999",
          "text": "Confira nosso site! https://exemplo.com",
          "linkPreview": true,
          "linkPreviewTitle": "Título Personalizado",
          "linkPreviewDescription": "Uma descrição personalizada do link",
          "linkPreviewImage": "https://exemplo.com/imagem.jpg",
          "linkPreviewLarge": true
        }

        ```
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: >-
                    ID do chat para o qual a mensagem será enviada. Pode ser um número de telefone em formato
                    internacional, um ID de grupo (`@g.us`), um ID de usuário (com `@s.whatsapp.net` ou `@lid`) ou um ID
                    de canal/newsletter (`@newsletter`).
                  example: '5511999999999'
                text:
                  type: string
                  description: Texto da mensagem (aceita placeholders)
                  example: Olá {{name}}! Como posso ajudar?
                linkPreview:
                  type: boolean
                  description: >
                    Ativa/desativa preview de links. Se true, procura automaticamente um link no texto para gerar
                    preview.


                    Comportamento:

                    - Se apenas linkPreview=true: gera preview automático do primeiro link encontrado no texto

                    - Se fornecidos campos personalizados (title, description, image): usa os valores fornecidos

                    - Se campos personalizados parciais: combina com dados automáticos do link como fallback
                  example: true
                linkPreviewTitle:
                  type: string
                  description: Define um título personalizado para o preview do link
                  example: Título Personalizado
                linkPreviewDescription:
                  type: string
                  description: Define uma descrição personalizada para o preview do link
                  example: Descrição personalizada do link
                linkPreviewImage:
                  type: string
                  description: URL ou Base64 da imagem para usar no preview do link
                  example: https://exemplo.com/imagem.jpg
                linkPreviewLarge:
                  type: boolean
                  description: Se true, gera um preview grande com upload da imagem. Se false, gera um preview pequeno sem upload
                  example: true
                replyid:
                  type: string
                  description: ID da mensagem para responder
                  example: 3EB0538DA65A59F6D8A251
                mentions:
                  type: string
                  description: Números para mencionar (separados por vírgula)
                  example: 5511999999999,5511888888888
                readchat:
                  type: boolean
                  description: Marca conversa como lida após envio
                  example: true
                readmessages:
                  type: boolean
                  description: Marca últimas mensagens recebidas como lidas
                  example: true
                delay:
                  type: integer
                  description: Atraso em milissegundos antes do envio, durante o atraso apacerá 'Digitando...'
                  example: 1000
                forward:
                  type: boolean
                  description: Marca a mensagem como encaminhada no WhatsApp
                  example: true
                track_source:
                  type: string
                  description: Origem do rastreamento da mensagem
                  example: chatwoot
                track_id:
                  type: string
                  description: ID para rastreamento da mensagem (aceita valores duplicados)
                  example: msg_123456789
                async:
                  type: boolean
                  description: Se true, envia a mensagem de forma assíncrona via fila interna. Útil para alto volume de mensagens.
                  example: false
              required:
                - number
                - text
            examples:
              basic:
                summary: Mensagem básica
                description: Exemplo mais simples possível
                value:
                  number: '5511999999999'
                  text: Olá! Como posso ajudar?
              withLinkPreview:
                summary: Com preview automático
                description: Preview automático de link no texto
                value:
                  number: '5511999999999'
                  text: 'Confira: https://exemplo.com'
                  linkPreview: true
              customLinkPreview:
                summary: Preview personalizado
                description: Preview com título, descrição e imagem customizados
                value:
                  number: '5511999999999'
                  text: Confira nosso site! https://exemplo.com
                  linkPreview: true
                  linkPreviewTitle: Título Personalizado
                  linkPreviewDescription: Uma descrição personalizada do link
                  linkPreviewImage: https://exemplo.com/imagem.jpg
                  linkPreviewLarge: true
              withPlaceholders:
                summary: Com placeholders
                description: Texto com variáveis dinâmicas
                value:
                  number: '5511999999999'
                  text: Olá {{name}}! Sua empresa {{company}} está cadastrada.
              newsletter:
                summary: Envio para newsletter
                description: Publica uma mensagem de texto em um canal usando o JID completo `@newsletter`.
                value:
                  number: 120363123456789012@newsletter
                  text: Post publicado no canal
      responses:
        '200':
          description: Mensagem enviada com sucesso
          content:
            application/json:
              schema:
                allOf:
                  - $ref: ../schemas/message.yaml#/Message
                  - type: object
                    properties:
                      response:
                        type: object
                        properties:
                          status:
                            type: string
                            example: success
                          message:
                            type: string
                            example: Message sent successfully
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Missing number or text
        '401':
          description: Não autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid token
        '429':
          description: Limite de requisições excedido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Rate limit exceeded
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: >-
                      WhatsApp server error 463: WhatsApp reported that the currently connected account is under a
                      temporary restriction for starting new conversations, usually related to sending volume or
                      quality.
                  error_source:
                    type: string
                    example: whatsapp_server
                  provider:
                    type: string
                    example: whatsapp
                  provider_code:
                    type: integer
                    example: 463
                  error_key:
                    type: string
                    example: WHATSAPP_REACHOUT_TIMELOCK
                  message:
                    type: string
                    example: The WhatsApp server rejected this message. This was not an internal API error.
                  message_ptbr:
                    type: string
                    example: O servidor do WhatsApp recusou esta mensagem. Isso não foi um erro interno da API.
                  provider_message:
                    type: string
                    example: >-
                      WhatsApp reported that the currently connected account is under a temporary restriction for
                      starting new conversations, usually related to sending volume or quality.
                  provider_message_ptbr:
                    type: string
                    example: >-
                      O WhatsApp informou que a conta atualmente conectada está sob uma restrição temporária para
                      iniciar novas conversas, normalmente relacionada a volume ou qualidade de envios.
                  diagnostics_endpoint:
                    type: string
                    example: /instance/wa_messages_limits
                  details:
                    type: object
                    properties:
                      new_chat_message_capping:
                        type: object
                        additionalProperties: true
                      reachout_timelock:
                        type: object
                        additionalProperties: true
              examples:
                generic:
                  summary: Erro interno genérico
                  value:
                    error: Failed to send message
                whatsapp_463:
                  summary: Erro do WhatsApp ao iniciar novas conversas
                  value:
                    error: >-
                      WhatsApp server error 463: WhatsApp reported that the currently connected account is under a
                      temporary restriction for starting new conversations, usually related to sending volume or
                      quality.
                    error_source: whatsapp_server
                    provider: whatsapp
                    provider_code: 463
                    error_key: WHATSAPP_REACHOUT_TIMELOCK
                    message: The WhatsApp server rejected this message. This was not an internal API error.
                    message_ptbr: O servidor do WhatsApp recusou esta mensagem. Isso não foi um erro interno da API.
                    provider_message: >-
                      WhatsApp reported that the currently connected account is under a temporary restriction for
                      starting new conversations, usually related to sending volume or quality.
                    provider_message_ptbr: >-
                      O WhatsApp informou que a conta atualmente conectada está sob uma restrição temporária para
                      iniciar novas conversas, normalmente relacionada a volume ou qualidade de envios.
                    diagnostics_endpoint: /instance/wa_messages_limits
                    details:
                      new_chat_message_capping:
                        available: true
                        status: CAPPED
                        used_quota: 10
                        total_quota: 10
                      reachout_timelock:
                        available: true
                        active: true
                        until: '2026-04-07T12:00:00Z'
                        enforcement_type: BIZ_QUALITY
  /send/media:
    post:
      operationId: sendMedia
      tags:
        - Enviar Mensagem
      summary: Enviar mídia (imagem, vídeo, áudio ou documento)
      description: >
        Envia diferentes tipos de mídia para um contato, grupo ou canal/newsletter. Suporta URLs ou arquivos base64.


        ## Tipos de Mídia Suportados

        - **`image`**: Imagens (JPG preferencialmente)

        - **`video`**: Vídeos (apenas MP4)

        - **`videoplay`**: Vídeo com comportamento visual de autoplay/loop no WhatsApp

        - **`document`**: Documentos (PDF, DOCX, XLSX, etc)

        - **`audio`**: Áudio comum (MP3 ou OGG)

        - **`myaudio`**: Mensagem de voz (alternativa ao PTT)

        - **`ptt`**: Mensagem de voz (Push-to-Talk)

        - **`ptv`**: Mensagem de vídeo (Push-to-Video)

        - **`sticker`**: Figurinha/Sticker


        ## Recursos Específicos

        - **Upload por URL ou base64**

        - **Caption/legenda** opcional com suporte a placeholders

        - **Nome personalizado** para documentos (`docName`)

        - **Geração automática de thumbnails**

        - **Compressão otimizada** conforme o tipo

        - **`viewOnce`** recomendado para mídia compatível


        ## Envio para Newsletter


        Para enviar mídia para um canal, use o mesmo campo `number`, mas informe o JID completo do canal:

        - Exemplo: `120363123456789012@newsletter`


        ```json

        {
          "number": "120363123456789012@newsletter",
          "type": "image",
          "file": "https://exemplo.com/foto.jpg",
          "text": "Imagem publicada no canal"
        }

        ```


        ## Campos Comuns


        Este endpoint suporta todos os **campos opcionais comuns** documentados na tag **"Enviar Mensagem"**, incluindo:

        `delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `forward`, `track_source`, `track_id`, placeholders
        e envio para grupos.


        ## Exemplos Básicos


        ## Visualização Única (`viewOnce`)


        O campo `viewOnce` é recomendado quando quiser mídia de visualização única e hoje produz efeito para os tipos:

        `image`, `video`, `videoplay`, `ptv`, `audio`, `myaudio` e `ptt`.


        Para `document`, `sticker` e demais endpoints de envio, o campo é ignorado silenciosamente.


        ### Imagem Simples

        ```json

        {
          "number": "5511999999999",
          "type": "image",
          "file": "https://exemplo.com/foto.jpg"
        }

        ```


        ### Documento com Nome

        ```json

        {
          "number": "5511999999999",
          "type": "document",
          "file": "https://exemplo.com/contrato.pdf",
          "docName": "Contrato.pdf",
          "text": "Segue o documento solicitado"
        }

        ```
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: >-
                    ID do chat para o qual a mensagem será enviada. Pode ser um número de telefone em formato
                    internacional, um ID de grupo (`@g.us`), um ID de usuário (com `@s.whatsapp.net` ou `@lid`) ou um ID
                    de canal/newsletter (`@newsletter`).
                  example: '5511999999999'
                type:
                  type: string
                  description: Tipo de mídia (image, video, videoplay, document, audio, myaudio, ptt, ptv, sticker)
                  enum:
                    - image
                    - video
                    - videoplay
                    - document
                    - audio
                    - myaudio
                    - ptt
                    - ptv
                    - sticker
                  example: image
                file:
                  type: string
                  description: URL ou base64 do arquivo
                  example: https://exemplo.com/imagem.jpg
                text:
                  type: string
                  description: Texto descritivo (caption) - aceita placeholders
                  example: Veja esta foto!
                docName:
                  type: string
                  description: Nome do arquivo (apenas para documents)
                  example: relatorio.pdf
                thumbnail:
                  type: string
                  description: URL ou base64 de thumbnail personalizado para vídeos e documentos
                  example: https://exemplo.com/thumb.jpg
                mimetype:
                  type: string
                  description: MIME type do arquivo (opcional, detectado automaticamente)
                  example: application/pdf
                replyid:
                  type: string
                  description: ID da mensagem para responder
                  example: 3EB0538DA65A59F6D8A251
                mentions:
                  type: string
                  description: Números para mencionar (separados por vírgula)
                  example: 5511999999999,5511888888888
                readchat:
                  type: boolean
                  description: Marca conversa como lida após envio
                  example: true
                readmessages:
                  type: boolean
                  description: Marca últimas mensagens recebidas como lidas
                  example: true
                delay:
                  type: integer
                  description: >-
                    Atraso em milissegundos antes do envio, durante o atraso apacerá 'Digitando...' ou 'Gravando
                    áudio...'
                  example: 1000
                forward:
                  type: boolean
                  description: Marca a mensagem como encaminhada no WhatsApp
                  example: true
                track_source:
                  type: string
                  description: Origem do rastreamento da mensagem
                  example: chatwoot
                track_id:
                  type: string
                  description: ID para rastreamento da mensagem (aceita valores duplicados)
                  example: msg_123456789
                async:
                  type: boolean
                  description: Se true, envia a mensagem de forma assíncrona via fila interna
                  example: false
                viewOnce:
                  type: boolean
                  description: >-
                    Recomendado para mídia com visualização única em tipos compatíveis (`image`, `video`, `videoplay`,
                    `ptv`, `audio`, `myaudio`, `ptt`). Em tipos não compatíveis, o campo é ignorado silenciosamente.
                  example: false
              required:
                - number
                - type
                - file
            examples:
              image:
                summary: Imagem
                description: Envio de imagem simples
                value:
                  number: '5511999999999'
                  type: image
                  file: https://exemplo.com/foto.jpg
              imageWithCaption:
                summary: Imagem com legenda
                description: Imagem com texto descritivo
                value:
                  number: '5511999999999'
                  type: image
                  file: https://exemplo.com/foto.jpg
                  text: Veja esta foto!
              imageViewOnce:
                summary: Imagem view once
                description: Imagem enviada como visualização única
                value:
                  number: '5511999999999'
                  type: image
                  file: https://exemplo.com/foto.jpg
                  text: Abra uma vez
                  viewOnce: true
              document:
                summary: Documento
                description: Documento PDF com nome personalizado
                value:
                  number: '5511999999999'
                  type: document
                  file: https://exemplo.com/contrato.pdf
                  docName: Contrato.pdf
                  text: Segue o documento solicitado
              audio:
                summary: Mensagem de voz
                description: Arquivo de áudio como mensagem de voz
                value:
                  number: '5511999999999'
                  type: ptt
                  file: https://exemplo.com/audio.ogg
              video:
                summary: Vídeo
                description: Arquivo de vídeo com legenda
                value:
                  number: '5511999999999'
                  type: video
                  file: https://exemplo.com/video.mp4
                  text: Confira este vídeo!
              videoplay:
                summary: Vídeo com autoplay
                description: Vídeo MP4 enviado com comportamento visual de autoplay/loop no WhatsApp
                value:
                  number: '5511999999999'
                  type: videoplay
                  file: https://exemplo.com/video.mp4
                  text: Confira este vídeo
              ptv:
                summary: Mensagem de vídeo
                description: Arquivo de vídeo como mensagem de vídeo
                value:
                  number: '5511999999999'
                  type: ptv
                  file: https://exemplo.com/video.mp4
              sticker:
                summary: Figurinha
                description: Envio de figurinha/sticker
                value:
                  number: '5511999999999'
                  type: sticker
                  file: https://exemplo.com/sticker.webp
              newsletterImage:
                summary: Imagem para newsletter
                description: Publica uma imagem em um canal usando o JID completo `@newsletter`.
                value:
                  number: 120363123456789012@newsletter
                  type: image
                  file: https://exemplo.com/foto.jpg
                  text: Imagem publicada no canal
              newsletterDocument:
                summary: Documento para newsletter
                description: Publica um documento em um canal usando o JID completo `@newsletter`.
                value:
                  number: 120363123456789012@newsletter
                  type: document
                  file: https://exemplo.com/contrato.pdf
                  docName: Contrato.pdf
                  text: Documento publicado no canal
      responses:
        '200':
          description: Mídia enviada com sucesso
          content:
            application/json:
              schema:
                allOf:
                  - $ref: ../schemas/message.yaml#/Message
                  - type: object
                    properties:
                      response:
                        type: object
                        properties:
                          status:
                            type: string
                            example: success
                          message:
                            type: string
                            example: Media sent successfully
                          fileUrl:
                            type: string
                            example: https://mmg.whatsapp.net/...
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid media type or file format
        '401':
          description: Não autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid token
        '413':
          description: Arquivo muito grande
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: File size exceeds limit
        '415':
          description: Formato de mídia não suportado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unsupported media format
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to upload media
  /send/contact:
    post:
      operationId: sendContact
      tags:
        - Enviar Mensagem
      summary: Enviar cartão de contato (vCard)
      description: >
        Envia um cartão de contato (vCard) para um contato ou grupo.


        ## Recursos Específicos


        - **vCard completo** com nome, telefones, organização, email e URL

        - **Múltiplos números de telefone** (separados por vírgula)

        - **Cartão clicável** no WhatsApp para salvar na agenda

        - **Informações profissionais** (organização/empresa)


        ## Campos Comuns


        Este endpoint suporta todos os **campos opcionais comuns** documentados na tag **"Enviar Mensagem"**, incluindo:

        `delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `forward`, `track_source`, `track_id`, placeholders
        e envio para grupos.


        ## Exemplo Básico

        ```json

        {
          "number": "5511999999999",
          "fullName": "João Silva",
          "phoneNumber": "5511999999999,5511888888888",
          "organization": "Empresa XYZ",
          "email": "joao.silva@empresa.com",
          "url": "https://empresa.com/joao"
        }

        ```
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: >-
                    ID do chat para o qual a mensagem será enviada. Pode ser um número de telefone em formato
                    internacional, um ID de grupo (`@g.us`), um ID de usuário (com `@s.whatsapp.net` ou `@lid`).
                  example: '5511999999999'
                fullName:
                  type: string
                  description: Nome completo do contato
                  example: João Silva
                phoneNumber:
                  type: string
                  description: Números de telefone (separados por vírgula)
                  example: 5511999999999,5511888888888
                organization:
                  type: string
                  description: Nome da organização/empresa
                  example: Empresa XYZ
                email:
                  type: string
                  description: Endereço de email
                  example: joao@empresa.com
                url:
                  type: string
                  description: URL pessoal ou da empresa
                  example: https://empresa.com/joao
                replyid:
                  type: string
                  description: ID da mensagem para responder
                  example: 3EB0538DA65A59F6D8A251
                mentions:
                  type: string
                  description: Números para mencionar (separados por vírgula)
                  example: 5511999999999,5511888888888
                readchat:
                  type: boolean
                  description: Marca conversa como lida após envio
                  example: true
                readmessages:
                  type: boolean
                  description: Marca últimas mensagens recebidas como lidas
                  example: true
                delay:
                  type: integer
                  description: Atraso em milissegundos antes do envio, durante o atraso apacerá 'Digitando...'
                  example: 1000
                forward:
                  type: boolean
                  description: Marca a mensagem como encaminhada no WhatsApp
                  example: true
                track_source:
                  type: string
                  description: Origem do rastreamento da mensagem
                  example: chatwoot
                track_id:
                  type: string
                  description: ID para rastreamento da mensagem (aceita valores duplicados)
                  example: msg_123456789
                async:
                  type: boolean
                  description: Se true, envia a mensagem de forma assíncrona via fila interna
                  example: false
              required:
                - number
                - fullName
                - phoneNumber
      responses:
        '200':
          description: Cartão de contato enviado com sucesso
          content:
            application/json:
              schema:
                allOf:
                  - $ref: ../schemas/message.yaml#/Message
                  - type: object
                    properties:
                      response:
                        type: object
                        properties:
                          status:
                            type: string
                            example: success
                          message:
                            type: string
                            example: Contact card sent successfully
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Missing required fields
        '401':
          description: Não autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid token
        '429':
          description: Limite de requisições excedido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Rate limit exceeded
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to send contact card
  /send/location:
    post:
      operationId: sendLocation
      tags:
        - Enviar Mensagem
      summary: Enviar localização geográfica
      description: >
        Envia uma localização geográfica para um contato ou grupo.


        ## Recursos Específicos


        - **Coordenadas precisas** (latitude e longitude obrigatórias)

        - **Nome do local** para identificação

        - **Endereço completo** para exibição detalhada

        - **Mapa interativo** no WhatsApp para navegação

        - **Pin personalizado** com nome do local


        ## Campos Comuns


        Este endpoint suporta todos os **campos opcionais comuns** documentados na tag **"Enviar Mensagem"**, incluindo:

        `delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `forward`, `track_source`, `track_id`, placeholders
        e envio para grupos.


        ## Exemplo Básico

        ```json

        {
          "number": "5511999999999",
          "name": "Maracanã",
          "address": "Av. Pres. Castelo Branco - Maracanã, Rio de Janeiro - RJ",
          "latitude": -22.912982815767986,
          "longitude": -43.23028153499254
        }

        ```
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: >-
                    ID do chat para o qual a mensagem será enviada. Pode ser um número de telefone em formato
                    internacional, um ID de grupo (`@g.us`), um ID de usuário (com `@s.whatsapp.net` ou `@lid`).
                  example: '5511999999999'
                name:
                  type: string
                  description: Nome do local
                  example: MASP
                address:
                  type: string
                  description: Endereço do local
                  example: Av. Paulista, 1578 - Bela Vista, São Paulo - SP
                latitude:
                  type: number
                  description: Latitude (-90 a 90)
                  example: -23.5616
                longitude:
                  type: number
                  description: Longitude (-180 a 180)
                  example: -46.6562
                replyid:
                  type: string
                  description: ID da mensagem para responder
                  example: 3EB0538DA65A59F6D8A251
                mentions:
                  type: string
                  description: Números para mencionar (separados por vírgula)
                  example: 5511999999999,5511888888888
                readchat:
                  type: boolean
                  description: Marca conversa como lida após envio
                  example: true
                readmessages:
                  type: boolean
                  description: Marca últimas mensagens recebidas como lidas
                  example: true
                delay:
                  type: integer
                  description: Atraso em milissegundos antes do envio, durante o atraso apacerá 'Digitando...'
                  example: 1000
                forward:
                  type: boolean
                  description: Marca a mensagem como encaminhada no WhatsApp
                  example: true
                track_source:
                  type: string
                  description: Origem do rastreamento da mensagem
                  example: chatwoot
                track_id:
                  type: string
                  description: ID para rastreamento da mensagem (aceita valores duplicados)
                  example: msg_123456789
                async:
                  type: boolean
                  description: Se true, envia a mensagem de forma assíncrona via fila interna
                  example: false
              required:
                - number
                - latitude
                - longitude
      responses:
        '200':
          description: Localização enviada com sucesso
          content:
            application/json:
              schema:
                allOf:
                  - $ref: ../schemas/message.yaml#/Message
                  - type: object
                    properties:
                      response:
                        type: object
                        properties:
                          status:
                            type: string
                            example: success
                          message:
                            type: string
                            example: Location sent successfully
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid coordinates or missing number
        '401':
          description: Não autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid token
        '429':
          description: Limite de requisições excedido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Rate limit exceeded
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to send location
  /message/presence:
    post:
      operationId: sendPresence
      tags:
        - Enviar Mensagem
      summary: Enviar atualização de presença
      description: |
        Envia uma atualização de presença para um contato ou grupo de forma **assíncrona**.

        ## 🔄 Comportamento Assíncrono:
        - **Execução independente**: A presença é gerenciada em background, não bloqueia o retorno da API
        - **Limite máximo**: 5 minutos de duração (300 segundos)
        - **Tick de atualização**: Reenvia a presença a cada 10 segundos
        - **Cancelamento automático**: Presença é cancelada automaticamente ao enviar uma mensagem para o mesmo chat

        ## 📱 Tipos de presença suportados:
        - **composing**: Indica que você está digitando uma mensagem
        - **recording**: Indica que você está gravando um áudio
        - **paused**: Remove/cancela a indicação de presença atual

        ## ⏱️ Controle de duração:
        - **Sem delay**: Usa limite padrão de 5 minutos
        - **Com delay**: Usa o valor especificado (máximo 5 minutos)
        - **Cancelamento**: Envio de mensagem cancela presença automaticamente

        ## 📋 Exemplos de uso:

        ### Digitar por 30 segundos:
        ```json
        {
          "number": "5511999999999",
          "presence": "composing",
          "delay": 30000
        }
        ```

        ### Gravar áudio por 1 minuto:
        ```json
        {
          "number": "5511999999999",
          "presence": "recording",
          "delay": 60000
        }
        ```

        ### Cancelar presença atual:
        ```json
        {
          "number": "5511999999999",
          "presence": "paused"
        }
        ```

        ### Usar limite máximo (5 minutos):
        ```json
        {
          "number": "5511999999999",
          "presence": "composing"
        }
        ```
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: 'Número do destinatário no formato internacional (ex: 5511999999999)'
                  example: '5511999999999'
                presence:
                  type: string
                  description: Tipo de presença a ser enviada
                  enum:
                    - composing
                    - recording
                    - paused
                  example: composing
                delay:
                  type: integer
                  description: |
                    Duração em milissegundos que a presença ficará ativa (máximo 5 minutos = 300000ms).
                    Se não informado ou valor maior que 5 minutos, usa o limite padrão de 5 minutos.
                    A presença é reenviada a cada 10 segundos durante este período.
                  maximum: 300000
                  example: 30000
              required:
                - number
                - presence
      responses:
        '200':
          description: Presença atualizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    description: Mensagem de confirmação
                    example: Chat presence sent successfully
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro
                    example: Número inválido ou tipo de presença inválido
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro de autenticação
                    example: Token inválido ou expirado
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro interno
                    example: Erro ao enviar presença
  /send/status:
    post:
      operationId: sendStatus
      tags:
        - Enviar Mensagem
      summary: Enviar Stories (Status)
      description: >
        Envia um story (status) com suporte para texto, imagem, vídeo e áudio.


        **Suporte a campos de rastreamento**: Este endpoint também suporta `track_source` e `track_id` documentados na
        tag **"Enviar Mensagem"**.


        ## Tipos de Status

        - text: Texto com estilo e cor de fundo

        - image: Imagens com legenda opcional

        - video: Vídeos com thumbnail e legenda

        - audio: Áudio normal ou mensagem de voz (PTT)


        ## Cores de Fundo

        - 1-3: Tons de amarelo

        - 4-6: Tons de verde

        - 7-9: Tons de azul

        - 10-12: Tons de lilás

        - 13: Magenta

        - 14-15: Tons de rosa

        - 16: Marrom claro

        - 17-19: Tons de cinza (19 é o padrão)


        ## Fontes (para texto)

        - 0: Padrão 

        - 1-8: Estilos alternativos


        ## Limites

        - Texto: Máximo 656 caracteres

        - Imagem: JPG, PNG, GIF

        - Vídeo: MP4, MOV

        - Áudio: MP3, OGG, WAV (convertido para OGG/OPUS)


        ## Exemplo

        ```json

        {
          "type": "text",
          "text": "Novidades chegando!",
          "background_color": 7,
          "font": 1
        }

        ```
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - text
                    - image
                    - video
                    - audio
                    - myaudio
                    - ptt
                  description: Tipo do status
                  example: text
                text:
                  type: string
                  description: Texto principal ou legenda
                  example: Novidades chegando!
                background_color:
                  type: integer
                  minimum: 1
                  maximum: 19
                  description: Código da cor de fundo
                  example: 7
                font:
                  type: integer
                  minimum: 0
                  maximum: 8
                  description: Estilo da fonte (apenas para type=text)
                  example: 1
                file:
                  type: string
                  description: URL ou Base64 do arquivo de mídia
                  example: https://example.com/video.mp4
                thumbnail:
                  type: string
                  description: URL ou Base64 da miniatura (opcional para vídeos)
                  example: https://example.com/thumb.jpg
                mimetype:
                  type: string
                  description: MIME type do arquivo (opcional)
                  example: video/mp4
                replyid:
                  type: string
                  description: ID da mensagem para responder
                  example: 3EB0538DA65A59F6D8A251
                mentions:
                  type: string
                  description: Números para mencionar (separados por vírgula)
                  example: 5511999999999,5511888888888
                readchat:
                  type: boolean
                  description: Marca conversa como lida após envio
                  example: true
                readmessages:
                  type: boolean
                  description: Marca últimas mensagens recebidas como lidas
                  example: true
                delay:
                  type: integer
                  description: Atraso em milissegundos antes do envio
                  example: 1000
                forward:
                  type: boolean
                  description: Marca a mensagem como encaminhada no WhatsApp
                  example: false
                async:
                  type: boolean
                  description: Se true, envia a mensagem de forma assíncrona via fila interna
                  example: false
                track_source:
                  type: string
                  description: Origem do rastreamento da mensagem
                  example: chatwoot
                track_id:
                  type: string
                  description: ID para rastreamento da mensagem (aceita valores duplicados)
                  example: msg_123456789
              required:
                - type
      responses:
        '200':
          description: Status enviado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  Id:
                    type: string
                    example: ABCD1234
                  content:
                    type: object
                    description: Conteúdo processado da mensagem
                  messageTimestamp:
                    type: integer
                    example: 1672531200000
                  status:
                    type: string
                    example: Pending
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Text too long
        '401':
          description: Não autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to upload media
  /send/menu:
    post:
      operationId: sendMenu
      tags:
        - Enviar Mensagem
      summary: Enviar menu interativo (botões, carrosel, lista ou enquete)
      description: >
        Este endpoint oferece uma interface unificada para envio de quatro tipos principais de mensagens interativas:

        - Botões: Para ações rápidas e diretas

        - Carrosel de Botões: Para uma lista horizontal de botões com imagens

        - Listas: Para menus organizados em seções

        - Enquetes: Para coleta de opiniões e votações


        **Suporte a campos de rastreamento**: Este endpoint também suporta `track_source` e `track_id` documentados na
        tag **"Enviar Mensagem"**.


        ## Estrutura Base do Payload


        Todas as requisições seguem esta estrutura base:


        ```json

        {
          "number": "5511999999999",
          "type": "button|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 Mensagens Interativas


        ### 1. Botões (type: "button")


        Cria botões interativos com diferentes funcionalidades de ação.


        #### Campos Específicos

        - `footerText`: Texto opcional exibido abaixo da mensagem principal

        - `choices`: Array de opções que serão convertidas em botões


        #### Formatos de Botões

        Cada botão pode ser configurado usando `|` (pipe) ou `\n` (quebra de linha) como separadores:


        - **Botão de Resposta**: 
          - `"texto|id"` ou 
          - `"texto\nid"` ou 
          - `"texto"` (ID será igual ao texto)

        - **Botão de Cópia**: 
          - `"texto|copy:código"` ou 
          - `"texto\ncopy:código"`

        - **Botão de Chamada**: 
          - `"texto|call:+5511999999999"` ou 
          - `"texto\ncall:+5511999999999"`

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

        #### Botões com Imagem

        Para adicionar uma imagem aos botões, use o campo `imageButton` no payload:


        #### Exemplo com Imagem

        ```json

        {
          "number": "5511999999999",
          "type": "button",
          "text": "Escolha um produto:",
          "imageButton": "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"
        }

        ```


        > **Suporte**: O campo `imageButton` aceita URLs ou imagens em base64.


        #### Exemplo 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"
        }

        ```


        #### Limitações e Compatibilidade

        > **Importante**: Ao combinar botões de resposta com outros tipos (call, url, copy) na mesma mensagem, será
        exibido o aviso: "Não é possível exibir esta mensagem no WhatsApp Web. Abra o WhatsApp no seu celular para
        visualizá-la."


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


        Cria menus organizados em seções com itens selecionáveis.


        #### Campos Específicos

        - `listButton`: Texto do botão que abre a lista

        - `footerText`: Texto opcional do rodapé

        - `choices`: Array com seções e itens da lista


        #### Formato das Choices

        - `"[Título da Seção]"`: Inicia uma nova seção

        - `"texto|id|descrição"`: Item da lista com:
          - texto: Label do item
          - id: Identificador único, opcional
          - descrição: Texto descritivo adicional e opcional

        #### Exemplo 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. Enquetes (type: "poll")


        Cria enquetes interativas para votação.


        #### Campos Específicos

        - `selectableCount`: Número de opções que podem ser selecionadas (padrão: 1)

        - `choices`: Array simples com as opções de voto


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


        Cria um carrossel de cartões com imagens e botões interativos.


        #### Campos Específicos

        - `choices`: Array com elementos do carrossel na seguinte ordem:
          - `[Texto do cartão]`: Texto do cartão entre colchetes
          - `{URL ou base64 da imagem}`: Imagem entre chaves
          - Botões do cartão (um por linha):
            - `"texto|copy:código"` para botão de copiar
            - `"texto|https://url"` para botão de link
            - `"texto|call:+número"` para botão de ligação

        #### Exemplo 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**: Criamos outro endpoint para carrossel: `/send/carousel`, funciona da mesma forma, mas com outro
        formato de payload. Veja o que é mais fácil para você.


        ## Termos de uso


        Os recursos de botões interativos e listas podem ser descontinuados a qualquer momento sem aviso prévio. Não nos
        responsabilizamos por quaisquer alterações ou indisponibilidade destes recursos.


        ### Alternativas e Compatibilidade


        Considerando a natureza dinâmica destes recursos, nosso endpoint foi projetado para facilitar a migração entre
        diferentes tipos de mensagens (botões, listas e enquetes). 


        Recomendamos criar seus fluxos de forma flexível, preparados para alternar entre os diferentes tipos.


        Em caso de descontinuidade de algum recurso, você poderá facilmente migrar para outro tipo de mensagem apenas
        alterando o campo "type" no payload, mantendo a mesma estrutura de choices.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: >-
                    ID do chat para o qual a mensagem será enviada. Pode ser um número de telefone em formato
                    internacional, um ID de grupo (`@g.us`), um ID de usuário (com `@s.whatsapp.net` ou `@lid`).
                  example: '5511999999999'
                type:
                  type: string
                  description: Tipo do menu (button, list, poll, carousel)
                  enum:
                    - button
                    - list
                    - poll
                    - carousel
                  example: list
                text:
                  type: string
                  description: Texto principal (aceita placeholders)
                  example: 'Escolha uma opção:'
                footerText:
                  type: string
                  description: Texto do rodapé (opcional)
                  example: Menu de serviços
                listButton:
                  type: string
                  description: Texto do botão principal
                  example: Ver opções
                selectableCount:
                  type: integer
                  description: Número máximo de opções selecionáveis (para enquetes)
                  example: 1
                choices:
                  type: array
                  description: Lista de opções. Use [Título] para seções em 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
                imageButton:
                  type: string
                  description: 'URL da imagem para botões (recomendado para type: button)'
                  example: https://exemplo.com/imagem-botao.jpg
                replyid:
                  type: string
                  description: ID da mensagem para responder
                  example: 3EB0538DA65A59F6D8A251
                mentions:
                  type: string
                  description: Números para mencionar (separados por vírgula)
                  example: 5511999999999,5511888888888
                readchat:
                  type: boolean
                  description: Marca conversa como lida após envio
                  example: true
                readmessages:
                  type: boolean
                  description: Marca últimas mensagens recebidas como lidas
                  example: true
                delay:
                  type: integer
                  description: Atraso em milissegundos antes do envio, durante o atraso apacerá 'Digitando...'
                  example: 1000
                track_source:
                  type: string
                  description: Origem do rastreamento da mensagem
                  example: chatwoot
                track_id:
                  type: string
                  description: ID para rastreamento da mensagem (aceita valores duplicados)
                  example: msg_123456789
                async:
                  type: boolean
                  description: Se true, envia a mensagem de forma assíncrona via fila interna
                  example: false
              required:
                - number
                - type
                - text
                - choices
      responses:
        '200':
          description: Menu enviado com sucesso
          content:
            application/json:
              schema:
                allOf:
                  - $ref: ../schemas/message.yaml#/Message
                  - type: object
                    properties:
                      response:
                        type: object
                        properties:
                          status:
                            type: string
                            example: success
                          message:
                            type: string
                            example: Menu sent successfully
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Missing required fields or invalid menu type
        '401':
          description: Não autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid token
        '429':
          description: Limite de requisições excedido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Rate limit exceeded
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to send menu
  /send/carousel:
    post:
      operationId: sendCarousel
      tags:
        - Enviar Mensagem
      summary: Enviar carrossel de mídia com botões
      description: >
        Este endpoint permite enviar um carrossel com imagens e botões interativos.

        Funciona de maneira igual ao endpoint `/send/menu` com type: carousel, porém usando outro formato de payload.


        ## Campos Comuns


        Este endpoint suporta todos os **campos opcionais comuns** documentados na tag **"Enviar Mensagem"**, incluindo:

        `delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `forward`, `track_source`, `track_id`, placeholders
        e envio para grupos.


        ## Estrutura do Payload


        ```json

        {
          "number": "5511999999999",
          "text": "Texto principal",
          "carousel": [
            {
              "text": "Texto do cartão",
              "image": "URL da imagem",
              "buttons": [
                {
                  "id": "resposta1",
                  "text": "Texto do botão",
                  "type": "REPLY"
                }
              ]
            }
          ],
          "delay": 1000,
          "readchat": true
        }

        ```


        ## Tipos de Botões


        - `REPLY`: Botão de resposta rápida
          - Quando clicado, envia o valor do id como resposta ao chat
          - O id será o texto enviado como resposta

        - `URL`: Botão com link
          - Quando clicado, abre a URL especificada
          - O id deve conter a URL completa (ex: https://exemplo.com)

        - `COPY`: Botão para copiar texto
          - Quando clicado, copia o texto para a área de transferência
          - O id será o texto que será copiado

        - `CALL`: Botão para realizar chamada
          - Quando clicado, inicia uma chamada telefônica
          - O id deve conter o número de telefone

        ## Exemplo de Botões

        ```json

        {
          "buttons": [
            {
              "id": "Sim, quero comprar!",
              "text": "Confirmar Compra",
              "type": "REPLY"
            },
            {
              "id": "https://exemplo.com/produto",
              "text": "Ver Produto",
              "type": "URL"
            },
            {
              "id": "CUPOM20",
              "text": "Copiar Cupom",
              "type": "COPY"
            },
            {
              "id": "5511999999999",
              "text": "Falar com Vendedor",
              "type": "CALL"
            }
          ]
        }

        ```


        ## Exemplo Completo de Carrossel

        ```json

        {
          "number": "5511999999999",
          "text": "Nossos Produtos em Destaque",
          "carousel": [
            {
              "text": "Smartphone XYZ\nO mais avançado smartphone da linha",
              "image": "https://exemplo.com/produto1.jpg",
              "buttons": [
                {
                  "id": "SIM_COMPRAR_XYZ",
                  "text": "Comprar Agora",
                  "type": "REPLY"
                },
                {
                  "id": "https://exemplo.com/xyz",
                  "text": "Ver Detalhes",
                  "type": "URL"
                }
              ]
            },
            {
              "text": "Cupom de Desconto\nGanhe 20% OFF em qualquer produto",
              "image": "https://exemplo.com/cupom.jpg",
              "buttons": [
                {
                  "id": "DESCONTO20",
                  "text": "Copiar Cupom",
                  "type": "COPY"
                },
                {
                  "id": "5511999999999",
                  "text": "Falar com Vendedor",
                  "type": "CALL"
                }
              ]
            }
          ],
          "delay": 0,
          "readchat": true
        }

        ```
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: >-
                    ID do chat para o qual a mensagem será enviada. Pode ser um número de telefone em formato
                    internacional, um ID de grupo (`@g.us`), um ID de usuário (com `@s.whatsapp.net` ou `@lid`).
                  example: '5511999999999'
                text:
                  type: string
                  description: Texto principal da mensagem
                  example: Nossos Produtos em Destaque
                carousel:
                  type: array
                  description: Array de cartões do carrossel
                  items:
                    type: object
                    properties:
                      text:
                        type: string
                        description: Texto do cartão
                        example: |-
                          Smartphone XYZ
                          O mais avançado smartphone da linha
                      image:
                        type: string
                        description: URL da imagem (opcional)
                        example: https://exemplo.com/produto1.jpg
                      video:
                        type: string
                        description: URL do vídeo (alternativa à imagem)
                        example: https://exemplo.com/produto1.mp4
                      document:
                        type: string
                        description: URL do documento (alternativa à imagem)
                        example: https://exemplo.com/catalogo.pdf
                      filename:
                        type: string
                        description: Nome do arquivo para documentos
                        example: Catalogo.pdf
                      buttons:
                        type: array
                        description: Array de botões do cartão
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                              description: ID do botão
                              example: buy_xyz
                            text:
                              type: string
                              description: Texto exibido no botão
                              example: Comprar Agora
                            type:
                              type: string
                              description: |
                                Tipo do botão:
                                * REPLY - O id será enviado como resposta ao chat
                                * URL - O id deve ser a URL completa que será aberta
                                * COPY - O id será o texto copiado para área de transferência
                                * CALL - O id deve ser o número de telefone para a chamada
                              enum:
                                - REPLY
                                - URL
                                - CALL
                                - COPY
                              example: REPLY
                    required:
                      - text
                      - buttons
                delay:
                  type: integer
                  description: Atraso em milissegundos antes do envio
                  example: 1000
                readchat:
                  type: boolean
                  description: Marca conversa como lida após envio
                  example: true
                readmessages:
                  type: boolean
                  description: Marca últimas mensagens recebidas como lidas
                  example: true
                replyid:
                  type: string
                  description: ID da mensagem para responder
                  example: 3EB0538DA65A59F6D8A251
                mentions:
                  type: string
                  description: Números para mencionar (separados por vírgula)
                  example: 5511999999999,5511888888888
                forward:
                  type: boolean
                  description: Marca a mensagem como encaminhada no WhatsApp
                  example: false
                async:
                  type: boolean
                  description: Se true, envia a mensagem de forma assíncrona via fila interna
                  example: false
                track_source:
                  type: string
                  description: Origem do rastreamento da mensagem
                  example: chatwoot
                track_id:
                  type: string
                  description: ID para rastreamento da mensagem (aceita valores duplicados)
                  example: msg_123456789
              required:
                - number
                - text
                - carousel
      responses:
        '200':
          description: Carrossel enviado com sucesso
          content:
            application/json:
              schema:
                allOf:
                  - $ref: ../schemas/message.yaml#/Message
                  - type: object
                    properties:
                      response:
                        type: object
                        properties:
                          status:
                            type: string
                            example: success
                          message:
                            type: string
                            example: Carousel sent successfully
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Missing required fields or invalid card format
        '401':
          description: Não autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid token
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to send carousel
  /send/location-button:
    post:
      operationId: sendLocationButton
      tags:
        - Enviar Mensagem
      summary: Solicitar localização do usuário
      description: >
        Este endpoint envia uma mensagem com um botão que solicita a localização do usuário.

        Quando o usuário clica no botão, o WhatsApp abre a interface para compartilhar a localização atual.


        ## Campos Comuns


        Este endpoint suporta todos os **campos opcionais comuns** documentados na tag **"Enviar Mensagem"**, incluindo:

        `delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `forward`, `track_source`, `track_id`, placeholders
        e envio para grupos.


        ## Estrutura do Payload


        ```json

        {
          "number": "5511999999999",
          "text": "Por favor, compartilhe sua localização",
          "delay": 0,
          "readchat": true
        }

        ```


        ## Exemplo de Uso


        ```json

        {
          "number": "5511999999999",
          "text": "Para continuar o atendimento, clique no botão abaixo e compartilhe sua localização"
        }

        ```


        > **Nota**: O botão de localização é adicionado automaticamente à mensagem
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: >-
                    ID do chat para o qual a mensagem será enviada. Pode ser um número de telefone em formato
                    internacional, um ID de grupo (`@g.us`), um ID de usuário (com `@s.whatsapp.net` ou `@lid`).
                  example: '5511999999999'
                text:
                  type: string
                  description: Texto da mensagem que será exibida
                  example: Por favor, compartilhe sua localização
                delay:
                  type: integer
                  description: Atraso em milissegundos antes do envio
                  example: 0
                readchat:
                  type: boolean
                  description: Se deve marcar a conversa como lida após envio
                  example: true
                readmessages:
                  type: boolean
                  description: Marca últimas mensagens recebidas como lidas
                  example: true
                replyid:
                  type: string
                  description: ID da mensagem para responder
                  example: 3EB0538DA65A59F6D8A251
                mentions:
                  type: string
                  description: Números para mencionar (separados por vírgula)
                  example: 5511999999999,5511888888888
                async:
                  type: boolean
                  description: Se true, envia a mensagem de forma assíncrona via fila interna
                  example: false
                track_source:
                  type: string
                  description: Origem do rastreamento da mensagem
                  example: chatwoot
                track_id:
                  type: string
                  description: ID para rastreamento da mensagem (aceita valores duplicados)
                  example: msg_123456789
              required:
                - number
                - text
      responses:
        '200':
          description: Localização enviada com sucesso
          content:
            application/json:
              schema:
                allOf:
                  - $ref: ../schemas/message.yaml#/Message
                  - type: object
                    properties:
                      response:
                        type: object
                        properties:
                          status:
                            type: string
                            example: success
                          message:
                            type: string
                            example: Location sent successfully
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Missing required fields or invalid coordinates
        '401':
          description: Não autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid token
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to send location
  /send/request-payment:
    post:
      operationId: sendRequestPayment
      tags:
        - Enviar Mensagem
      summary: Solicitar pagamento
      description: |
        Envia uma solicitação de pagamento com o botão nativo **"Revisar e pagar"** do WhatsApp.
        O fluxo suporta PIX (estático, dinâmico ou desabilitado), boleto, link de pagamento e cartão,
        combinando tudo em uma única mensagem interativa.

        ## Como funciona
        - Define o valor em `amount` (BRL por padrão) e opcionalmente personaliza título, texto e nota adicional.
        - Por padrão exige `pixKey`.
        - O arquivo apontado por `fileUrl` é anexado como documento (boleto ou fatura em PDF, por exemplo).
        - `paymentLink` habilita o botão externo.



        ## Campos comuns
        Este endpoint também suporta os campos padrão: `delay`, `readchat`, `readmessages`, `replyid`,
        `mentions`, `track_source`, `track_id` e `async`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: >-
                    ID do chat para o qual a mensagem será enviada. Pode ser um número de telefone em formato
                    internacional, um ID de grupo (`@g.us`), um ID de usuário (com `@s.whatsapp.net` ou `@lid`).
                  example: '5511999999999'
                title:
                  type: string
                  description: Título que aparece no cabeçalho do fluxo
                  example: Detalhes do pedido
                text:
                  type: string
                  description: Mensagem exibida no corpo do fluxo
                  example: 'Pedido #123 pronto para pagamento'
                footer:
                  type: string
                  description: Texto do rodapé da mensagem
                  example: Loja Exemplo
                itemName:
                  type: string
                  description: Nome do item principal listado no fluxo
                  example: Assinatura Plano Ouro
                invoiceNumber:
                  type: string
                  description: Identificador ou número da fatura
                  example: PED-123
                amount:
                  type: number
                  format: float
                  description: Valor da cobrança (em BRL por padrão)
                  example: 199.9
                pixKey:
                  type: string
                  description: Chave PIX estático (CPF/CNPJ/telefone/email/EVP)
                  example: 123e4567-e89b-12d3-a456-426614174000
                pixType:
                  type: string
                  description: Tipo da chave PIX (`CPF`, `CNPJ`, `PHONE`, `EMAIL`, `EVP`). Padrão `EVP`
                  example: EVP
                pixName:
                  type: string
                  description: Nome do recebedor exibido no fluxo (padrão usa o nome do perfil da instância)
                  example: Loja Exemplo
                paymentLink:
                  type: string
                  description: URL externa para checkout (somente dominios homologados; veja lista acima)
                  example: https://pagamentos.exemplo.com/checkout/abc
                fileUrl:
                  type: string
                  description: 'URL ou caminho (base64) do documento a ser anexado (ex.: boleto PDF)'
                  example: https://cdn.exemplo.com/boleto-123.pdf
                fileName:
                  type: string
                  description: Nome do arquivo exibido no WhatsApp ao anexar `fileUrl`
                  example: boleto-123.pdf
                boletoCode:
                  type: string
                  description: Linha digitável do boleto (habilita o método boleto automaticamente)
                  example: 34191.79001 01043.510047 91020.150008 5 91070026000
                replyid:
                  type: string
                  description: ID da mensagem que será respondida
                mentions:
                  type: string
                  description: Números mencionados separados por vírgula
                delay:
                  type: integer
                  description: Atraso em milissegundos antes do envio (exibe "digitando..." no WhatsApp)
                readchat:
                  type: boolean
                  description: Marca o chat como lido após enviar a mensagem
                readmessages:
                  type: boolean
                  description: Marca mensagens recentes como lidas após o envio
                async:
                  type: boolean
                  description: Enfileira o envio para processamento assíncrono
                track_source:
                  type: string
                  description: 'Origem de rastreamento (ex.: chatwoot, crm-interno)'
                track_id:
                  type: string
                  description: Identificador de rastreamento (aceita valores duplicados)
              required:
                - number
                - amount
            examples:
              pixSimples:
                summary: PIX simples
                value:
                  number: '5511999999999'
                  amount: 199.9
                  text: 'Pedido #123 pronto para pagamento'
                  pixKey: 123e4567-e89b-12d3-a456-426614174000
                  pixType: EVP
              pixEBoleto:
                summary: PIX + boleto
                value:
                  number: '5511999999999'
                  amount: 349.5
                  text: 'Pedido #457 com boleto'
                  pixKey: '12345678000190'
                  pixType: CNPJ
                  pixName: Loja Exemplo LTDA
                  boletoCode: 34191.79001 01043.510047 91020.150008 5 91070026000
                  additionalNote: Pague via PIX ou utilize o boleto em anexo
              completo:
                summary: PIX + boleto + link
                value:
                  number: '5511888888888'
                  title: Assinatura Premium
                  text: Plano anual disponível para pagamento
                  footer: footer
                  invoiceNumber: INV-789
                  itemName: Bolo XYZ
                  amount: 599
                  pixKey: 123e4567-e89b-12d3-a456-426614174000
                  pixType: EVP
                  pixName: Empresa Exemplo
                  boletoCode: 23793.38128 60000.000123 45670.000012 3 45670000012345
                  fileUrl: https://cdn.exemplo.com/boleto-inv-789.pdf
                  fileName: Clique para abrir o PDF.pdf
                  paymentLink: https://payment-link.pagar.me/checkout/inv-789
      responses:
        '200':
          description: Solicitação de pagamento enviada com sucesso
          content:
            application/json:
              schema:
                allOf:
                  - $ref: ../schemas/message.yaml#/Message
                  - type: object
                    properties:
                      response:
                        type: object
                        properties:
                          status:
                            type: string
                            example: success
                          message:
                            type: string
                            example: Payment request sent successfully
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Missing pixKey or pixCode
        '401':
          description: Não autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid token
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to send payment request
  /send/pix-button:
    post:
      operationId: sendPixButton
      tags:
        - Enviar Mensagem
      summary: Enviar botão PIX
      description: |
        Envia um botão nativo do WhatsApp que abre para pagamento PIX com a chave informada.
        O usuário visualiza o detalhe do recebedor, nome e chave.

        ## Regras principais
        - `pixType` aceita: `CPF`, `CNPJ`, `PHONE`, `EMAIL`, `EVP` (case insensitive)
        - `pixName` padrão: `"Pix"` quando não informado - nome de quem recebe o pagamento


        ## Campos comuns
        Este endpoint herda os campos opcionais padronizados da tag **"Enviar Mensagem"**:
        `delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `track_source`, `track_id` e `async`.

        ## Exemplo de payload
        ```json
        {
          "number": "5511999999999",
          "pixType": "EVP",
          "pixKey": "123e4567-e89b-12d3-a456-426614174000",
          "pixName": "Loja Exemplo"
        }
        ```
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: >-
                    ID do chat para o qual a mensagem será enviada. Pode ser um número de telefone em formato
                    internacional, um ID de grupo (`@g.us`), um ID de usuário (com `@s.whatsapp.net` ou `@lid`).
                  example: '5511999999999'
                pixType:
                  type: string
                  description: 'Tipo da chave PIX. Valores aceitos: CPF, CNPJ, PHONE, EMAIL ou EVP'
                  example: EVP
                pixKey:
                  type: string
                  description: Valor da chave PIX (CPF/CNPJ/telefone/email/EVP)
                  example: 123e4567-e89b-12d3-a456-426614174000
                pixName:
                  type: string
                  description: Nome exibido como recebedor do PIX (padrão "Pix" se vazio)
                  example: Loja Exemplo
                async:
                  type: boolean
                  description: Enfileira o envio para processamento assíncrono
                delay:
                  type: integer
                  description: Atraso em milissegundos antes do envio (exibe "digitando..." no WhatsApp)
                readchat:
                  type: boolean
                  description: Marca o chat como lido após enviar a mensagem
                readmessages:
                  type: boolean
                  description: Marca mensagens recentes como lidas após o envio
                replyid:
                  type: string
                  description: ID da mensagem que será respondida
                mentions:
                  type: string
                  description: Lista de números mencionados separados por vírgula
                track_source:
                  type: string
                  description: 'Origem de rastreamento (ex.: chatwoot, crm-interno)'
                track_id:
                  type: string
                  description: Identificador de rastreamento (aceita valores duplicados)
              required:
                - number
                - pixType
                - pixKey
              example:
                number: '5511999999999'
                pixType: EVP
                pixKey: 123e4567-e89b-12d3-a456-426614174000
                pixName: Loja Exemplo
      responses:
        '200':
          description: Botão PIX enviado com sucesso
          content:
            application/json:
              schema:
                allOf:
                  - $ref: ../schemas/message.yaml#/Message
                  - type: object
                    properties:
                      response:
                        type: object
                        properties:
                          status:
                            type: string
                            example: success
                          message:
                            type: string
                            example: PIX button sent successfully
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: 'Invalid keyType. Allowed: CPF, CNPJ, PHONE, EMAIL, EVP'
        '401':
          description: Não autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid token
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to send PIX button
  /message/async:
    get:
      operationId: getAsyncQueueStatus
      tags:
        - Mensagem Async
      summary: Consultar fila async de envio direto
      description: |
        Retorna um resumo simples da fila de envio `async=true` da instância atual autenticada.

        Este endpoint cobre apenas a fila interna de envio direto assíncrono. Ele **não** representa:
        - campanhas do sender (`/sender/*`)
        - filas de envio em massa

        A resposta padrão foi pensada para clientes:
        - `status`: visão resumida da fila (`idle`, `queued`, `processing`, `waiting_connection`, `resetting`)
        - `pending`: quantidade total estimada de mensagens pendentes
        - `processingNow`: indica se o worker está ocupando um job neste momento
        - `acceptingNewMessages`: indica se a fila aceita novos envios async
        - `sessionReady`: indica se a sessão WhatsApp está pronta para envio
        - `resetting`: indica se a fila está pausada por reset/clear
      responses:
        '200':
          description: Resumo da fila async
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Async queue status
                  instanceId:
                    type: string
                    description: ID da instância
                  queue:
                    type: object
                    properties:
                      status:
                        type: string
                        description: Estado resumido da fila
                        example: waiting_connection
                      pending:
                        type: integer
                        format: int64
                        description: Quantidade total estimada de mensagens pendentes
                        example: 3
                      processingNow:
                        type: boolean
                        description: Indica se há um job ativo no worker agora
                        example: true
                      acceptingNewMessages:
                        type: boolean
                        description: Indica se a fila aceita novos envios async
                        example: true
                      sessionReady:
                        type: boolean
                        description: Indica se a sessão WhatsApp está pronta para envio
                        example: false
                      resetting:
                        type: boolean
                        description: Indica se a fila async está pausada por reset/clear
                        example: false
        '401':
          description: Token inválido ou ausente
        '500':
          description: Erro interno ao consultar a fila async
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  instanceId:
                    type: string
    delete:
      operationId: clearAsyncQueue
      tags:
        - Mensagem Async
      summary: Limpar fila async de envio direto
      description: >
        Cancela toda a fila de envio `async=true` da instância e marca as mensagens pendentes como `Canceled`.


        Este endpoint atua apenas na fila interna de envio direto assíncrono. Ele **não** afeta:

        - campanhas do sender (`/sender/*`)

        - mensagens já enviadas com sucesso

        - mensagens em massa agendadas


        O fluxo executado é:

        1. pausa o worker interno da fila async

        2. drena jobs pendentes em memória e overflow

        3. marca backlog persistido em `Queued` como `Canceled`

        4. libera a fila para novos envios async


        Use este endpoint quando houver backlog preso, fila acumulada ou quando você quiser abortar todos os envios
        assíncronos ainda não concluídos.
      responses:
        '200':
          description: Fila async limpa com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Async queue cleared
                  instanceId:
                    type: string
                    description: ID da instância
                  stats:
                    type: object
                    properties:
                      trackedJobsCleared:
                        type: integer
                        description: Quantidade de IDs rastreados removidos da fila em memória
                        example: 3
                      bufferedJobsMarkedCanceled:
                        type: integer
                        description: Jobs em memória marcados como `Canceled`
                        example: 2
                      drainedChannelJobs:
                        type: integer
                        description: Jobs removidos do canal principal da fila
                        example: 1
                      clearedOverflowJobs:
                        type: integer
                        description: Jobs removidos do backlog de overflow
                        example: 1
                      persistedQueuedCanceled:
                        type: integer
                        format: int64
                        description: Mensagens persistidas em `Queued` que foram atualizadas para `Canceled`
                        example: 5
        '401':
          description: Token inválido ou ausente
        '409':
          description: >-
            A fila não pôde ser limpa porque a instância está em reset ou havia envio em progresso que não drenou a
            tempo
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: async queue did not drain before reset
                  instanceId:
                    type: string
                  stats:
                    type: object
                    additionalProperties: true
        '500':
          description: Erro interno ao limpar a fila async
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  instanceId:
                    type: string
                  stats:
                    type: object
                    additionalProperties: true
  /message/download:
    post:
      operationId: downloadMessage
      tags:
        - Ações na mensagem e Buscar
      summary: Baixar arquivo de uma mensagem
      description: >
        Baixa o arquivo associado a uma mensagem de mídia (imagem, vídeo, áudio, documento ou sticker).


        ## Parâmetros


        - **id** (string, obrigatório): ID da mensagem

        - **return_base64** (boolean, default: false): Retorna arquivo em base64

        - **generate_mp3** (boolean, default: true): Para áudios, define formato de retorno
          - `true`: Retorna MP3
          - `false`: Retorna OGG
        - **return_link** (boolean, default: true): Retorna URL pública do arquivo

        - **transcribe** (boolean, default: false): Transcreve áudios para texto

        - **openai_apikey** (string, opcional): Chave OpenAI para transcrição
          - Se não informada, usa a chave salva na instância
          - Se informada, atualiza e salva na instância para próximas chamadas
        - **download_quoted** (boolean, default: false): Baixa mídia da mensagem citada
          - Útil para baixar conteúdo original de status do WhatsApp
          - Quando uma mensagem é resposta a um status, permite baixar a mídia do status original
          - **Contextualização**: Ao baixar a mídia citada, você identifica o contexto da conversa
            - Exemplo: Se alguém responde a uma promoção, baixando a mídia você saberá que a pergunta é sobre aquela promoção específica

        ## Exemplos


        ### Baixar áudio como MP3:

        ```json

        {
          "id": "7EB0F01D7244B421048F0706368376E0",
          "generate_mp3": true
        }

        ```


        ### Transcrever áudio:

        ```json

        {
          "id": "7EB0F01D7244B421048F0706368376E0",
          "transcribe": true
        }

        ```


        ### Apenas base64 (sem salvar):

        ```json

        {
          "id": "7EB0F01D7244B421048F0706368376E0",
          "return_base64": true,
          "return_link": false
        }

        ```


        ### Baixar mídia de status (mensagem citada):

        ```json

        {
          "id": "7EB0F01D7244B421048F0706368376E0",
          "download_quoted": true
        }

        ```

        *Útil quando o cliente responde a uma promoção/status - você baixa a mídia original para entender sobre qual
        produto/oferta ele está perguntando.*


        ## Resposta


        ```json

        {
          "fileURL": "https://api.exemplo.com/files/arquivo.mp3",
          "mimetype": "audio/mpeg",
          "base64Data": "UklGRkj...",
          "transcription": "Texto transcrito"
        }

        ```


        **Nota**: 

        - Por padrão, se não definido o contrário:
          1. áudios são retornados como MP3. 
          2. E todos os pedidos de download são retornados com URL pública.
        - Transcrição requer chave OpenAI válida. A chave pode ser configurada uma vez na instância e será reutilizada
        automaticamente.

        - Retenção de mídia: mantemos as mídias no nosso storage por 2 dias. Após 2 dias, elas são removidas na limpeza
        automática e o link retornado deixa de ficar disponível. Para voltar a disponibilizar a mídia, é necessário
        refazer o download pelo endpoint. Se o cliente solicitar novamente, a mídia será baixada do CDN da Meta, o que
        pode aumentar o tempo de resposta. Enquanto estiver no nosso storage, a resposta tende a ser mais rápida.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: ID da mensagem contendo o arquivo
                  example: 7EB0F01D7244B421048F0706368376E0
                return_base64:
                  type: boolean
                  description: Se verdadeiro, retorna o conteúdo em base64
                  default: false
                generate_mp3:
                  type: boolean
                  description: Para áudios, define formato de retorno (true=MP3, false=OGG)
                  default: true
                return_link:
                  type: boolean
                  description: Salva e retorna URL pública do arquivo
                  default: true
                transcribe:
                  type: boolean
                  description: Se verdadeiro, transcreve áudios para texto
                  default: false
                openai_apikey:
                  type: string
                  description: Chave da API OpenAI para transcrição (opcional)
                  example: sk-...
                download_quoted:
                  type: boolean
                  description: Se verdadeiro, baixa mídia da mensagem citada ao invés da mensagem principal
                  default: false
              required:
                - id
      responses:
        '200':
          description: Successful file download
          content:
            application/json:
              schema:
                type: object
                properties:
                  fileURL:
                    type: string
                    description: URL pública para acessar o arquivo (se return_link=true)
                    example: https://api.exemplo.com/files/arquivo.mp3
                  mimetype:
                    type: string
                    description: Tipo MIME do arquivo
                    example: audio/mpeg
                  base64Data:
                    type: string
                    description: Conteúdo do arquivo em base64 (se return_base64=true)
                    example: UklGRkj...
                  transcription:
                    type: string
                    description: Texto transcrito do áudio (se transcribe=true)
                    example: Texto transcrito
                required:
                  - mimetype
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unsupported media type or no media found in message
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid token
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    examples:
                      - Message not found
                      - No quoted message found in this message
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to download media
  /message/find:
    post:
      operationId: findMessages
      tags:
        - Ações na mensagem e Buscar
      summary: Buscar mensagens em um chat
      description: |
        Busca mensagens com múltiplos filtros disponíveis. Este endpoint permite:

        1. **Busca por ID específico**: Use `id` para encontrar uma mensagem exata
        2. **Filtrar por chat**: Use `chatid` para mensagens de uma conversa específica
        3. **Filtrar por rastreamento**: Use `track_source` e `track_id` para mensagens com dados de tracking
        4. **Limitar resultados**: Use `limit` para controlar quantas mensagens retornar
        5. **Ordenação**: Resultados ordenados por data (mais recentes primeiro)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: ID específico da mensagem para busca exata
                  example: user123:r3EB0538
                chatid:
                  type: string
                  description: ID do chat no formato internacional
                  example: 5511999999999@s.whatsapp.net
                track_source:
                  type: string
                  description: Origem do rastreamento para filtrar mensagens
                  example: chatwoot
                track_id:
                  type: string
                  description: ID de rastreamento para filtrar mensagens
                  example: msg_123456789
                limit:
                  type: integer
                  description: Numero maximo de mensagens a retornar (padrao 100)
                  minimum: 1
                  default: 100
                  example: 20
                offset:
                  type: integer
                  description: Deslocamento para paginacao (0 retorna as mensagens mais recentes)
                  default: 0
            examples:
              chatSearch:
                summary: Buscar por chat especifico
                description: Busca mensagens de uma conversa especifica
                value:
                  chatid: 5511999999999@s.whatsapp.net
                  limit: 20
                  offset: 0
              idSearch:
                summary: Buscar por ID especifico
                description: Busca uma mensagem especifica pelo seu ID
                value:
                  id: user123:r3EB0538
              trackingSearch:
                summary: Buscar por rastreamento
                description: Busca mensagens usando dados de tracking com paginacao
                value:
                  track_source: chatwoot
                  track_id: conv_123456
                  limit: 50
                  offset: 100
      responses:
        '200':
          description: Lista de mensagens encontradas com metadados de paginacao
          content:
            application/json:
              schema:
                type: object
                properties:
                  returnedMessages:
                    type: integer
                    description: Quantidade de mensagens retornadas nesta pagina
                  messages:
                    type: array
                    items:
                      $ref: ../schemas/message.yaml#/Message
                  limit:
                    type: integer
                    description: Limite aplicado na busca
                  offset:
                    type: integer
                    description: Offset usado para recuperar os resultados
                  nextOffset:
                    type: integer
                    description: Offset sugerido para a proxima pagina
                  hasMore:
                    type: boolean
                    description: Indica se existem mais mensagens apos esta pagina
        '400':
          description: Parametros invalidos
        '401':
          description: Token invalido ou expirado
        '404':
          description: Chat nao encontrado
        '500':
          description: Erro interno do servidor
  /message/history-sync:
    post:
      operationId: requestHistorySync
      tags:
        - Ações na mensagem e Buscar
      summary: Solicitar histórico sob demanda de um chat
      description: >
        Solicita ao WhatsApp um sync sob demanda de mensagens antigas de um chat.


        Regras:

        - envie `number`

        - `count` é opcional e limitado a 100

        - `messageid` é opcional; quando informado, a API usa essa mensagem como referência para buscar mensagens mais
        antigas do chat


        Observação:

        - **Importante:** a recuperação pode só acontecer depois de abrir o WhatsApp no celular ou deixá-lo ativo em
        segundo plano

        - `messageid` define a mensagem de referência para carregar histórico anterior

        - esse campo não serve para buscar essa mensagem específica

        - o histórico é buscado para trás a partir da mensagem de referência informada

        - se você quiser recuperar apenas uma mensagem específica `X`, informe como `messageid` a mensagem logo depois
        de `X` e use `count=1`

        - se `messageid` não for informado, a API usa a mensagem mais antiga conhecida localmente desse chat como
        referência para buscar histórico anterior

        - as mensagens retornam depois via webhook/SSE em eventos do tipo `history` e também ficam disponíveis em
        `/message/find`
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                messageid:
                  type: string
                  description: ID da mensagem de referência usada para buscar mensagens mais antigas do chat
                  example: 3EB01234567890ABCDEF
                number:
                  type: string
                  description: JID completo do chat
                  example: 5511999999999@s.whatsapp.net
                count:
                  type: integer
                  minimum: 1
                  maximum: 100
                  description: Quantidade desejada de mensagens no sync
                  example: 20
            examples:
              usando_ancora_explicita:
                summary: Buscar histórico anterior a uma mensagem de referência
                value:
                  number: 5511999999999@s.whatsapp.net
                  messageid: 3EB01234567890ABCDEF
                  count: 20
              recuperar_mensagem_especifica:
                summary: Recuperar apenas a mensagem imediatamente anterior à referência
                value:
                  number: 5511999999999@s.whatsapp.net
                  messageid: 3EB0MENSAGEM_LOGO_APOS_X
                  count: 1
              usando_ancora_local:
                summary: Reutilizar âncora local já persistida
                value:
                  number: 5511999999999@s.whatsapp.net
                  count: 50
      responses:
        '200':
          description: Solicitação de history sync enviada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: History sync request sent. Messages will be received as history sync events.
                  details:
                    type: object
                    additionalProperties: true
                    description: Metadados adicionais da operação
              examples:
                async_padrão:
                  summary: Solicitação enviada
                  value:
                    success: true
                    message: History sync request sent. Messages will be received as history sync events.
        '400':
          description: Payload inválido ou âncora insuficiente
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: number is required
        '500':
          description: Erro interno ao solicitar o history sync
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: 'Failed to request history: connection closed'
  /message/markread:
    post:
      operationId: markMessageRead
      tags:
        - Ações na mensagem e Buscar
      summary: Marcar mensagens como lidas
      description: |
        Marca uma ou mais mensagens como lidas. Este endpoint permite:
        1. Marcar múltiplas mensagens como lidas de uma vez
        2. Atualizar o status de leitura no WhatsApp
        3. Sincronizar o status de leitura entre dispositivos

        Exemplo de requisição básica:
        ```json
        {
          "id": [
            "62AD1AD844E518180227BF68DA7ED710",
            "ECB9DE48EB41F77BFA8491BFA8D6EF9B"  
          ]
        }
        ```

        Exemplo de resposta:
        ```json
        {
          "success": true,
          "message": "Messages marked as read",
          "markedMessages": [
            {
              "id": "62AD1AD844E518180227BF68DA7ED710",
              "timestamp": 1672531200000
            },
            {
              "id": "ECB9DE48EB41F77BFA8491BFA8D6EF9B",
              "timestamp": 1672531300000
            }
          ]
        }
        ```

        Parâmetros disponíveis:
        - id: Lista de IDs das mensagens a serem marcadas como lidas

        Erros comuns:
        - 401: Token inválido ou expirado
        - 400: Lista de IDs vazia ou inválida
        - 404: Uma ou mais mensagens não encontradas
        - 500: Erro ao marcar mensagens como lidas
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: array
                  description: Lista de IDs das mensagens a serem marcadas como lidas
                  items:
                    type: string
                  example:
                    - 62AD1AD844E518180227BF68DA7ED710
                    - ECB9DE48EB41F77BFA8491BFA8D6EF9B
              required:
                - id
      responses:
        '200':
          description: Messages successfully marked as read
          content:
            application/json:
              schema:
                type: object
                properties:
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        message_id:
                          type: string
                          description: ID of the message that was processed
                        status:
                          type: string
                          enum:
                            - success
                            - error
                          description: Status of the mark as read operation
                        error:
                          type: string
                          description: Error message if status is error
                    example:
                      - message_id: 62AD1AD844E518180227BF68DA7ED710
                        status: success
                      - message_id: ECB9DE48EB41F77BFA8491BFA8D6EF9B
                        status: error
                        error: Message not found
        '400':
          description: Invalid request payload or missing required fields
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Missing Id in Payload
        '401':
          description: Unauthorized - invalid or missing token
        '500':
          description: Server error while processing the request
  /message/react:
    post:
      operationId: reactToMessage
      tags:
        - Ações na mensagem e Buscar
      summary: Enviar reação a uma mensagem
      description: |
        Envia uma reação (emoji) a uma mensagem específica. Este endpoint permite:

        1. Adicionar ou remover reações em mensagens

        2. Usar qualquer emoji Unicode válido

        3. Reagir a mensagens em chats individuais ou grupos

        4. Remover reações existentes

        5. Verificar o status da reação enviada


        Tipos de reações suportados:

        - Qualquer emoji Unicode válido (👍, ❤️, 😂, etc)

        - String vazia para remover reação


        Exemplo de requisição básica:

        ```json

        {
          "number": "5511999999999@s.whatsapp.net",
          "text": "👍",
          "id": "3EB0538DA65A59F6D8A251"
        }

        ```


        Exemplo de requisição para remover reação:

        ```json

        {
          "number": "5511999999999@s.whatsapp.net",
          "text": "",
          "id": "3EB0538DA65A59F6D8A251"
        }

        ```


        Exemplo de resposta:

        ```json

        {
          "success": true,
          "message": "Reaction sent",
          "reaction": {
            "id": "3EB0538DA65A59F6D8A251",
            "emoji": "👍",
            "timestamp": 1672531200000,
            "status": "sent"
          }
        }

        ```


        Exemplo de resposta ao remover reação:

        ```json

        {
          "success": true,
          "message": "Reaction removed",
          "reaction": {
            "id": "3EB0538DA65A59F6D8A251",
            "emoji": null,
            "timestamp": 1672531200000,
            "status": "removed"
          }
        }

        ```


        Parâmetros disponíveis:

        - number: Número do chat no formato internacional (ex:
        5511999999999@s.whatsapp.net)

        - text: Emoji Unicode da reação (ou string vazia para remover reação)

        - id: ID da mensagem que receberá a reação


        Erros comuns:

        - 401: Token inválido ou expirado

        - 400: Número inválido ou emoji não suportado

        - 404: Mensagem não encontrada

        - 500: Erro ao enviar reação


        Limitações:

        - Só é possível reagir a mensagens enviadas por outros usuários

        - Não é possível reagir a mensagens antigas (mais de 7 dias)

        - O mesmo usuário só pode ter uma reação ativa por mensagem
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: Número do chat no formato internacional
                  example: 5511999999999@s.whatsapp.net
                text:
                  type: string
                  description: Emoji Unicode da reação (ou string vazia para remover reação)
                  example: 👍
                id:
                  type: string
                  description: ID da mensagem que receberá a reação
                  example: 3EB0538DA65A59F6D8A251
              required:
                - number
                - text
                - id
      responses:
        '200':
          description: Reação enviada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: ID único da mensagem de reação
                    example: owner:generated_message_id
                  messageid:
                    type: string
                    description: ID gerado para a mensagem de reação
                    example: generated_message_id
                  content:
                    type: object
                    description: Detalhes da reação
                  messageTimestamp:
                    type: number
                    description: Timestamp da mensagem em milissegundos
                    example: 1672531200000
                  messageType:
                    type: string
                    description: Tipo da mensagem
                    example: reaction
                  status:
                    type: string
                    description: Status atual da mensagem
                    example: Pending
                  owner:
                    type: string
                    description: Proprietário da instância
                    example: instance_owner
        '400':
          description: Erro nos dados da requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Missing Id in Payload
        '401':
          description: Não autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
        '404':
          description: Mensagem não encontrada
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Message not found
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Error sending message
  /message/delete:
    post:
      operationId: deleteMessage
      tags:
        - Ações na mensagem e Buscar
      summary: Apagar Mensagem Para Todos
      description: |
        Apaga uma mensagem para todos os participantes da conversa.

        ### Funcionalidades:
        - Apaga mensagens em conversas individuais ou grupos
        - Funciona com mensagens enviadas pelo usuário ou recebidas
        - Atualiza o status no banco de dados
        - Envia webhook de atualização

        **Notas Técnicas**:
        1. O ID da mensagem pode ser fornecido em dois formatos:
           - ID completo (contém ":"): usado diretamente
           - ID curto: concatenado com o owner para busca
        2. Gera evento webhook do tipo "messages_update"
        3. Atualiza o status da mensagem para "Deleted"
        4. Para newsletters/canais, use `POST /newsletter/messages/delete`
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: ID da mensagem a ser apagada
              required:
                - id
      responses:
        '200':
          description: Mensagem apagada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  timestamp:
                    type: string
                    format: date-time
                  id:
                    type: string
        '400':
          description: Payload inválido ou ID de chat/sender inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid payload
        '401':
          description: Token não fornecido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unauthorized
        '404':
          description: Mensagem não encontrada
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: message not found
        '500':
          description: Erro interno do servidor ou sessão não iniciada
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
  /message/edit:
    post:
      operationId: editMessage
      tags:
        - Ações na mensagem e Buscar
      summary: Edita uma mensagem enviada
      description: |
        Edita o conteúdo de uma mensagem já enviada usando a funcionalidade nativa do WhatsApp.

        O endpoint realiza:
        - Busca a mensagem original no banco de dados usando o ID fornecido
        - Edita o conteúdo da mensagem para o novo texto no WhatsApp
        - Gera um novo ID para a mensagem editada
        - Retorna objeto de mensagem completo seguindo o padrão da API
        - Dispara eventos SSE/Webhook automaticamente

        **Importante**: 
        - Só é possível editar mensagens enviadas pela própria instância
        - A mensagem deve existir no banco de dados
        - O ID pode ser fornecido no formato completo (owner:messageid) ou apenas messageid
        - A mensagem deve estar dentro do prazo permitido pelo WhatsApp para edição
        - Para newsletters/canais, use `POST /newsletter/messages/edit`
      security:
        - token: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - id
                - text
              properties:
                id:
                  type: string
                  description: ID único da mensagem que será editada (formato owner:messageid ou apenas messageid)
                  example: 3A12345678901234567890123456789012
                text:
                  type: string
                  description: Novo conteúdo de texto da mensagem
                  example: Texto editado da mensagem
      responses:
        '200':
          description: Mensagem editada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: ID único da mensagem no formato owner:messageid
                    example: 5511999999999:3A12345678901234567890123456789012
                  messageid:
                    type: string
                    description: ID da mensagem no WhatsApp
                    example: 3A12345678901234567890123456789012
                  content:
                    type: string
                    description: Conteúdo da mensagem editada
                    example: Texto editado da mensagem
                  messageTimestamp:
                    type: integer
                    description: Timestamp da mensagem (Unix timestamp em milissegundos)
                    example: 1704067200000
                  messageType:
                    type: string
                    description: Tipo da mensagem
                    example: text
                  status:
                    type: string
                    description: Status da mensagem
                    example: Pending
                  owner:
                    type: string
                    description: Proprietário da instância
                    example: '5511999999999'
        '400':
          description: Dados inválidos na requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid payload
        '401':
          description: Sem sessão ativa
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
        '404':
          description: Mensagem não encontrada
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Message not found
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Error fetching message from database
  /message/pin:
    post:
      operationId: pinMessage
      tags:
        - Ações na mensagem e Buscar
      summary: Fixa ou desafixa uma mensagem
      description: |
        Fixa ou desafixa uma mensagem específica usando a funcionalidade nativa do WhatsApp.

        O endpoint realiza:
        - Busca a mensagem original no banco de dados usando o ID fornecido
        - Envia a ação de fixar ou desafixar a mensagem no WhatsApp
        - Funciona em conversas individuais e grupos
        - Gera um novo ID para o evento de pin/unpin
        - Retorna objeto de mensagem completo seguindo o padrão da API
        - Dispara eventos SSE/Webhook automaticamente

        **Importante**:
        - O ID pode ser fornecido no formato completo (`owner:messageid`) ou apenas `messageid`
        - Em conversas `1:1`, a ação é suportada normalmente
        - Em grupos, a permissão depende da configuração do WhatsApp do grupo (`apenas admins` ou `qualquer membro`)
        - O backend não valida localmente se a instância é admin do grupo; a decisão final é do WhatsApp
        - Newsletters/canais não são suportados neste endpoint
        - Se `pin` não for enviado, o valor padrão é `true`
        - Ao fixar mensagem, `duration` aceita dias (`1`, `7` ou `30`)
        - Se `duration` não for enviado ou vier com qualquer outro valor, o backend usa `30` dias
        - Ao desafixar (`pin: false`), `duration` é ignorado
      security:
        - token: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - id
              properties:
                id:
                  type: string
                  description: ID único da mensagem alvo (formato `owner:messageid` ou apenas `messageid`)
                  example: 3A12345678901234567890123456789012
                pin:
                  type: boolean
                  default: true
                  description: Define se a mensagem deve ser fixada (`true`) ou desafixada (`false`)
                  example: true
                duration:
                  type: integer
                  default: 30
                  description: 'Duração do pin em dias. Valores aceitos: `1`, `7` ou `30`. Qualquer outro valor cai para `30`.'
                  example: 7
            examples:
              pinMessage:
                summary: Fixar mensagem
                value:
                  id: 3A12345678901234567890123456789012
                  pin: true
                  duration: 7
              pinMessageFallback30Days:
                summary: Fixar mensagem com fallback para 30 dias
                value:
                  id: 3A12345678901234567890123456789012
                  pin: true
                  duration: 99
              unpinMessage:
                summary: Desafixar mensagem
                value:
                  id: 3A12345678901234567890123456789012
                  pin: false
      responses:
        '200':
          description: Ação de fixar/desafixar mensagem enviada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: ID único da mensagem gerada para o evento de pin/unpin
                    example: 5511999999999:3A12345678901234567890123456789012
                  messageid:
                    type: string
                    description: ID da mensagem do evento no WhatsApp
                    example: 3A12345678901234567890123456789012
                  chatid:
                    type: string
                    description: Chat onde a ação ocorreu
                    example: 120363123456789012@g.us
                  sender:
                    type: string
                    description: JID do remetente da ação
                    example: 5511999999999@s.whatsapp.net
                  senderName:
                    type: string
                    description: Nome do perfil da instância
                    example: Minha Instância
                  isGroup:
                    type: boolean
                    description: Indica se o chat é um grupo
                    example: true
                  fromMe:
                    type: boolean
                    description: Indica se a ação foi enviada pela própria instância
                    example: true
                  content:
                    type: object
                    description: Payload interno de `PinInChatMessage`
                  messageType:
                    type: string
                    description: Tipo da mensagem retornada
                    example: PinInChatMessage
                  source:
                    type: string
                    description: Origem estimada da mensagem
                    example: web
                  messageTimestamp:
                    type: integer
                    description: Timestamp da mensagem em milissegundos
                    example: 1704067200000
                  status:
                    type: string
                    description: Status atual da ação
                    example: Pending
                  text:
                    type: string
                    description: Texto amigável derivado da ação
                    example: Mensagem fixada
                  quoted:
                    type: string
                    description: ID da mensagem citada, quando aplicável
                    example: ''
                  edited:
                    type: string
                    description: ID da mensagem editada, quando aplicável
                    example: ''
                  reaction:
                    type: string
                    description: Emoji de reação, quando aplicável
                    example: ''
                  convertOptions:
                    type: string
                    description: Opções convertidas para mensagens interativas, quando aplicável
                    example: ''
                  owner:
                    type: string
                    description: Proprietário da instância
                    example: '5511999999999'
                  targetMessageID:
                    type: string
                    description: ID da mensagem alvo que foi fixada ou desafixada
                    example: 3EB0538DA65A59F6D8A251
                  pinned:
                    type: boolean
                    description: Estado final solicitado para a mensagem alvo
                    example: true
        '400':
          description: Dados inválidos na requisição ou operação não suportada
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: message pinning is not supported for newsletters
        '401':
          description: Sem sessão ativa ou token inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
        '404':
          description: Mensagem não encontrada
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Message not found
        '500':
          description: Erro interno do servidor ou erro retornado pelo WhatsApp
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: 'error pinning message: ...'
  /group/create:
    post:
      operationId: createGroup
      tags:
        - Grupos e Comunidades
      summary: Criar um novo grupo
      description: |
        Cria um novo grupo no WhatsApp com participantes iniciais.

        ### Detalhes
        - Requer autenticação via token da instância
        - Os números devem ser fornecidos sem formatação (apenas dígitos)

        ### Limitações
        - Mínimo de 1 participante além do criador
          
        ### Comportamento
        - Retorna informações detalhadas do grupo criado
        - Inclui lista de participantes adicionados com sucesso/falha
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Nome do grupo
                  minLength: 1
                  maxLength: 100
                  example: zaptos grupo
                participants:
                  type: array
                  description: Lista de números de telefone dos participantes iniciais
                  items:
                    type: string
                    description: Número de telefone sem formatação
                  minItems: 1
                  maxItems: 50
                  example:
                    - '5521987905995'
                    - '5511912345678'
              required:
                - name
                - participants
            examples:
              default:
                value:
                  name: Meu Novo Grupo
                  participants:
                    - '5521987905995'
              multiple_participants:
                value:
                  name: Equipe de Projeto
                  participants:
                    - '5521987905995'
                    - '5511912345678'
                    - '5519987654321'
      responses:
        '200':
          description: Grupo criado com sucesso
          content:
            application/json:
              schema:
                $ref: ../schemas/group.yaml#/Group
        '400':
          description: Erro de payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Could not parse phone
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to create group
      security:
        - token: []
  /group/info:
    post:
      operationId: getGroupInfo
      tags:
        - Grupos e Comunidades
      summary: Obter informações detalhadas de um grupo
      description: |
        Recupera informações completas de um grupo do WhatsApp, incluindo:
        - Detalhes do grupo
        - Participantes
        - Configurações
        - Link de convite (opcional)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                groupjid:
                  type: string
                  description: Identificador único do grupo (JID)
                  example: 120363153742561022@g.us
                getInviteLink:
                  type: boolean
                  description: Recuperar link de convite do grupo
                  default: false
                  example: true
                getRequestsParticipants:
                  type: boolean
                  description: Recuperar lista de solicitações pendentes de participação
                  default: false
                  example: false
                force:
                  type: boolean
                  description: Forçar atualização, ignorando cache
                  default: false
                  example: false
              required:
                - groupjid
      responses:
        '200':
          description: Informações do grupo obtidas com sucesso
          content:
            application/json:
              schema:
                $ref: ../schemas/group.yaml#/Group
              example:
                JID: 120363153742561022@g.us
                Name: zaptos Community
                Participants:
                  - JID: 5521987654321@s.whatsapp.net
                    IsAdmin: true
                IsLocked: false
                IsAnnounce: false
        '400':
          description: Código de convite inválido ou mal formatado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid invite code
        '404':
          description: Grupo não encontrado ou link de convite expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Group invite link is invalid or has expired
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to retrieve group information
  /group/inviteInfo:
    post:
      operationId: getGroupInviteInfo
      tags:
        - Grupos e Comunidades
      summary: Obter informações de um grupo pelo código de convite
      description: |
        Retorna informações detalhadas de um grupo usando um código de convite ou URL completo do WhatsApp.

        Esta rota permite:
        - Recuperar informações básicas sobre um grupo antes de entrar
        - Validar um link de convite
        - Obter detalhes como nome do grupo, número de participantes e restrições de entrada
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                invitecode:
                  type: string
                  description: |
                    Código de convite ou URL completo do grupo.
                    Pode ser um código curto ou a URL completa do WhatsApp.
                  examples:
                    - IYnl5Zg9bUcJD32rJrDzO7
                    - https://chat.whatsapp.com/IYnl5Zg9bUcJD32rJrDzO7
              required:
                - invitecode
      responses:
        '200':
          description: Informações do grupo obtidas com sucesso
          content:
            application/json:
              schema:
                $ref: ../schemas/group.yaml#/Group
              example:
                JID: 120363153742561022@g.us
                Name: zaptos Community
                Participants:
                  - JID: 5521987654321@s.whatsapp.net
                    IsAdmin: true
                IsLocked: false
                IsAnnounce: false
        '400':
          description: Código de convite inválido ou mal formatado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid invite code
        '404':
          description: Grupo não encontrado ou link de convite expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Group invite link is invalid or has expired
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to retrieve group information
  /group/join:
    post:
      operationId: joinGroup
      tags:
        - Grupos e Comunidades
      summary: Entrar em um grupo usando código de convite
      description: |
        Permite entrar em um grupo do WhatsApp usando um código de convite ou URL completo. 

        Características:
        - Suporta código de convite ou URL completo
        - Valida o código antes de tentar entrar no grupo
        - Retorna informações básicas do grupo após entrada bem-sucedida
        - Trata possíveis erros como convite inválido ou expirado
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - invitecode
              properties:
                invitecode:
                  type: string
                  description: |
                    Código de convite ou URL completo do grupo. 
                    Formatos aceitos:
                    - Código completo: "IYnl5Zg9bUcJD32rJrDzO7"
                    - URL completa: "https://chat.whatsapp.com/IYnl5Zg9bUcJD32rJrDzO7"
                  example: https://chat.whatsapp.com/IYnl5Zg9bUcJD32rJrDzO7
                  minLength: 10
                  maxLength: 50
      responses:
        '200':
          description: Entrada no grupo realizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Group join successful
                  group:
                    $ref: ../schemas/group.yaml#/Group
                  needs_refresh:
                    type: boolean
                    description: Indica se o grupo precisa ser atualizado no cache local
                    example: false
        '400':
          description: Código de convite inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid invite code
        '403':
          description: Usuário já está no grupo ou não tem permissão para entrar
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unable to join group
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Error processing group invite
  /group/leave:
    post:
      operationId: leaveGroup
      tags:
        - Grupos e Comunidades
      summary: Sair de um grupo
      description: |
        Remove o usuário atual de um grupo específico do WhatsApp.

        Requisitos:
        - O usuário deve estar conectado a uma instância válida
        - O usuário deve ser um membro do grupo

        Comportamentos:
        - Se o usuário for o último administrador, o grupo será dissolvido
        - Se o usuário for um membro comum, será removido do grupo
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                groupjid:
                  type: string
                  description: |
                    Identificador único do grupo (JID)
                    - Formato: número@g.us
                    - Exemplo válido: 120363324255083289@g.us
                  example: 120363324255083289@g.us
                  pattern: ^\d+@g\.us$
              required:
                - groupjid
      responses:
        '200':
          description: Saída do grupo realizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Group leave successful
        '400':
          description: Erro de payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid payload
        '500':
          description: Erro interno do servidor ou falha na conexão
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: error leaving group
  /group/list:
    get:
      operationId: listGroups
      tags:
        - Grupos e Comunidades
      summary: Listar todos os grupos
      description: |
        Retorna uma lista com todos os grupos disponíveis para a conta do WhatsApp atualmente conectada.

        Recursos adicionais:
        - Suporta atualização forçada do cache de grupos
        - Recupera informações detalhadas de grupos conectados
      parameters:
        - name: force
          in: query
          schema:
            type: boolean
            default: false
          description: |
            Se definido como `true`, força a atualização do cache de grupos.
            Útil para garantir que as informações mais recentes sejam recuperadas.

            Comportamentos:
            - `false` (padrão): Usa informações em cache
            - `true`: Busca dados atualizados diretamente do WhatsApp
        - name: noparticipants
          in: query
          schema:
            type: boolean
            default: false
          description: |
            Se definido como `true`, retorna a lista de grupos sem incluir os participantes.
            Útil para otimizar a resposta quando não há necessidade dos dados dos participantes.

            Comportamentos:
            - `false` (padrão): Retorna grupos com lista completa de participantes
            - `true`: Retorna grupos sem incluir os participantes
      responses:
        '200':
          description: Lista de grupos recuperada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  groups:
                    type: array
                    items:
                      $ref: ../schemas/group.yaml#/Group
                    description: Lista detalhada de grupos
        '500':
          description: Erro interno do servidor ao recuperar grupos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
    post:
      operationId: refreshGroups
      tags:
        - Grupos e Comunidades
      summary: Listar todos os grupos com filtros e paginacao
      description: >
        Retorna uma lista com todos os grupos disponiveis para a conta do WhatsApp atualmente conectada, com opcoes de
        filtros e paginacao via corpo (POST).

        A rota GET continua para quem prefere a listagem direta sem paginacao.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                limit:
                  type: integer
                  description: Quantidade maxima de resultados por pagina (padrao 50, maximo 1000)
                  default: 50
                offset:
                  type: integer
                  description: Deslocamento base zero
                  default: 0
                search:
                  type: string
                  description: Texto para filtrar grupos por nome/JID
                force:
                  type: boolean
                  default: false
                  description: |
                    Se definido como `true`, forca a atualizacao do cache de grupos.
                    Util para garantir que as informacoes mais recentes sejam recuperadas.
                noParticipants:
                  type: boolean
                  default: false
                  description: |
                    Se definido como `true`, retorna a lista de grupos sem incluir os participantes.
                    Util para otimizar a resposta quando nao ha necessidade dos dados dos participantes.
      responses:
        '200':
          description: Lista de grupos recuperada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  groups:
                    type: array
                    items:
                      $ref: ../schemas/group.yaml#/Group
                    description: Lista detalhada de grupos
                  pagination:
                    type: object
                    properties:
                      totalRecords:
                        type: integer
                        description: Total de grupos encontrados
                      limit:
                        type: integer
                        description: Limite aplicado na pagina atual
                      offset:
                        type: integer
                        description: Offset efetivamente usado na pagina atual
        '500':
          description: Erro interno do servidor ao recuperar grupos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
  /group/resetInviteCode:
    post:
      operationId: resetGroupInviteCode
      tags:
        - Grupos e Comunidades
      summary: Resetar código de convite do grupo
      description: |
        Gera um novo código de convite para o grupo, invalidando o código de convite anterior. 
        Somente administradores do grupo podem realizar esta ação.

        Principais características:
        - Invalida o link de convite antigo
        - Cria um novo link único
        - Retorna as informações atualizadas do grupo
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                groupjid:
                  type: string
                  description: Identificador único do grupo (JID)
                  example: 120363308883996631@g.us
              required:
                - groupjid
      responses:
        '200':
          description: Código de convite resetado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  InviteLink:
                    type: string
                    description: Novo link de convite gerado
                    example: https://chat.whatsapp.com/AbCdEfGhIjKlMnOpQrStUv
                  group:
                    $ref: ../schemas/group.yaml#/Group
                  needs_refresh:
                    type: boolean
                    description: Indica se o grupo precisa ser atualizado no cache local
                    example: false
        '400':
          description: Erro de validação
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Could not parse Group JID
        '403':
          description: Usuário sem permissão
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: User is not an admin of this group
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to reset group invite link
  /group/updateAnnounce:
    post:
      operationId: updateGroupAnnounce
      tags:
        - Grupos e Comunidades
      summary: Configurar permissões de envio de mensagens no grupo
      description: |
        Define as permissões de envio de mensagens no grupo, permitindo restringir o envio apenas para administradores.

        Quando ativado (announce=true):
        - Apenas administradores podem enviar mensagens
        - Outros participantes podem apenas ler
        - Útil para anúncios importantes ou controle de spam

        Quando desativado (announce=false):
        - Todos os participantes podem enviar mensagens
        - Configuração padrão para grupos normais

        Requer que o usuário seja administrador do grupo para fazer alterações.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                groupjid:
                  type: string
                  description: Identificador único do grupo no formato xxxx@g.us
                  example: 120363339858396166@g.us
                announce:
                  type: boolean
                  description: Controla quem pode enviar mensagens no grupo
                  example: true
              required:
                - groupjid
                - announce
      responses:
        '200':
          description: Configuração atualizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Group announce enabled successfully
                  group:
                    $ref: ../schemas/group.yaml#/Group
                  needs_refresh:
                    type: boolean
                    description: Indica se o grupo precisa ser atualizado no cache local
                    example: false
        '401':
          description: Token de autenticação ausente ou inválido
        '403':
          description: Usuário não é administrador do grupo
        '404':
          description: Grupo não encontrado
        '500':
          description: Erro interno do servidor ou falha na API do WhatsApp
  /group/updateDescription:
    post:
      operationId: updateGroupDescription
      tags:
        - Grupos e Comunidades
      summary: Atualizar descrição do grupo
      description: |
        Altera a descrição (tópico) do grupo WhatsApp especificado.
        Requer que o usuário seja administrador do grupo.
        A descrição aparece na tela de informações do grupo e pode ser visualizada por todos os participantes.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - groupjid
                - description
              properties:
                groupjid:
                  type: string
                  description: JID (ID) do grupo no formato xxxxx@g.us
                  example: 120363339858396166@g.us
                  pattern: ^[0-9]+@g\.us$
                description:
                  type: string
                  description: Nova descrição/tópico do grupo
                  example: Grupo oficial de suporte
                  maxLength: 512
      responses:
        '200':
          description: Descrição atualizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Group description updated successfully
                  group:
                    $ref: ../schemas/group.yaml#/Group
                  needs_refresh:
                    type: boolean
                    description: Indica se o grupo precisa ser atualizado no cache local
                    example: false
        '401':
          description: Token inválido ou ausente
        '403':
          description: Usuário não é administrador do grupo
        '404':
          description: Grupo não encontrado
        '413':
          description: Descrição excede o limite máximo permitido
  /group/updateImage:
    post:
      operationId: updateGroupImage
      tags:
        - Grupos e Comunidades
      summary: Atualizar imagem do grupo
      description: |
        Altera a imagem do grupo especificado. A imagem pode ser enviada como URL ou como string base64.

        Requisitos da imagem:
        - Formato: JPEG
        - Resolução máxima: 640x640 pixels
        - Imagens maiores ou diferente de JPEG não são aceitas pelo WhatsApp

        Para remover a imagem atual, envie "remove" ou "delete" no campo image.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                groupjid:
                  type: string
                  description: JID do grupo
                  example: 120363308883996631@g.us
                image:
                  type: string
                  description: |
                    URL da imagem, string base64 ou "remove"/"delete" para remover.
                    A imagem deve estar em formato JPEG e ter resolução máxima de 640x640.
                  examples:
                    - https://example.com/image.jpg
                    - data:image/jpeg;base64,/9j/4AAQSkZJRg...
                    - remove
              required:
                - groupjid
                - image
      parameters: []
      responses:
        '200':
          description: Imagem atualizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Group image updated successfully
                  group:
                    $ref: ../schemas/group.yaml#/Group
                  needs_refresh:
                    type: boolean
                    description: Indica se o grupo precisa ser atualizado no cache local
                    example: false
        '400':
          description: Erro nos parâmetros da requisição
        '401':
          description: Token inválido ou expirado
        '403':
          description: Usuário não é administrador do grupo
        '413':
          description: Imagem muito grande
        '415':
          description: Formato de imagem inválido
  /group/updateLocked:
    post:
      operationId: updateGroupLocked
      tags:
        - Grupos e Comunidades
      summary: Configurar permissão de edição do grupo
      description: |
        Define se apenas administradores podem editar as informações do grupo. 
        Quando bloqueado (locked=true), apenas administradores podem alterar nome, descrição, 
        imagem e outras configurações do grupo. Quando desbloqueado (locked=false), 
        qualquer participante pode editar as informações.

        Importante:
        - Requer que o usuário seja administrador do grupo
        - Afeta edições de nome, descrição, imagem e outras informações do grupo
        - Não controla permissões de adição de membros
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                groupjid:
                  type: string
                  description: Identificador único do grupo (JID)
                  example: 120363308883996631@g.us
                locked:
                  type: boolean
                  description: |
                    Define permissões de edição:
                    - true = apenas admins podem editar infos do grupo
                    - false = qualquer participante pode editar infos do grupo
                  example: true
              required:
                - groupjid
                - locked
      responses:
        '200':
          description: Operação realizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Group lock status changed successfully
                  group:
                    $ref: ../schemas/group.yaml#/Group
                  needs_refresh:
                    type: boolean
                    description: Indica se o grupo precisa ser atualizado no cache local
                    example: false
        '403':
          description: Usuário não é administrador do grupo
        '404':
          description: Grupo não encontrado
  /group/updateName:
    post:
      operationId: updateGroupName
      tags:
        - Grupos e Comunidades
      summary: Atualizar nome do grupo
      description: |
        Altera o nome de um grupo do WhatsApp. Apenas administradores do grupo podem realizar esta operação.
        O nome do grupo deve seguir as diretrizes do WhatsApp e ter entre 1 e 25 caracteres.
      security:
        - token: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - groupjid
                - name
              properties:
                groupjid:
                  type: string
                  description: Identificador único do grupo no formato JID
                  example: 120363339858396166@g.us
                name:
                  type: string
                  description: Novo nome para o grupo
                  example: Grupo de Suporte
                  minLength: 1
                  maxLength: 25
      responses:
        '200':
          description: Nome do grupo atualizado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Group name updated successfully
                  group:
                    $ref: ../schemas/group.yaml#/Group
                  needs_refresh:
                    type: boolean
                    description: Indica se o grupo precisa ser atualizado no cache local
                    example: false
        '400':
          description: Erro de validação na requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid payload
        '401':
          description: Token de autenticação ausente ou inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unauthorized
        '403':
          description: Usuário não é administrador do grupo
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: User is not an admin of this group
        '404':
          description: Grupo não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Group not found
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to update group name
  /group/updateParticipants:
    post:
      operationId: updateGroupParticipants
      tags:
        - Grupos e Comunidades
      summary: Gerenciar participantes do grupo
      description: |
        Gerencia participantes do grupo através de diferentes ações:
        - Adicionar ou remover participantes
        - Promover ou rebaixar administradores
        - Aprovar ou rejeitar solicitações pendentes

        Requer que o usuário seja administrador do grupo para executar as ações.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                groupjid:
                  type: string
                  description: JID (identificador) do grupo
                  example: 120363308883996631@g.us
                action:
                  type: string
                  description: |
                    Ação a ser executada:
                    - add: Adicionar participantes ao grupo
                    - remove: Remover participantes do grupo
                    - promote: Promover participantes a administradores
                    - demote: Remover privilégios de administrador
                    - approve: Aprovar solicitações pendentes de entrada
                    - reject: Rejeitar solicitações pendentes de entrada
                  enum:
                    - add
                    - remove
                    - promote
                    - demote
                    - approve
                    - reject
                  example: promote
                participants:
                  type: array
                  items:
                    type: string
                  description: |
                    Lista de números de telefone ou JIDs dos participantes.
                    Para números de telefone, use formato internacional sem '+' ou espaços.
                  example:
                    - '5521987654321'
                    - '5511999887766'
              required:
                - groupjid
                - action
                - participants
      responses:
        '200':
          description: Sucesso na operação
          content:
            application/json:
              schema:
                type: object
                properties:
                  groupUpdated:
                    type: array
                    items:
                      type: object
                      properties:
                        JID:
                          type: string
                          description: JID do participante
                        Error:
                          type: integer
                          description: Código de erro (0 para sucesso)
                    description: Status da operação para cada participante
                  group:
                    $ref: ../schemas/group.yaml#/Group
                    description: Informações atualizadas do grupo
                  needs_refresh:
                    type: boolean
                    description: Indica se o grupo precisa ser atualizado no cache local
                    example: false
        '400':
          description: Erro nos parâmetros da requisição
        '403':
          description: Usuário não é administrador do grupo
        '500':
          description: Erro interno do servidor
  /community/create:
    post:
      operationId: createCommunity
      tags:
        - Grupos e Comunidades
      summary: Criar uma comunidade
      description: >
        Cria uma nova comunidade no WhatsApp. Uma comunidade é uma estrutura que permite agrupar múltiplos grupos
        relacionados sob uma única administração. 


        A comunidade criada inicialmente terá apenas o grupo principal (announcements), e grupos adicionais podem ser
        vinculados posteriormente usando o endpoint `/community/updategroups`.


        **Observações importantes:**

        - O número que cria a comunidade torna-se automaticamente o administrador

        - A comunidade terá um grupo principal de anúncios criado automaticamente
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Nome da comunidade
                  example: Comunidade do Bairro
              required:
                - name
      responses:
        '200':
          description: Comunidade criada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  group:
                    $ref: ../schemas/group.yaml#/Group
                  failed:
                    type: array
                    description: Lista de JIDs que falharam ao serem adicionados
                    items:
                      type: string
                      format: jid
        '400':
          description: Erro na requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid payload
        '401':
          description: Token inválido ou não fornecido
        '403':
          description: Sem permissão para criar comunidades
        '429':
          description: Limite de criação de comunidades atingido
        '500':
          description: Erro interno do servidor
  /community/editgroups:
    post:
      operationId: editCommunityGroups
      tags:
        - Grupos e Comunidades
      summary: Gerenciar grupos em uma comunidade
      description: >
        Adiciona ou remove grupos de uma comunidade do WhatsApp. Apenas administradores da comunidade podem executar
        estas operações.


        ## Funcionalidades

        - Adicionar múltiplos grupos simultaneamente a uma comunidade

        - Remover grupos de uma comunidade existente

        - Suporta operações em lote


        ## Limitações

        - Os grupos devem existir previamente

        - A comunidade deve existir e o usuário deve ser administrador

        - Grupos já vinculados não podem ser adicionados novamente

        - Grupos não vinculados não podem ser removidos


        ## Ações Disponíveis

        - `add`: Adiciona os grupos especificados à comunidade

        - `remove`: Remove os grupos especificados da comunidade
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - community
                - action
                - groupjids
              properties:
                community:
                  type: string
                  description: JID (identificador único) da comunidade
                  example: 120363153742561022@g.us
                action:
                  type: string
                  enum:
                    - add
                    - remove
                  description: |
                    Tipo de operação a ser realizada:
                    * add - Adiciona grupos à comunidade
                    * remove - Remove grupos da comunidade
                groupjids:
                  type: array
                  items:
                    type: string
                    pattern: ^[0-9]+@g.us$
                  minItems: 1
                  description: Lista de JIDs dos grupos para adicionar ou remover
                  example:
                    - 120363324255083289@g.us
                    - 120363308883996631@g.us
      responses:
        '200':
          description: Operação realizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: community updated
                  success:
                    type: array
                    items:
                      type: string
                    description: Lista de JIDs dos grupos processados com sucesso
                  failed:
                    type: array
                    items:
                      type: string
                    description: Lista de JIDs dos grupos que falharam no processamento
        '400':
          description: Requisição inválida
        '401':
          description: Não autorizado
        '403':
          description: Usuário não é administrador da comunidade
  /newsletter/create:
    post:
      operationId: createNewsletter
      tags:
        - Newsletters e Canais
      summary: Criar canal
      description: |
        Cria um novo canal/newsletter no WhatsApp.

        Observações:
        - `name` é obrigatório
        - `picture` é opcional
        - `picture` aceita URL HTTP/HTTPS, base64 puro ou data URI
        - imagens acima de 1 MB são rejeitadas
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
                  example: Canal de Promoções
                description:
                  type: string
                  example: Ofertas e novidades da loja
                picture:
                  type: string
                  description: URL, base64 puro ou data URI da imagem do canal.
                  example: https://example.com/newsletter.png
      responses:
        '200':
          description: Canal criado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: object
                    description: Metadata do canal retornada pelo WhatsApp.
                    additionalProperties: true
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: name is required
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao criar o canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/list:
    get:
      operationId: listNewsletters
      tags:
        - Newsletters e Canais
      summary: Listar canais inscritos
      description: |
        Retorna os canais/newsletters já inscritos pela conta do WhatsApp atualmente conectada.
      responses:
        '200':
          description: Lista de canais recuperada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: array
                    items:
                      type: object
                      additionalProperties: true
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao listar canais
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/info:
    post:
      operationId: getNewsletterInfo
      tags:
        - Newsletters e Canais
      summary: Buscar informações de um canal
      description: |
        Busca os detalhes de um canal/newsletter pelo `id` numérico ou pelo `jid`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: ID numérico do canal. Se informado sem domínio, será convertido para `@newsletter`.
                  example: '120363123456789012'
                jid:
                  type: string
                  description: JID completo do canal.
                  example: 120363123456789012@newsletter
      responses:
        '200':
          description: Informações do canal recuperadas com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: object
                    additionalProperties: true
        '400':
          description: ID/JID inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid newsletter id
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao consultar o canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/link:
    post:
      operationId: getNewsletterInfoWithInvite
      tags:
        - Newsletters e Canais
      summary: Buscar canal por link-chave de convite
      description: |
        Busca as informações de um canal a partir da chave de convite.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - key
              properties:
                key:
                  type: string
                  description: Chave do convite do canal.
                  example: AbCdEfGhIjKlMn
      responses:
        '200':
          description: Informações do canal recuperadas com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: object
                    additionalProperties: true
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: key is required
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao consultar o convite
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/subscribe:
    post:
      operationId: subscribeNewsletterLiveUpdates
      tags:
        - Newsletters e Canais
      summary: Assinar live updates temporários de um canal
      description: |
        Assina temporariamente os live updates internos do WhatsApp para um canal.

        Observação:
        - esta rota retorna apenas a duração da assinatura temporária
        - isso não cria um novo evento de webhook
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
      responses:
        '200':
          description: Assinatura criada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    description: Duração retornada pelo WhatsApp.
                    example: 5m0s
        '400':
          description: ID/JID inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid newsletter id
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao assinar updates
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/messages:
    post:
      operationId: getNewsletterMessages
      tags:
        - Newsletters e Canais
      summary: Buscar mensagens de um canal
      description: |
        Busca diretamente no WhatsApp os posts/mensagens de um canal (newsletter).

        Esta rota não depende de mensagens salvas localmente e é útil para:
        - carregar o histórico recente de posts de um canal
        - paginar mensagens anteriores usando `beforeid`
        - consumir conteúdo de newsletters sem persistência em banco

        Identificação do canal:
        - envie `id` com o identificador numérico do canal; o backend converte para `@newsletter`
        - ou envie `jid` completo no formato `1234567890@newsletter`

        Observações:
        - `count` controla quantos posts retornar
        - use preferencialmente `beforeid`
        - `beforeid` pagina para trás a partir de um `serverid`
        - o retorno vem no campo `response`
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: ID numérico do canal. Se informado sem domínio, será convertido para `@newsletter`.
                  example: '120363123456789012'
                jid:
                  type: string
                  description: JID completo do canal.
                  example: 120363123456789012@newsletter
                count:
                  type: integer
                  minimum: 1
                  description: Quantidade de mensagens/posts a buscar.
                  example: 20
                beforeid:
                  type: integer
                  minimum: 1
                  description: |
                    Retorna mensagens anteriores ao `serverid` informado.
                    Use para paginação retroativa.
                  example: 12345
            examples:
              basico:
                summary: Buscar últimos posts do canal
                value:
                  id: '120363123456789012'
                  count: 20
              paginacao:
                summary: Buscar posts anteriores a um server id
                value:
                  jid: 120363123456789012@newsletter
                  count: 20
                  beforeid: 12345
      responses:
        '200':
          description: Mensagens do canal recuperadas com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: array
                    description: Lista de mensagens/posts do canal retornados diretamente pelo WhatsApp.
                    items:
                      type: object
                      properties:
                        serverid:
                          type: integer
                          description: Identificador sequencial do post no canal.
                          example: 12345
                        messageid:
                          type: string
                          description: ID lógico da mensagem.
                          example: 3EB0B4302B3A8A52F7A1
                        type:
                          type: string
                          description: Tipo da mensagem do canal.
                          example: text
                        timestamp:
                          type: string
                          format: date-time
                          description: Momento em que o post foi publicado.
                        viewsCount:
                          type: integer
                          description: Quantidade de visualizações conhecida no momento da consulta.
                          example: 1200
                        reactionCounts:
                          type: object
                          additionalProperties:
                            type: integer
                          description: Mapa de emoji para quantidade de reações.
                          example:
                            👍: 22
                            🔥: 7
                        message:
                          type: object
                          description: Conteúdo bruto da mensagem retornado pelo WhatsApp quando disponível.
                          additionalProperties: true
              examples:
                sucesso:
                  value:
                    response:
                      - messageid: 3EB0B4302B3A8A52F7A1
                        serverid: 12345
                        type: text
                        timestamp: '2026-03-24T18:20:00Z'
                        viewsCount: 1200
                        reactionCounts:
                          👍: 22
                          🔥: 7
                        message:
                          conversation: Post do canal
        '400':
          description: Payload inválido ou ID/JID do canal inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid newsletter id
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao consultar mensagens do canal no WhatsApp
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/messages/edit:
    post:
      operationId: editNewsletterMessage
      tags:
        - Newsletters e Canais
      summary: Editar mensagem recente de um canal
      description: |
        Edita o conteúdo de um post recente de newsletter diretamente no WhatsApp.

        Esta rota:
        - nao depende de mensagens salvas localmente
        - busca a mensagem recente do canal via WhatsApp/whatsmeow
        - localiza o post por `messageid` ou `serverid`
        - edita apenas tipos suportados (`text`, `image`, `video`, `document`)

        Observações:
        - use `jid` ou `id` para identificar o canal
        - envie ao menos um entre `messageid` e `serverid`
        - envie `text` com o novo conteúdo/legenda
        - `count` e `maxpages` controlam a janela de busca no canal
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - text
              properties:
                id:
                  type: string
                  description: ID numérico do canal. Se informado sem domínio, será convertido para `@newsletter`.
                  example: '120363123456789012'
                jid:
                  type: string
                  description: JID completo do canal.
                  example: 120363123456789012@newsletter
                messageid:
                  type: string
                  description: ID lógico da mensagem no canal.
                  example: 3EB0B4302B3A8A52F7A1
                serverid:
                  type: integer
                  minimum: 1
                  description: Identificador sequencial do post no canal.
                  example: 12345
                text:
                  type: string
                  description: Novo texto ou nova legenda do post.
                  example: Post atualizado
                count:
                  type: integer
                  minimum: 1
                  description: Quantidade de mensagens buscadas por página ao localizar o post.
                  example: 100
                maxpages:
                  type: integer
                  minimum: 1
                  description: Quantidade máxima de páginas buscadas ao localizar o post.
                  example: 5
            examples:
              por_message_id:
                summary: Editar usando o ID lógico da mensagem
                value:
                  jid: 120363123456789012@newsletter
                  messageid: 3EB0B4302B3A8A52F7A1
                  text: Post atualizado
              por_server_id:
                summary: Editar usando o server id do post
                value:
                  id: '120363123456789012'
                  serverid: 12345
                  text: Nova legenda do post
      responses:
        '200':
          description: Mensagem do canal editada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: object
                    properties:
                      jid:
                        type: string
                        example: 120363123456789012@newsletter
                      targetmessageid:
                        type: string
                        description: ID lógico do post editado.
                        example: 3EB0B4302B3A8A52F7A1
                      targetserverid:
                        type: integer
                        description: Identificador sequencial do post editado.
                        example: 12345
                      messageid:
                        type: string
                        description: ID da operação de edição enviada ao WhatsApp.
                        example: 3EB01234567890ABCDEF
                      serverid:
                        type: integer
                        description: Server id retornado pela operação de edição.
                        example: 12346
        '400':
          description: Payload inválido, mensagem não editável, mensagem alvo não identificada ou canal inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: text is required
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '404':
          description: Mensagem do canal não encontrada na janela recente consultada
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: newsletter message not found in recent history
        '500':
          description: Erro interno ao consultar ou editar a mensagem do canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/messages/delete:
    post:
      operationId: deleteNewsletterMessage
      tags:
        - Newsletters e Canais
      summary: Deletar mensagem recente de um canal
      description: |
        Apaga um post recente de newsletter diretamente no WhatsApp.

        Esta rota:
        - nao depende de mensagens salvas localmente
        - revoga o post no canal usando o WhatsApp/whatsmeow
        - aceita localizar o post por `messageid` ou `serverid`

        Observações:
        - use `jid` ou `id` para identificar o canal
        - envie ao menos um entre `messageid` e `serverid`
        - `count` e `maxpages` controlam a janela de busca no canal
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: ID numérico do canal. Se informado sem domínio, será convertido para `@newsletter`.
                  example: '120363123456789012'
                jid:
                  type: string
                  description: JID completo do canal.
                  example: 120363123456789012@newsletter
                messageid:
                  type: string
                  description: ID lógico da mensagem no canal.
                  example: 3EB0B4302B3A8A52F7A1
                serverid:
                  type: integer
                  minimum: 1
                  description: Identificador sequencial do post no canal.
                  example: 12345
                count:
                  type: integer
                  minimum: 1
                  description: Quantidade de mensagens buscadas por página ao localizar o post.
                  example: 100
                maxpages:
                  type: integer
                  minimum: 1
                  description: Quantidade máxima de páginas buscadas ao localizar o post.
                  example: 5
            examples:
              por_message_id:
                summary: Deletar usando o ID lógico da mensagem
                value:
                  jid: 120363123456789012@newsletter
                  messageid: 3EB0B4302B3A8A52F7A1
              por_server_id:
                summary: Deletar usando o server id do post
                value:
                  id: '120363123456789012'
                  serverid: 12345
      responses:
        '200':
          description: Mensagem do canal deletada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: object
                    properties:
                      jid:
                        type: string
                        example: 120363123456789012@newsletter
                      targetmessageid:
                        type: string
                        description: ID lógico do post deletado.
                        example: 3EB0B4302B3A8A52F7A1
                      targetserverid:
                        type: integer
                        description: Identificador sequencial do post deletado.
                        example: 12345
                      messageid:
                        type: string
                        description: ID da operação de deleção enviada ao WhatsApp.
                        example: 3EB01234567890ABCDEF
                      serverid:
                        type: integer
                        description: Server id retornado pela operação de deleção.
                        example: 12346
        '400':
          description: Payload inválido ou canal inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: messageid or serverid is required
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '404':
          description: Mensagem do canal não encontrada na janela recente consultada
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: newsletter message not found in recent history
        '500':
          description: Erro interno ao consultar ou deletar a mensagem do canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/updates:
    post:
      operationId: getNewsletterMessageUpdates
      tags:
        - Newsletters e Canais
      summary: Buscar updates de mensagens de um canal
      description: |
        Consulta diretamente no WhatsApp os updates de posts já existentes de um canal.

        Esta rota é diferente de `/newsletter/messages`:
        - `/newsletter/messages` retorna o conteúdo dos posts
        - `/newsletter/updates` retorna mudanças posteriores nos posts, especialmente métricas

        Esta rota também não é um evento de webhook:
        - não existe webhook `newsletter_messages_update`
        - para views e reactions de canais, consulte `/newsletter/updates` sob demanda

        Casos de uso:
        - atualizar contadores de `views` de posts já carregados
        - atualizar `reactionCounts` de posts do canal
        - consultar sob demanda os mesmos tipos de métricas que chegam nos live updates internos do WhatsApp

        Observações:
        - use preferencialmente `afterid`
        - `afterid` filtra updates depois de um `serverid`
        - `since` filtra pelo momento do update
        - `since` aceita timestamp em segundos ou milissegundos
        - o retorno vem no campo `response`
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: ID numérico do canal. Se informado sem domínio, será convertido para `@newsletter`.
                  example: '120363123456789012'
                jid:
                  type: string
                  description: JID completo do canal.
                  example: 120363123456789012@newsletter
                count:
                  type: integer
                  minimum: 1
                  description: Quantidade máxima de updates retornados.
                  example: 50
                afterid:
                  type: integer
                  minimum: 1
                  description: Retorna apenas updates posteriores ao `serverid` informado.
                  example: 12345
                since:
                  type: integer
                  description: |
                    Timestamp de corte.
                    - Se maior que `1000000000000`, é interpretado como milissegundos.
                    - Caso contrário, é interpretado como segundos.
                  example: 1710000000
            examples:
              por_after_id:
                summary: Buscar updates depois de um post conhecido
                value:
                  id: '120363123456789012'
                  count: 50
                  afterid: 12345
              por_since:
                summary: Buscar updates a partir de um timestamp
                value:
                  jid: 120363123456789012@newsletter
                  count: 50
                  since: 1710000000
      responses:
        '200':
          description: Updates de mensagens do canal recuperados com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: array
                    description: Lista de updates de mensagens do canal.
                    items:
                      type: object
                      properties:
                        serverid:
                          type: integer
                          description: Identificador do post no canal.
                          example: 12345
                        messageid:
                          type: string
                          description: ID lógico da mensagem.
                          example: 3EB0B4302B3A8A52F7A1
                        type:
                          type: string
                          description: Tipo da mensagem do canal.
                          example: text
                        timestamp:
                          type: string
                          format: date-time
                          description: Momento associado ao update retornado.
                        viewsCount:
                          type: integer
                          description: Quantidade atualizada de visualizações.
                          example: 1540
                        reactionCounts:
                          type: object
                          additionalProperties:
                            type: integer
                          description: Mapa atualizado de emoji para quantidade de reações.
                          example:
                            👍: 35
                            🔥: 11
                        message:
                          type: object
                          description: |
                            Conteúdo bruto da mensagem, quando presente.
                            Em muitos live updates esse campo pode vir ausente.
                          additionalProperties: true
              examples:
                sucesso:
                  value:
                    response:
                      - messageid: 3EB0B4302B3A8A52F7A1
                        serverid: 12345
                        type: text
                        timestamp: '2026-03-24T19:00:00Z'
                        viewsCount: 1540
                        reactionCounts:
                          👍: 35
                          🔥: 11
        '400':
          description: Payload inválido ou ID/JID do canal inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid newsletter id
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao consultar updates do canal no WhatsApp
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/viewed:
    post:
      operationId: markNewsletterViewed
      tags:
        - Newsletters e Canais
      summary: Marcar posts do canal como visualizados
      description: |
        Marca um ou mais posts do canal como visualizados usando `serverid`.

        Observações:
        - envie `serverids` com uma lista de posts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
                serverids:
                  type: array
                  items:
                    type: integer
                  example:
                    - 12345
                    - 12346
      responses:
        '200':
          description: Posts marcados como visualizados
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: Payload inválido ou faltando `serverids`
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: serverids is required
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao marcar visualização
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/reaction:
    post:
      operationId: reactNewsletterMessage
      tags:
        - Newsletters e Canais
      summary: Reagir a um post do canal
      description: |
        Envia, altera ou remove uma reação de um post do canal.

        Observações:
        - `serverid` identifica o post alvo
        - `reaction` define o emoji
        - envie `reaction` vazio para remover a reação
        - `reactionmessageid` é opcional; se omitido, o WhatsApp gera o ID da reação
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
                serverid:
                  type: integer
                  example: 12345
                reaction:
                  type: string
                  example: 🔥
                reactionmessageid:
                  type: string
                  example: 3EB0AABBCCDD
      responses:
        '200':
          description: Reação aplicada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: Payload inválido ou faltando `serverid`
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: serverid is required
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao reagir ao post
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/follow:
    post:
      operationId: followNewsletter
      tags:
        - Newsletters e Canais
      summary: Seguir canal
      description: Segue um canal/newsletter.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
      responses:
        '200':
          description: Canal seguido com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: ID/JID inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid newsletter id
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao seguir canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/unfollow:
    post:
      operationId: unfollowNewsletter
      tags:
        - Newsletters e Canais
      summary: Deixar de seguir canal
      description: Deixa de seguir um canal/newsletter.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
      responses:
        '200':
          description: Canal removido dos seguidos com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: ID/JID inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid newsletter id
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao deixar de seguir canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/mute:
    post:
      operationId: muteNewsletter
      tags:
        - Newsletters e Canais
      summary: Silenciar canal
      description: Ativa o mute de um canal/newsletter.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
      responses:
        '200':
          description: Canal silenciado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: ID/JID inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid newsletter id
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao silenciar canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/unmute:
    post:
      operationId: unmuteNewsletter
      tags:
        - Newsletters e Canais
      summary: Remover mute do canal
      description: Remove o mute de um canal/newsletter.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
      responses:
        '200':
          description: Mute removido com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: ID/JID inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid newsletter id
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao remover mute do canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/delete:
    post:
      operationId: deleteNewsletter
      tags:
        - Newsletters e Canais
      summary: Deletar canal
      description: Remove/deleta um canal/newsletter.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
      responses:
        '200':
          description: Canal deletado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: ID/JID inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid newsletter id
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao deletar o canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/picture:
    post:
      operationId: updateNewsletterPicture
      tags:
        - Newsletters e Canais
      summary: Atualizar foto do canal
      description: |
        Atualiza a imagem do canal/newsletter.

        Observações:
        - `picture` aceita URL HTTP/HTTPS, base64 puro ou data URI
        - imagens acima de 1 MB são rejeitadas
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - picture
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
                picture:
                  type: string
                  example: https://example.com/newsletter.png
      responses:
        '200':
          description: Foto do canal atualizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: empty image source
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao atualizar a foto do canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/name:
    post:
      operationId: updateNewsletterName
      tags:
        - Newsletters e Canais
      summary: Atualizar nome do canal
      description: Atualiza o nome do canal/newsletter.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
                name:
                  type: string
                  example: Canal de Promoções VIP
      responses:
        '200':
          description: Nome atualizado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: name is required
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao atualizar o nome do canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/description:
    post:
      operationId: updateNewsletterDescription
      tags:
        - Newsletters e Canais
      summary: Atualizar descrição do canal
      description: Atualiza a descrição do canal/newsletter.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
                description:
                  type: string
                  example: Atualizações, ofertas e novidades
      responses:
        '200':
          description: Descrição atualizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: Payload inválido ou ID/JID inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid newsletter id
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao atualizar a descrição do canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/settings:
    post:
      operationId: updateNewsletterSettings
      tags:
        - Newsletters e Canais
      summary: Atualizar configurações do canal
      description: |
        Atualiza configurações do canal/newsletter.

        Atualmente, esta rota controla `reactionCodes`.

        Valores aceitos:
        - `all`
        - `basic`
        - `none`
        - `blocklist`
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - reactionCodes
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
                reactionCodes:
                  type: string
                  example: basic
      responses:
        '200':
          description: Configurações atualizadas com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid reactionCodes
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao atualizar configurações do canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/search:
    post:
      operationId: searchNewsletterDirectory
      tags:
        - Newsletters e Canais
      summary: Pesquisar canais públicos
      description: |
        Pesquisa canais/newsletters públicos no diretório do WhatsApp.

        Observações:
        - use `after` para buscar a próxima página
        - `countryCodes` filtra por países
        - `view` e `searchText` são opcionais
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                limit:
                  type: integer
                  example: 20
                view:
                  type: string
                  example: RECOMMENDED
                countryCodes:
                  type: array
                  items:
                    type: string
                  example:
                    - BR
                searchText:
                  type: string
                  example: promo
                after:
                  type: string
                  example: YXJyYXljb25uZWN0aW9uOjE5
      responses:
        '200':
          description: Pesquisa executada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: object
                    properties:
                      after:
                        type: string
                        nullable: true
                        example: YXJyYXljb25uZWN0aW9uOjIw
                      data:
                        type: array
                        items:
                          type: object
                          additionalProperties: true
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid payload
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao pesquisar canais
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/admin/invite:
    post:
      operationId: inviteNewsletterAdmin
      tags:
        - Newsletters e Canais
      summary: Convidar admin do canal
      description: Convida um telefone para virar administrador do canal.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - phone
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
                phone:
                  type: string
                  example: '5511999999999'
      responses:
        '200':
          description: Convite enviado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: phone is required
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao convidar admin
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/admin/accept:
    post:
      operationId: acceptNewsletterAdminInvite
      tags:
        - Newsletters e Canais
      summary: Aceitar convite de admin do canal
      description: Aceita um convite pendente de administrador do canal.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
      responses:
        '200':
          description: Convite aceito com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: ID/JID inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid newsletter id
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao aceitar convite de admin
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/admin/remove:
    post:
      operationId: removeNewsletterAdmin
      tags:
        - Newsletters e Canais
      summary: Remover admin do canal
      description: Remove um administrador do canal usando o telefone dele.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - phone
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
                phone:
                  type: string
                  example: '5511999999999'
      responses:
        '200':
          description: Admin removido com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: phone is required
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao remover admin
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/admin/revoke:
    post:
      operationId: revokeNewsletterAdminInvite
      tags:
        - Newsletters e Canais
      summary: Revogar convite de admin do canal
      description: Revoga um convite pendente de administrador do canal usando o telefone do convidado.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - phone
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
                phone:
                  type: string
                  example: '5511999999999'
      responses:
        '200':
          description: Convite revogado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: phone is required
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao revogar convite
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /newsletter/owner/transfer:
    post:
      operationId: transferNewsletterOwnership
      tags:
        - Newsletters e Canais
      summary: Transferir dono do canal
      description: |
        Transfere a propriedade do canal para outro telefone.

        Observações:
        - `phone` é obrigatório
        - `quitAdmin=true` remove o dono anterior da posição de admin após a transferência
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - phone
              properties:
                id:
                  type: string
                  example: '120363123456789012'
                jid:
                  type: string
                  example: 120363123456789012@newsletter
                phone:
                  type: string
                  example: '5511999999999'
                quitAdmin:
                  type: boolean
                  example: false
      responses:
        '200':
          description: Transferência solicitada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: boolean
                    example: true
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: phone is required
        '401':
          description: Instância não autenticada ou cliente não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: client not found
        '500':
          description: Erro interno ao transferir ownership do canal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: connection closed
  /webhook:
    get:
      operationId: getWebhook
      tags:
        - Webhooks e SSE
      summary: Ver Webhook da Instância
      description: |
        Retorna a configuração atual do webhook da instância, incluindo:
        - URL configurada
        - Eventos ativos
        - Filtros aplicados
        - Configurações adicionais

        Exemplo de resposta:
        ```json
        [
          {
            "id": "123e4567-e89b-12d3-a456-426614174000",
            "enabled": true,
            "url": "https://example.com/webhook",
            "events": ["messages", "messages_update"],
            "excludeMessages": ["wasSentByApi", "isGroupNo"],
            "addUrlEvents": true,
            "addUrlTypesMessages": true
          },
          {
            "id": "987fcdeb-51k3-09j8-x543-864297539100",
            "enabled": true,
            "url": "https://outro-endpoint.com/webhook",
            "events": ["connection", "presence"],
            "excludeMessages": [],
            "addUrlEvents": false,
            "addUrlTypesMessages": false
          }
        ]
        ```

        A resposta é sempre um array, mesmo quando há apenas um webhook configurado.
      responses:
        '200':
          description: Configuração do webhook retornada com sucesso
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: ../schemas/webhook.yaml#/Webhook
              example:
                - id: 123e4567-e89b-12d3-a456-426614174000
                  enabled: true
                  url: https://example.com/webhook
                  events:
                    - messages
                    - messages_update
                  excludeMessages:
                    - wasSentByApi
                    - isGroupNo
                  addUrlEvents: true
                  addUrlTypesMessages: true
                - id: 987fcdeb-51k3-09j8-x543-864297539100
                  enabled: true
                  url: https://outro-endpoint.com/webhook
                  events:
                    - connection
                    - presence
                  excludeMessages: []
                  addUrlEvents: false
                  addUrlTypesMessages: false
        '401':
          description: Token inválido ou não fornecido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: missing token
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to process webhook data
    post:
      operationId: updateWebhook
      tags:
        - Webhooks e SSE
      summary: Configurar Webhook da Instância
      description: >
        Gerencia a configuração de webhooks para receber eventos em tempo real da instância.

        Permite gerenciar múltiplos webhooks por instância através do campo ID e action.


        ### 🚀 Modo Simples (Recomendado)


        **Uso mais fácil - sem complexidade de IDs**:

        - Não inclua `action` nem `id` no payload

        - Gerencia automaticamente um único webhook por instância

        - Cria novo ou atualiza o existente automaticamente

        - **Recomendado**: Sempre use `"excludeMessages": ["wasSentByApi"]` para evitar loops

        - **Exemplo**: `{"url": "https://meusite.com/webhook", "events": ["messages"], "excludeMessages":
        ["wasSentByApi"]}`


        ### 🧪 Sites para Testes (ordenados por qualidade)


        **Para testar webhooks durante desenvolvimento**:

        1. **https://webhook.cool/** - ⭐ Melhor opção (sem rate limit, interface limpa)

        2. **https://rbaskets.in/** - ⭐ Boa alternativa (confiável, baixo rate limit)

        3. **https://webhook.site/** - ⚠️ Evitar se possível (rate limit agressivo)


        ### ⚙️ Modo Avançado (Para múltiplos webhooks)


        **Para usuários que precisam de múltiplos webhooks por instância**:


        💡 **Dica**: Mesmo precisando de múltiplos webhooks, considere usar `addUrlEvents` no modo simples.

        Um único webhook pode receber diferentes tipos de eventos em URLs específicas 

        (ex: `/webhook/message`, `/webhook/connection`), eliminando a necessidade de múltiplos webhooks.


        1. **Criar Novo Webhook**:
           - Use `action: "add"`
           - Não inclua `id` no payload
           - O sistema gera ID automaticamente

        2. **Atualizar Webhook Existente**:
           - Use `action: "update"`
           - Inclua o `id` do webhook no payload
           - Todos os campos serão atualizados

        3. **Remover Webhook**:
           - Use `action: "delete"`
           - Inclua apenas o `id` do webhook
           - Outros campos são ignorados



        ### Eventos Disponíveis

        - `connection`: Alterações no estado da conexão

        - `history`: Recebimento de histórico de mensagens

        - `messages`: Novas mensagens recebidas

        - `messages_update`: Atualizações em mensagens existentes

        - `newsletter_messages`: Novos posts/mensagens de canais do WhatsApp
          Para views e reactions de canais, use a rota `/newsletter/updates`.
        - `call`: Eventos de chamadas VoIP

        - `contacts`: Atualizações na agenda de contatos

        - `presence`: Alterações no status de presença

        - `groups`: Modificações em grupos

        - `labels`: Gerenciamento de etiquetas

        - `chats`: Eventos de conversas

        - `chat_labels`: Alterações em etiquetas de conversas

        - `blocks`: Bloqueios/desbloqueios

        - `sender`: Atualizações de campanhas, quando inicia, e quando completa


        **Remover mensagens com base nos filtros**:

        - `wasSentByApi`: Mensagens originadas pela API ⚠️ **IMPORTANTE:** Use sempre este filtro para evitar loops em
        automações

        - `wasNotSentByApi`: Mensagens não originadas pela API

        - `fromMeYes`: Mensagens enviadas pelo usuário

        - `fromMeNo`: Mensagens recebidas de terceiros

        - `isGroupYes`: Mensagens em grupos

        - `isGroupNo`: Mensagens em conversas individuais


        💡 **Prevenção de Loops**: Se você tem automações que enviam mensagens via API, sempre inclua
        `"excludeMessages": ["wasSentByApi"]` no seu webhook. Caso prefira receber esses eventos, certifique-se de que
        sua automação detecta mensagens enviadas pela própria API para não criar loops infinitos.


        **Ações Suportadas**:

        - `add`: Registrar novo webhook

        - `delete`: Remover webhook existente


        **Parâmetros de URL**:

        - `addUrlEvents` (boolean): Quando ativo, adiciona o tipo do evento como path parameter na URL.
          Exemplo: `https://api.example.com/webhook/{evento}`
        - `addUrlTypesMessages` (boolean): Quando ativo, adiciona o tipo da mensagem como path parameter na URL.
          Exemplo: `https://api.example.com/webhook/{tipo_mensagem}`

        **Combinações de Parâmetros**:

        - Ambos ativos: `https://api.example.com/webhook/{evento}/{tipo_mensagem}`
          Exemplo real: `https://api.example.com/webhook/message/conversation`
        - Apenas eventos: `https://api.example.com/webhook/message`

        - Apenas tipos: `https://api.example.com/webhook/conversation`


        **Notas Técnicas**:

        1. Os parâmetros são adicionados na ordem: evento → tipo mensagem

        2. A URL deve ser configurada para aceitar esses parâmetros dinâmicos

        3. Funciona com qualquer combinação de eventos/mensagens
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: ID único do webhook (necessário para update/delete)
                  example: 123e4567-e89b-12d3-a456-426614174000
                enabled:
                  type: boolean
                  description: Habilita/desabilita o webhook
                  example: true
                url:
                  type: string
                  description: URL para receber os eventos
                  example: https://example.com/webhook
                events:
                  type: array
                  description: Lista de eventos monitorados
                  items:
                    type: string
                    enum:
                      - connection
                      - history
                      - messages
                      - messages_update
                      - newsletter_messages
                      - call
                      - contacts
                      - presence
                      - groups
                      - labels
                      - chats
                      - chat_labels
                      - blocks
                      - sender
                excludeMessages:
                  type: array
                  description: Filtros para excluir tipos de mensagens
                  items:
                    type: string
                    enum:
                      - wasSentByApi
                      - wasNotSentByApi
                      - fromMeYes
                      - fromMeNo
                      - isGroupYes
                      - isGroupNo
                addUrlEvents:
                  type: boolean
                  description: |
                    Adiciona o tipo do evento como parâmetro na URL.
                    - `false` (padrão): URL normal
                    - `true`: Adiciona evento na URL (ex: `/webhook/message`)
                  default: false
                addUrlTypesMessages:
                  type: boolean
                  description: |
                    Adiciona o tipo da mensagem como parâmetro na URL.
                    - `false` (padrão): URL normal  
                    - `true`: Adiciona tipo da mensagem (ex: `/webhook/conversation`)
                  default: false
                action:
                  type: string
                  description: |
                    Ação a ser executada:
                    - add: criar novo webhook
                    - update: atualizar webhook existente (requer id)
                    - delete: remover webhook (requer apenas id)
                    Se não informado, opera no modo simples (único webhook)
                  enum:
                    - add
                    - update
                    - delete
              required:
                - url
            examples:
              modo_simples:
                summary: Exemplo Modo Simples (Recomendado)
                description: Configuração básica sem complexidade
                value:
                  enabled: true
                  url: https://webhook.cool/example
                  events:
                    - messages
                    - newsletter_messages
                    - connection
                  excludeMessages:
                    - wasSentByApi
              modo_avancado_criar:
                summary: Modo Avançado - Criar Webhook
                description: Criar novo webhook com ID automático
                value:
                  action: add
                  enabled: true
                  url: https://api.exemplo.com/webhook
                  events:
                    - messages
                    - groups
                  excludeMessages:
                    - wasSentByApi
              modo_simples_com_urls:
                summary: Modo Simples com URLs Dinâmicas
                description: Alternativa ao modo avançado usando addUrlEvents
                value:
                  enabled: true
                  url: https://webhook.cool/api
                  events:
                    - messages
                    - connection
                    - groups
                  excludeMessages:
                    - wasSentByApi
                  addUrlEvents: true
      responses:
        '200':
          description: Webhook configurado ou atualizado com sucesso
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: ../schemas/webhook.yaml#/Webhook
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid action
        '401':
          description: Token inválido ou não fornecido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: missing token
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Could not save webhook
  /webhook/errors:
    get:
      operationId: getWebhookErrors
      tags:
        - Webhooks e SSE
      summary: Ver últimos erros do webhook local
      description: |
        Retorna em memória os últimos 20 erros de envio dos webhooks locais da instância autenticada.

        Cada item inclui data/hora (`created`), URL de destino, evento, tipo do webhook
        (`local`), payload tentado, número de tentativas, status HTTP final quando existir e a mensagem de erro.

        Observações:
        - O histórico fica apenas em memória e é perdido quando o processo reinicia.
        - O endpoint usa o mesmo `token` da instância.
        - Retorna apenas falhas dos webhooks locais da própria instância.
        - Falhas do webhook global ficam disponíveis separadamente em `/globalwebhook/errors` com `admintoken`.
        - O header `X-Webhook-Error-Capture-Started-At` informa desde quando a captura atual está valendo.

        Exemplo de consulta:
        ```bash
        curl -X GET "$BASE_URL/webhook/errors" \
          -H "token: SUA_INSTANCIA_TOKEN"
        ```
      responses:
        '200':
          description: Histórico retornado com sucesso
          headers:
            X-Webhook-Error-Capture-Started-At:
              description: Data/hora em que a captura atual de erros começou para a instância
              schema:
                type: string
                format: date-time
                example: '2026-03-23T14:50:00Z'
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    created:
                      type: string
                      format: date-time
                      example: '2026-03-23T15:04:05Z'
                    url:
                      type: string
                      example: https://example.com/webhook/messages
                    type:
                      type: string
                      example: local
                    event:
                      type: string
                      example: messages
                    message_type:
                      type: string
                      example: text
                    status_code:
                      type: integer
                      example: 502
                    attempts:
                      type: integer
                      example: 3
                    error:
                      type: string
                      example: 'webhook returned non-success status: 502 Bad Gateway'
                    payload:
                      type: object
              example:
                - created: '2026-03-23T15:04:05Z'
                  url: https://example.com/webhook/messages
                  type: local
                  event: messages
                  message_type: text
                  status_code: 502
                  attempts: 3
                  error: 'webhook returned non-success status: 502 Bad Gateway'
                  payload:
                    EventType: messages
                    token: instance-token
        '401':
          description: Token inválido ou não fornecido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: missing token
  /globalwebhook:
    get:
      operationId: getGlobalWebhook
      tags:
        - Admininstração
      summary: Ver Webhook Global
      security:
        - admintoken: []
      description: |
        Retorna a configuração atual do webhook global, incluindo:
        - URL configurada
        - Eventos ativos
        - Filtros aplicados
        - Configurações adicionais

        Exemplo de resposta:
        ```json
        {
          "enabled": true,
          "url": "https://example.com/webhook",
          "events": ["messages", "messages_update"],
          "excludeMessages": ["wasSentByApi", "isGroupNo"],
          "addUrlEvents": true,
          "addUrlTypesMessages": true
        }
        ```
      responses:
        '200':
          description: Configuração atual do webhook global
          content:
            application/json:
              schema:
                $ref: ../schemas/webhook.yaml#/Webhook
        '401':
          description: Token de administrador não fornecido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unauthorized
        '403':
          description: Token de administrador inválido ou servidor demo
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: This is a public demo server. This endpoint has been disabled.
        '404':
          description: Webhook global não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Global webhook not found
    post:
      operationId: updateGlobalWebhook
      tags:
        - Admininstração
      summary: Configurar Webhook Global
      security:
        - admintoken: []
      description: >
        Configura um webhook global que receberá eventos de todas as instâncias.


        ### 🚀 Configuração Simples (Recomendada)


        **Para a maioria dos casos de uso**:

        - Configure apenas URL e eventos desejados

        - Modo simples por padrão (sem complexidade)

        - **Recomendado**: Sempre use `"excludeMessages": ["wasSentByApi"]` para evitar loops

        - **Exemplo**: `{"url": "https://webhook.cool/global", "events": ["messages", "connection"], "excludeMessages":
        ["wasSentByApi"]}`


        ### 🧪 Sites para Testes (ordenados por qualidade)


        **Para testar webhooks durante desenvolvimento**:

        1. **https://webhook.cool/** - ⭐ Melhor opção (sem rate limit, interface limpa)

        2. **https://rbaskets.in/** - ⭐ Boa alternativa (confiável, baixo rate limit)

        3. **https://webhook.site/** - ⚠️ Evitar se possível (rate limit agressivo)


        ### Funcionalidades Principais:

        - Configuração de URL para recebimento de eventos

        - Seleção granular de tipos de eventos

        - Filtragem avançada de mensagens

        - Parâmetros adicionais na URL


        **Eventos Disponíveis**:

        - `connection`: Alterações no estado da conexão

        - `history`: Recebimento de histórico de mensagens

        - `messages`: Novas mensagens recebidas

        - `messages_update`: Atualizações em mensagens existentes

        - `call`: Eventos de chamadas VoIP

        - `contacts`: Atualizações na agenda de contatos

        - `presence`: Alterações no status de presença

        - `groups`: Modificações em grupos

        - `labels`: Gerenciamento de etiquetas

        - `chats`: Eventos de conversas

        - `chat_labels`: Alterações em etiquetas de conversas

        - `blocks`: Bloqueios/desbloqueios

        - `sender`: Atualizações de campanhas, quando inicia, e quando completa


        **Remover mensagens com base nos filtros**:

        - `wasSentByApi`: Mensagens originadas pela API ⚠️ **IMPORTANTE:** Use sempre este filtro para evitar loops em
        automações

        - `wasNotSentByApi`: Mensagens não originadas pela API

        - `fromMeYes`: Mensagens enviadas pelo usuário

        - `fromMeNo`: Mensagens recebidas de terceiros

        - `isGroupYes`: Mensagens em grupos

        - `isGroupNo`: Mensagens em conversas individuais


        💡 **Prevenção de Loops Globais**: O webhook global recebe eventos de TODAS as instâncias. Se você tem
        automações que enviam mensagens via API, sempre inclua `"excludeMessages": ["wasSentByApi"]`. Caso prefira
        receber esses eventos, certifique-se de que sua automação detecta mensagens enviadas pela própria API para não
        criar loops infinitos em múltiplas instâncias.


        **Parâmetros de URL**:

        - `addUrlEvents` (boolean): Quando ativo, adiciona o tipo do evento como path parameter na URL.
          Exemplo: `https://api.example.com/webhook/{evento}`
        - `addUrlTypesMessages` (boolean): Quando ativo, adiciona o tipo da mensagem como path parameter na URL.
          Exemplo: `https://api.example.com/webhook/{tipo_mensagem}`

        **Combinações de Parâmetros**:

        - Ambos ativos: `https://api.example.com/webhook/{evento}/{tipo_mensagem}`
          Exemplo real: `https://api.example.com/webhook/message/conversation`
        - Apenas eventos: `https://api.example.com/webhook/message`

        - Apenas tipos: `https://api.example.com/webhook/conversation`


        **Notas Técnicas**:

        1. Os parâmetros são adicionados na ordem: evento → tipo mensagem

        2. A URL deve ser configurada para aceitar esses parâmetros dinâmicos

        3. Funciona com qualquer combinação de eventos/mensagens
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  format: uri
                  description: URL para receber os eventos
                  example: https://webhook.cool/global
                events:
                  type: array
                  description: Lista de eventos monitorados
                  items:
                    type: string
                    enum:
                      - connection
                      - history
                      - messages
                      - messages_update
                      - newsletter_messages
                      - call
                      - contacts
                      - presence
                      - groups
                      - labels
                      - chats
                      - chat_labels
                      - blocks
                      - sender
                  example:
                    - messages
                    - connection
                excludeMessages:
                  type: array
                  description: Filtros para excluir tipos de mensagens
                  items:
                    type: string
                    enum:
                      - wasSentByApi
                      - wasNotSentByApi
                      - fromMeYes
                      - fromMeNo
                      - isGroupYes
                      - isGroupNo
                  example:
                    - wasSentByApi
                addUrlEvents:
                  type: boolean
                  description: |
                    Adiciona o tipo do evento como parâmetro na URL.
                    - `false` (padrão): URL normal
                    - `true`: Adiciona evento na URL (ex: `/webhook/message`)
                  default: false
                addUrlTypesMessages:
                  type: boolean
                  description: |
                    Adiciona o tipo da mensagem como parâmetro na URL.
                    - `false` (padrão): URL normal  
                    - `true`: Adiciona tipo da mensagem (ex: `/webhook/conversation`)
                  default: false
              required:
                - url
                - events
            examples:
              configuracao_simples:
                summary: Configuração Simples (Recomendada)
                description: Configuração básica sem complexidade
                value:
                  url: https://webhook.cool/global
                  events:
                    - messages
                    - connection
                  excludeMessages:
                    - wasSentByApi
              configuracao_completa:
                summary: Configuração Completa
                description: Exemplo com todos os recursos
                value:
                  url: https://webhook.cool/api
                  events:
                    - messages
                    - connection
                    - groups
                    - chats
                  excludeMessages:
                    - wasSentByApi
                    - isGroupNo
                  addUrlEvents: true
      responses:
        '200':
          description: Webhook global configurado com sucesso
          content:
            application/json:
              schema:
                $ref: ../schemas/webhook.yaml#/Webhook
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid payload
        '401':
          description: Token de administrador não fornecido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unauthorized
        '403':
          description: Token de administrador inválido ou servidor demo
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: This is a public demo server. This endpoint has been disabled.
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to save global webhook to database
  /globalwebhook/errors:
    get:
      operationId: getGlobalWebhookErrors
      tags:
        - Admininstração
      summary: Ver últimos erros do webhook global
      security:
        - admintoken: []
      description: |
        Retorna em memória os últimos 20 erros de entrega do webhook global.

        Cada item inclui data/hora (`created`), URL de destino, evento, tipo do webhook
        (`global`), payload tentado, número de tentativas, status HTTP final quando existir e a mensagem de erro.

        Observações:
        - O histórico fica apenas em memória e é perdido quando o processo reinicia.
        - O endpoint exige `admintoken`.
        - Útil para diagnosticar falhas do webhook global sem expor esses dados aos tokens das instâncias.
        - O header `X-Webhook-Error-Capture-Started-At` informa desde quando a captura atual está valendo.

        Exemplo de consulta:
        ```bash
        curl -X GET "$BASE_URL/globalwebhook/errors" \
          -H "admintoken: SEU_ADMIN_TOKEN"
        ```
      responses:
        '200':
          description: Histórico global retornado com sucesso
          headers:
            X-Webhook-Error-Capture-Started-At:
              description: Data/hora em que a captura atual de erros globais começou
              schema:
                type: string
                format: date-time
                example: '2026-03-23T14:50:00Z'
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    created:
                      type: string
                      format: date-time
                      example: '2026-03-23T15:04:05Z'
                    url:
                      type: string
                      example: https://example.com/webhook/messages
                    type:
                      type: string
                      example: global
                    event:
                      type: string
                      example: messages
                    message_type:
                      type: string
                      example: text
                    status_code:
                      type: integer
                      example: 502
                    attempts:
                      type: integer
                      example: 3
                    error:
                      type: string
                      example: 'webhook returned non-success status: 502 Bad Gateway'
                    payload:
                      type: object
              example:
                - created: '2026-03-23T15:08:00Z'
                  url: https://example.com/global/messages
                  type: global
                  event: messages
                  message_type: text
                  status_code: 502
                  attempts: 3
                  error: 'webhook returned non-success status: 502 Bad Gateway'
                  payload:
                    EventType: messages
                    token: instance-token
        '401':
          description: Token de administrador não fornecido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unauthorized
        '403':
          description: Token de administrador inválido ou servidor demo
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: This is a public demo server. This endpoint has been disabled.
  /sse:
    get:
      operationId: subscribeSSE
      tags:
        - Webhooks e SSE
      summary: Server-Sent Events (SSE)
      description: |-
        Receber eventos em tempo real via Server-Sent Events (SSE)

        ### Funcionalidades Principais:
        - Configuração de URL para recebimento de eventos
        - Seleção granular de tipos de eventos
        - Filtragem avançada de mensagens
        - Parâmetros adicionais na URL
        - Gerenciamento múltiplo de webhooks

        **Eventos Disponíveis**:
        - `connection`: Alterações no estado da conexão
        - `history`: Recebimento de histórico de mensagens
        - `messages`: Novas mensagens recebidas
        - `messages_update`: Atualizações em mensagens existentes
        - `call`: Eventos de chamadas VoIP
        - `contacts`: Atualizações na agenda de contatos
        - `presence`: Alterações no status de presença
        - `groups`: Modificações em grupos
        - `labels`: Gerenciamento de etiquetas
        - `chats`: Eventos de conversas
        - `chat_labels`: Alterações em etiquetas de conversas
        - `blocks`: Bloqueios/desbloqueios


        Estabelece uma conexão persistente para receber eventos em tempo real. Este
        endpoint:

        1. Requer autenticação via token

        2. Mantém uma conexão HTTP aberta com o cliente

        3. Envia eventos conforme ocorrem no servidor

        4. Suporta diferentes tipos de eventos

        Exemplo de uso:

        ```javascript

        const eventSource = new
        EventSource('/sse?token=SEU_TOKEN&events=chats,messages');


        eventSource.onmessage = function(event) {
          const data = JSON.parse(event.data);
          console.log('Novo evento:', data);
        };


        eventSource.onerror = function(error) {
          console.error('Erro na conexão SSE:', error);
        };

        ```


        Estrutura de um evento:

        ```json

        {
          "type": "message",
          "data": {
            "id": "3EB0538DA65A59F6D8A251",
            "from": "5511999999999@s.whatsapp.net",
            "to": "5511888888888@s.whatsapp.net",
            "text": "Olá!",
            "timestamp": 1672531200000
          }
        }

        ```
      security: []
      parameters:
        - name: token
          in: query
          schema:
            type: string
          required: true
          description: Token de autenticação da instância
          example: '{{token}}'
        - name: events
          in: query
          schema:
            type: string
          required: true
          description: |
            Tipos de eventos a serem recebidos. Suporta dois formatos:
            - Separados por vírgula: `?events=chats,messages`
            - Parâmetros repetidos: `?events=chats&events=messages`
          example: chats,messages
        - name: excludeMessages
          in: query
          schema:
            type: string
          required: false
          description: |
            Tipos de mensagens a serem excluídas do evento `messages`. Suporta dois formatos:
            - Separados por vírgula: `?excludeMessages=poll,reaction`
            - Parâmetros repetidos: `?excludeMessages=poll&excludeMessages=reaction`
          example: poll,reaction
  /sender/simple:
    post:
      operationId: sendSimpleCampaign
      tags:
        - Mensagem em massa
      summary: Criar nova campanha (Simples)
      description: Cria uma nova campanha de envio com configurações básicas
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - numbers
                - type
                - delayMin
                - delayMax
                - scheduled_for
              properties:
                numbers:
                  type: array
                  description: Lista de números para envio
                  items:
                    type: string
                  example:
                    - 5511999999999@s.whatsapp.net
                type:
                  type: string
                  description: Tipo da mensagem
                  enum:
                    - text
                    - image
                    - video
                    - videoplay
                    - audio
                    - document
                    - contact
                    - location
                    - list
                    - button
                    - poll
                    - carousel
                folder:
                  type: string
                  description: Nome da campanha de envio
                  example: Campanha Janeiro
                delayMin:
                  type: integer
                  description: Delay mínimo entre mensagens em segundos
                  minimum: 1
                  example: 10
                delayMax:
                  type: integer
                  description: Delay máximo entre mensagens em segundos
                  minimum: 1
                  example: 30
                scheduled_for:
                  type: integer
                  description: Timestamp em milissegundos ou minutos a partir de agora para agendamento
                  example: 1706198400000
                info:
                  type: string
                  description: Informações adicionais sobre a campanha
                delay:
                  type: integer
                  description: Delay fixo entre mensagens (opcional)
                mentions:
                  type: string
                  description: Menções na mensagem em formato JSON
                text:
                  type: string
                  description: Texto da mensagem
                linkPreview:
                  type: boolean
                  description: >-
                    Habilitar preview de links em mensagens de texto. O preview será gerado automaticamente a partir da
                    URL contida no texto.
                linkPreviewTitle:
                  type: string
                  description: Título personalizado para o preview do link (opcional)
                linkPreviewDescription:
                  type: string
                  description: Descrição personalizada para o preview do link (opcional)
                linkPreviewImage:
                  type: string
                  description: URL ou dados base64 da imagem para o preview do link (opcional)
                linkPreviewLarge:
                  type: boolean
                  description: Se deve usar preview grande ou pequeno (opcional, padrão false)
                file:
                  type: string
                  description: URL da mídia ou arquivo (quando type é image, video, audio, document, etc.)
                docName:
                  type: string
                  description: Nome do arquivo (quando type é document)
                fullName:
                  type: string
                  description: Nome completo (quando type é contact)
                phoneNumber:
                  type: string
                  description: Número do telefone (quando type é contact)
                organization:
                  type: string
                  description: Organização (quando type é contact)
                email:
                  type: string
                  description: Email (quando type é contact)
                url:
                  type: string
                  description: URL (quando type é contact)
                latitude:
                  type: number
                  description: Latitude (quando type é location)
                longitude:
                  type: number
                  description: Longitude (quando type é location)
                name:
                  type: string
                  description: Nome do local (quando type é location)
                address:
                  type: string
                  description: Endereço (quando type é location)
                footerText:
                  type: string
                  description: Texto do rodapé (quando type é list, button, poll ou carousel)
                buttonText:
                  type: string
                  description: Texto do botão (quando type é list, button, poll ou carousel)
                listButton:
                  type: string
                  description: Texto do botão da lista (quando type é list)
                selectableCount:
                  type: integer
                  description: Quantidade de opções selecionáveis (quando type é poll)
                choices:
                  type: array
                  items:
                    type: string
                  description: >-
                    Lista de opções (quando type é list, button, poll ou carousel). Para carousel, use formato
                    específico com [texto], {imagem} e botões
                imageButton:
                  type: string
                  description: URL da imagem para o botão (quando type é button)
      responses:
        '200':
          description: campanha criada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  folder_id:
                    type: string
                    description: ID único da campanha criada
                  count:
                    type: integer
                    description: Quantidade de mensagens agendadas
                  status:
                    type: string
                    description: Status da operação
                    example: queued
        '400':
          description: Erro nos parâmetros da requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        '401':
          description: Erro de autenticação
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        '409':
          description: Conflito - campanha já existe
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
  /sender/advanced:
    post:
      operationId: sendAdvancedCampaign
      tags:
        - Mensagem em massa
      summary: Criar envio em massa avançado
      description: |
        Cria um novo envio em massa com configurações avançadas, permitindo definir
        múltiplos destinatários e mensagens com delays personalizados.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                delayMin:
                  type: integer
                  description: Delay mínimo entre mensagens (segundos)
                  minimum: 0
                  example: 3
                delayMax:
                  type: integer
                  description: Delay máximo entre mensagens (segundos)
                  minimum: 0
                  example: 6
                info:
                  type: string
                  description: Descrição ou informação sobre o envio em massa
                  example: Campanha de lançamento
                scheduled_for:
                  type: integer
                  description: Timestamp em milissegundos (date unix) ou minutos a partir de agora para agendamento
                  example: 1
                messages:
                  type: array
                  description: Lista de mensagens a serem enviadas
                  items:
                    type: object
                    required:
                      - number
                      - type
                    properties:
                      number:
                        type: string
                        description: ID do chat ou número do destinatário.
                        example: '5511999999999'
                      type:
                        type: string
                        enum:
                          - text
                          - image
                          - document
                          - audio
                          - ptt
                          - myaudio
                          - sticker
                          - video
                          - videoplay
                          - contact
                          - location
                          - poll
                          - list
                          - button
                          - carousel
                        description: |
                          Tipo da mensagem:
                          - text: Mensagem de texto
                          - image: Imagem
                          - document: Documento/arquivo
                          - audio: Áudio
                          - ptt: Mensagem de voz
                          - myaudio: Áudio (opção alternativa)
                          - sticker: Figurinha
                          - video: Vídeo
                          - videoplay: Vídeo com autoplay/loop no WhatsApp
                          - contact: Contato
                          - location: Localização
                          - poll: Enquete
                          - list: Lista de opções
                          - button: Botões interativos
                          - carousel: Carrossel de cartões com imagens e botões
                      text:
                        type: string
                        description: Texto da mensagem (quando type é "text") ou legenda para mídia
                      file:
                        type: string
                        description: URL da mídia (quando type é image, video, audio, document, etc)
                      docName:
                        type: string
                        description: Nome do arquivo (quando type é document)
                      linkPreview:
                        type: boolean
                        description: >-
                          Se deve gerar preview de links (quando type é text). O preview será gerado automaticamente a
                          partir da URL contida no texto.
                      linkPreviewTitle:
                        type: string
                        description: Título personalizado para o preview do link (opcional)
                      linkPreviewDescription:
                        type: string
                        description: Descrição personalizada para o preview do link (opcional)
                      linkPreviewImage:
                        type: string
                        description: URL ou dados base64 da imagem para o preview do link (opcional)
                      linkPreviewLarge:
                        type: boolean
                        description: Se deve usar preview grande ou pequeno (opcional, padrão false)
                      fullName:
                        type: string
                        description: Nome completo (quando type é contact)
                      phoneNumber:
                        type: string
                        description: Número do telefone (quando type é contact)
                      organization:
                        type: string
                        description: Organização (quando type é contact)
                      email:
                        type: string
                        description: Email (quando type é contact)
                      url:
                        type: string
                        description: URL (quando type é contact)
                      latitude:
                        type: number
                        description: Latitude (quando type é location)
                      longitude:
                        type: number
                        description: Longitude (quando type é location)
                      name:
                        type: string
                        description: Nome do local (quando type é location)
                      address:
                        type: string
                        description: Endereço (quando type é location)
                      footerText:
                        type: string
                        description: Texto do rodapé (quando type é list, button, poll ou carousel)
                      buttonText:
                        type: string
                        description: Texto do botão (quando type é list, button, poll ou carousel)
                      listButton:
                        type: string
                        description: Texto do botão da lista (quando type é list)
                      selectableCount:
                        type: integer
                        description: Quantidade de opções selecionáveis (quando type é poll)
                      choices:
                        type: array
                        items:
                          type: string
                        description: >-
                          Lista de opções (quando type é list, button, poll ou carousel). Para carousel, use formato
                          específico com [texto], {imagem} e botões
                      imageButton:
                        type: string
                        description: URL da imagem para o botão (quando type é button)
              required:
                - messages
              example:
                delayMin: 3
                delayMax: 6
                info: teste avançado
                scheduled_for: 1
                messages:
                  - number: '5511999999999'
                    type: text
                    text: First message
                  - number: '5511999999999'
                    type: button
                    text: |-
                      Promoção Especial!
                      Confira nossas ofertas incríveis
                    footerText: Válido até 31/12/2024
                    imageButton: https://exemplo.com/banner-promocao.jpg
                    choices:
                      - Ver Ofertas|https://loja.exemplo.com/ofertas
                      - Falar com Vendedor|reply:vendedor
                      - Copiar Cupom|copy:PROMO2024
                  - number: '5511999999999'
                    type: list
                    text: 'Escolha sua categoria preferida:'
                    listButton: Ver Categorias
                    choices:
                      - '[Eletrônicos]'
                      - Smartphones|eletronicos_smartphones
                      - Notebooks|eletronicos_notebooks
                      - '[Roupas]'
                      - Camisetas|roupas_camisetas
                      - Sapatos|roupas_sapatos
                  - number: '5511999999999'
                    type: document
                    file: https://example.com/doc.pdf
                    docName: Documento.pdf
                  - number: '5511999999999'
                    type: carousel
                    text: Conheça nossos produtos
                    choices:
                      - |-
                        [Smartphone XYZ
                        O mais avançado smartphone da linha]
                      - '{https://exemplo.com/produto1.jpg}'
                      - Copiar Código|copy:PROD123
                      - Ver no Site|https://exemplo.com/xyz
                      - |-
                        [Notebook ABC
                        O notebook ideal para profissionais]
                      - '{https://exemplo.com/produto2.jpg}'
                      - Copiar Código|copy:NOTE456
                      - Comprar Online|https://exemplo.com/abc
      responses:
        '200':
          description: Mensagens adicionadas à fila com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  folder_id:
                    type: string
                    description: ID da pasta/lote criado
                  count:
                    type: integer
                    description: Total de mensagens adicionadas à fila
                  status:
                    type: string
                    description: Status da operação
                    example: queued
        '400':
          description: Erro nos parâmetros da requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro
                    example: Formato de número inválido
        '401':
          description: Não autorizado - token inválido ou ausente
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro
                    example: Token inválido ou ausente
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Detalhes do erro interno
  /sender/edit:
    post:
      operationId: editCampaign
      tags:
        - Mensagem em massa
      summary: Controlar campanha de envio em massa
      description: |
        Permite controlar campanhas de envio de mensagens em massa através de diferentes ações:

        ## Ações Disponíveis:

        **🛑 stop** - Pausar campanha
        - Pausa uma campanha ativa ou agendada
        - Altera o status para "paused" 
        - Use quando quiser interromper temporariamente o envio
        - Mensagens já enviadas não são afetadas

        **▶️ continue** - Continuar campanha  
        - Retoma uma campanha pausada
        - Altera o status para "scheduled"
        - Use para continuar o envio após pausar uma campanha
        - Não funciona em campanhas já concluídas ("done")

        **🗑️ delete** - Deletar campanha
        - Remove completamente a campanha
        - Deleta apenas mensagens NÃO ENVIADAS (status "scheduled")
        - Mensagens já enviadas são preservadas no histórico
        - Operação é executada de forma assíncrona

        ## Status de Campanhas:
        - **scheduled**: Agendada para envio
        - **sending**: Enviando mensagens  
        - **paused**: Pausada pelo usuário
        - **done**: Concluída (não pode ser alterada)
        - **deleting**: Sendo deletada (operação em andamento)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                folder_id:
                  type: string
                  description: Identificador único da campanha de envio
                  example: folder_123
                action:
                  type: string
                  enum:
                    - stop
                    - continue
                    - delete
                  description: |
                    Ação a ser executada na campanha:
                    - **stop**: Pausa a campanha (muda para status "paused")
                    - **continue**: Retoma campanha pausada (muda para status "scheduled") 
                    - **delete**: Remove campanha e mensagens não enviadas (assíncrono)
                  example: stop
              required:
                - folder_id
                - action
      responses:
        '200':
          description: Ação realizada com sucesso
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    title: Resposta para ação 'stop'
                    properties:
                      status:
                        type: string
                        enum:
                          - paused
                        description: Status da campanha após pausar
                        example: paused
                  - type: object
                    title: Resposta para ação 'continue'
                    properties:
                      status:
                        type: string
                        enum:
                          - scheduled
                        description: Status da campanha após retomar
                        example: scheduled
                      message:
                        type: string
                        description: Mensagem de confirmação
                        example: Folder resumed successfully
                  - type: object
                    title: Resposta para ação 'delete'
                    properties:
                      status:
                        type: string
                        enum:
                          - deleting
                        description: Status indicando que a deleção foi iniciada
                        example: deleting
                      message:
                        type: string
                        description: Mensagem informando que a deleção é assíncrona
                        example: Folder deletion has been initiated
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: folder_id is required
  /sender/cleardone:
    post:
      operationId: clearDoneCampaigns
      tags:
        - Mensagem em massa
      summary: Limpar mensagens enviadas
      description: >-
        Inicia processo de limpeza de mensagens antigas em lote que já foram enviadas com sucesso. Por padrão, remove
        mensagens mais antigas que 7 dias.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                hours:
                  type: integer
                  description: Quantidade de horas para manter mensagens. Mensagens mais antigas que esse valor serão removidas.
                  example: 168
                  default: 168
      responses:
        '200':
          description: Limpeza iniciada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: Status da operação
                    example: cleanup started
  /sender/clearall:
    delete:
      operationId: clearAllCampaigns
      tags:
        - Mensagem em massa
      summary: Limpar toda fila de mensagens
      description: |
        Remove todas as mensagens da fila de envio em massa, incluindo mensagens pendentes e já enviadas.
        Esta é uma operação irreversível.
      responses:
        '200':
          description: Fila de mensagens limpa com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: Status da operação
                    example: processed
                  messages_deleted:
                    type: integer
                    description: Quantidade de mensagens deletadas
                    example: 150
                  folders_deleted:
                    type: integer
                    description: Quantidade de pastas deletadas
                    example: 3
        '401':
          description: Não autorizado - token inválido ou ausente
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro
                    example: Token inválido ou ausente
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Detalhes do erro interno
  /sender/listfolders:
    get:
      operationId: listCampaignFolders
      tags:
        - Mensagem em massa
      summary: Listar campanhas de envio
      description: |
        Retorna as campanhas de envio em massa da instância atual, ordenadas das mais recentes
        para as mais antigas.

        Se a instância não possuir owner associado, a API retorna uma lista vazia.
      parameters:
        - in: query
          name: status
          schema:
            type: string
            enum:
              - Active
              - Archived
          description: |
            Filtro de status desejado. O backend atual retorna todas as pastas do owner e
            pode ignorar esse parâmetro dependendo da implementação da fila.
      responses:
        '200':
          description: Lista de campanhas retornada com sucesso
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: ../schemas/message_queue_folder.yaml#/MessageQueueFolder
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: 'Failed to fetch batches: database error'
  /sender/listmessages:
    post:
      operationId: listCampaignMessages
      tags:
        - Mensagem em massa
      summary: Listar mensagens de uma campanha
      description: Retorna a lista de mensagens de uma campanha específica, com opções de filtro por status e paginação
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                folder_id:
                  type: string
                  description: ID da campanha a ser consultada
                messageStatus:
                  type: string
                  enum:
                    - Scheduled
                    - Sent
                    - Failed
                  description: Status das mensagens para filtrar
                limit:
                  type: integer
                  minimum: 1
                  maximum: 1000
                  default: 1000
                  description: Quantidade maxima de itens por pagina
                offset:
                  type: integer
                  minimum: 0
                  default: 0
                  description: Deslocamento base zero para paginacao
              required:
                - folder_id
      responses:
        '200':
          description: Lista de mensagens retornada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  messages:
                    type: array
                    items:
                      $ref: ../schemas/message.yaml#/Message
                  pagination:
                    type: object
                    properties:
                      totalRecords:
                        type: integer
                        description: Total de mensagens encontradas
                      limit:
                        type: integer
                        description: Limite aplicado na pagina atual
                      offset:
                        type: integer
                        description: Offset efetivamente usado na pagina atual
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: folder_id is required
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to fetch messages
  /chat/block:
    post:
      operationId: blockChat
      summary: Bloqueia ou desbloqueia contato do WhatsApp
      description: |
        Bloqueia ou desbloqueia um contato do WhatsApp. Contatos bloqueados não podem enviar mensagens 
        para a instância e a instância não pode enviar mensagens para eles.
      tags:
        - Bloqueios
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: Número do WhatsApp no formato internacional (ex. 5511999999999)
                  example: '5511999999999'
                block:
                  type: boolean
                  description: True para bloquear, False para desbloquear
                  example: true
              required:
                - number
                - block
      responses:
        '200':
          description: Operação realizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    description: Mensagem de confirmação
                    example: Blocked successfully
                  blockList:
                    type: array
                    description: Lista atualizada de contatos bloqueados
                    items:
                      type: string
                    example:
                      - 5511999999999@s.whatsapp.net
                      - 5511888888888@s.whatsapp.net
        '401':
          description: Não autorizado - token inválido
        '404':
          description: Contato não encontrado
        '500':
          description: Erro do servidor ao processar a requisição
  /chat/blocklist:
    get:
      operationId: getBlocklist
      summary: Lista contatos bloqueados
      description: |
        Retorna a lista completa de contatos que foram bloqueados pela instância.
        Esta lista é atualizada em tempo real conforme contatos são bloqueados/desbloqueados.
      tags:
        - Bloqueios
      responses:
        '200':
          description: Lista de contatos bloqueados recuperada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  blockList:
                    type: array
                    items:
                      type: string
                      description: JIDs dos contatos bloqueados no formato "número@s.whatsapp.net"
                    example:
                      - 5511999999999@s.whatsapp.net
                      - 5511888888888@s.whatsapp.net
        '401':
          description: Token inválido ou não fornecido
        '500':
          description: Erro interno do servidor ou instância não conectada
  /chat/labels:
    post:
      operationId: setChatLabels
      summary: Gerencia labels de um chat
      description: >
        Atualiza as labels associadas a um chat específico. Este endpoint oferece três modos de operação:


        1. **Definir todas as labels** (labelids): Define o conjunto completo de labels para o chat, substituindo labels
        existentes

        2. **Adicionar uma label** (add_labelid): Adiciona uma única label ao chat sem afetar as existentes

        3. **Remover uma label** (remove_labelid): Remove uma única label do chat sem afetar as outras


        **Importante**: Use apenas um dos três parâmetros por requisição. Labels inexistentes serão rejeitadas.


        As labels devem ser fornecidas no formato id ou labelid encontradas na função get labels.
      tags:
        - Etiquetas
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: Número do chat ou grupo
                  example: '5511999999999'
                labelids:
                  type: array
                  items:
                    type: string
                  description: Lista de IDs das labels a serem aplicadas ao chat (define todas as labels)
                  example:
                    - '10'
                    - '20'
                add_labelid:
                  type: string
                  description: ID da label a ser adicionada ao chat
                  example: '10'
                remove_labelid:
                  type: string
                  description: ID da label a ser removida do chat
                  example: '20'
              required:
                - number
              oneOf:
                - required:
                    - labelids
                - required:
                    - add_labelid
                - required:
                    - remove_labelid
            examples:
              definir_todas_labels:
                summary: Definir todas as labels do chat
                description: Define o conjunto completo de labels, substituindo as existentes
                value:
                  number: '5511999999999'
                  labelids:
                    - '10'
                    - '20'
                    - '30'
              adicionar_label:
                summary: Adicionar uma label ao chat
                description: Adiciona uma única label sem afetar as existentes
                value:
                  number: '5511999999999'
                  add_labelid: '10'
              remover_label:
                summary: Remover uma label do chat
                description: Remove uma única label sem afetar as outras
                value:
                  number: '5511999999999'
                  remove_labelid: '20'
      responses:
        '200':
          description: Labels atualizadas com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    description: Mensagem de confirmação
                  editions:
                    type: array
                    items:
                      type: string
                    description: Lista de operações realizadas (apenas para operação labelids)
              examples:
                definir_todas_labels:
                  summary: Resposta para definir todas as labels
                  value:
                    response: Labels updated successfully
                    editions:
                      - Added label 10 to chat
                      - Added label 20 to chat
                      - Removed label 5 from chat
                adicionar_label:
                  summary: Resposta para adicionar uma label
                  value:
                    response: Label added to chat
                remover_label:
                  summary: Resposta para remover uma label
                  value:
                    response: Label removed from chat
        '400':
          description: Erro na requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: 'Use only one operation: labelids, add_labelid, or remove_labelid'
        '404':
          description: Chat não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Chat not found
  /chat/delete:
    post:
      operationId: deleteChat
      summary: Deleta chat
      description: |
        Deleta ou limpa um chat e/ou suas mensagens do WhatsApp e/ou banco de dados.
        Você pode escolher:
        - Deletar o chat do WhatsApp
        - Limpar a conversa no WhatsApp
        - Deletar o chat do banco de dados
        - Deletar apenas as mensagens do banco de dados
        - Qualquer combinação das opções acima
        Observação:
        - Se clearChatWhatsApp e deleteChatWhatsApp forem true, o clear tem prioridade.
      tags:
        - Chats
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: |
                    Número do chat no formato internacional.
                    Para grupos use o ID completo do grupo.
                  example: '5511999999999'
                deleteChatDB:
                  type: boolean
                  description: Se true, deleta o chat do banco de dados
                  default: false
                  example: true
                deleteMessagesDB:
                  type: boolean
                  description: Se true, deleta todas as mensagens do chat do banco de dados
                  default: false
                  example: true
                deleteChatWhatsApp:
                  type: boolean
                  description: |
                    Se true, deleta o chat do WhatsApp.
                    Para grupos, esta operação não é permitida e o chat será apenas limpo.
                  default: false
                  example: true
                clearChatWhatsApp:
                  type: boolean
                  description: |
                    Se true, limpa a conversa do chat no WhatsApp (sem sair do chat).
                    Funciona para grupos e conversas individuais.
                  default: false
                  example: true
              required:
                - number
      responses:
        '200':
          description: Operação realizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    description: Mensagem de sucesso
                    example: Chat deletion process completed
                  actions:
                    type: array
                    description: Lista de ações realizadas
                    items:
                      type: string
                    example:
                      - Chat deleted from WhatsApp
                      - Chat deleted from database
                      - 'Messages associated with chat deleted from database: 42'
                  errors:
                    type: array
                    description: Lista de erros ocorridos, se houver
                    items:
                      type: string
                    example:
                      - 'Error deleting chat from WhatsApp: connection timeout'
        '400':
          description: Erro nos parâmetros da requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Missing number in payload
        '401':
          description: Token inválido ou não fornecido
        '404':
          description: Chat não encontrado
        '500':
          description: Erro interno do servidor
  /chat/archive:
    post:
      operationId: archiveChat
      summary: Arquivar/desarquivar chat
      description: |
        Altera o estado de arquivamento de um chat do WhatsApp.
        - Quando arquivado, o chat é movido para a seção de arquivados no WhatsApp
        - A ação é sincronizada entre todos os dispositivos conectados
        - Não afeta as mensagens ou o conteúdo do chat
      tags:
        - Chats
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - number
                - archive
              properties:
                number:
                  type: string
                  description: Número do telefone (formato E.164) ou ID do grupo
                  example: '5511999999999'
                archive:
                  type: boolean
                  description: true para arquivar, false para desarquivar
                  example: true
      responses:
        '200':
          description: Chat arquivado/desarquivado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Chat updated successfully
        '400':
          description: Dados da requisição inválidos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid phone number format
        '401':
          description: Token de autenticação ausente ou inválido
        '500':
          description: Erro ao executar a operação
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Error archiving chat
  /chat/read:
    post:
      operationId: markChatRead
      summary: Marcar chat como lido/não lido
      description: |
        Atualiza o status de leitura de um chat no WhatsApp.

        Quando um chat é marcado como lido:
        - O contador de mensagens não lidas é zerado
        - O indicador visual de mensagens não lidas é removido
        - O remetente recebe confirmação de leitura (se ativado)

        Quando marcado como não lido:
        - O chat aparece como pendente de leitura
        - Não afeta as confirmações de leitura já enviadas
      tags:
        - Chats
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - number
                - read
              properties:
                number:
                  type: string
                  description: |
                    Identificador do chat no formato:
                    - Para usuários: [número]@s.whatsapp.net (ex: 5511999999999@s.whatsapp.net)
                    - Para grupos: [id-grupo]@g.us (ex: 123456789-987654321@g.us)
                  example: 5511999999999@s.whatsapp.net
                read:
                  type: boolean
                  description: |
                    - true: marca o chat como lido
                    - false: marca o chat como não lido
      responses:
        '200':
          description: Status de leitura atualizado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Chat read status updated successfully
        '401':
          description: Token de autenticação ausente ou inválido
        '404':
          description: Chat não encontrado
        '500':
          description: Erro ao atualizar status de leitura
  /chat/mute:
    post:
      operationId: muteChat
      summary: Silenciar chat
      description: |
        Silencia notificações de um chat por um período específico. 
        As opções de silenciamento são:
        * 0 - Remove o silenciamento
        * 8 - Silencia por 8 horas
        * 168 - Silencia por 1 semana (168 horas)
        * -1 - Silencia permanentemente
      tags:
        - Chats
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - number
                - muteEndTime
              properties:
                number:
                  type: string
                  description: ID do chat no formato 123456789@s.whatsapp.net ou 123456789-123456@g.us
                  example: 5511999999999@s.whatsapp.net
                muteEndTime:
                  type: integer
                  description: |
                    Duração do silenciamento:
                    * 0 = Remove silenciamento
                    * 8 = Silencia por 8 horas
                    * 168 = Silencia por 1 semana
                    * -1 = Silencia permanentemente
                  enum:
                    - 0
                    - 8
                    - 168
                    - -1
                  example: 8
      responses:
        '200':
          description: Chat silenciado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Chat mute settings updated successfully
        '400':
          description: Duração inválida ou formato de número incorreto
        '401':
          description: Token inválido ou ausente
        '404':
          description: Chat não encontrado
  /chat/pin:
    post:
      operationId: pinChat
      summary: Fixar/desafixar chat
      description: |
        Fixa ou desafixa um chat no topo da lista de conversas. Chats fixados permanecem 
        no topo mesmo quando novas mensagens são recebidas em outros chats.
      tags:
        - Chats
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: |
                    Número do chat no formato internacional completo (ex: "5511999999999") 
                    ou ID do grupo (ex: "123456789-123456@g.us")
                  example: '5511999999999'
                pin:
                  type: boolean
                  description: |
                    Define se o chat deve ser fixado (true) ou desafixado (false)
                  example: true
              required:
                - number
                - pin
      responses:
        '200':
          description: Chat fixado/desafixado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    description: Mensagem de confirmação
                    example: Chat pinned
        '400':
          description: Erro na requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro
                    example: Could not parse phone
        '401':
          description: Não autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de autenticação
                    example: Invalid token
  /chat/find:
    post:
      operationId: findChats
      summary: Busca chats com filtros
      description: |
        Busca chats com diversos filtros e ordenação. Suporta filtros em todos os campos do chat, 
        paginação e ordenação customizada.

        Operadores de filtro:
        - `~` : LIKE (contém)
        - `!~` : NOT LIKE (não contém)
        - `!=` : diferente
        - `>=` : maior ou igual
        - `>` : maior que
        - `<=` : menor ou igual
        - `<` : menor que
        - Sem operador: LIKE (contém)
      tags:
        - Chats
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                operator:
                  type: string
                  enum:
                    - AND
                    - OR
                  default: AND
                  description: Operador lógico entre os filtros
                sort:
                  type: string
                  description: Campo para ordenação (+/-campo). Ex -wa_lastMsgTimestamp
                limit:
                  type: integer
                  description: Quantidade máxima de resultados a retornar
                  default: 20
                offset:
                  type: integer
                  description: Número de registros a pular (para paginação)
                  default: 0
                wa_fastid:
                  type: string
                wa_chatid:
                  type: string
                wa_archived:
                  type: boolean
                wa_contactName:
                  type: string
                wa_name:
                  type: string
                name:
                  type: string
                wa_isBlocked:
                  type: boolean
                wa_isGroup:
                  type: boolean
                wa_isGroup_admin:
                  type: boolean
                wa_isGroup_announce:
                  type: boolean
                wa_isGroup_member:
                  type: boolean
                wa_isPinned:
                  type: boolean
                wa_label:
                  type: string
                  description: ID da label aplicada ao chat. Use o valor retornado por `/labels`, não o nome da etiqueta.
                wa_notes:
                  type: string
                lead_tags:
                  type: string
                lead_isTicketOpen:
                  type: boolean
                lead_assignedAttendant_id:
                  type: string
                lead_status:
                  type: string
              example:
                operator: AND
                sort: '-wa_lastMsgTimestamp'
                limit: 50
                offset: 0
                wa_isGroup: true
                lead_status: ~novo
                wa_label: '10'
                wa_notes: ~vip
      responses:
        '200':
          description: Lista de chats encontrados
          content:
            application/json:
              schema:
                type: object
                properties:
                  chats:
                    type: array
                    items:
                      $ref: ../schemas/chat.yaml#/Chat
                  totalChatsStats:
                    type: object
                    description: Contadores totais de chats
                  pagination:
                    type: object
                    properties:
                      totalRecords:
                        type: integer
                        description: Total de registros encontrados
                      limit:
                        type: integer
                        description: Limite aplicado na busca
                      offset:
                        type: integer
                        description: Offset usado para recuperar os resultados
  /chat/notes:
    post:
      operationId: getChatNotes
      tags:
        - Chats
      summary: Consultar notas internas do chat
      description: |
        Retorna `wa_notes` de um chat usando apenas os dados já persistidos localmente.

        Casos de uso:
        - ler a anotação local já persistida no chat
        - consultar notas mesmo durante reconexão da sessão do WhatsApp

        Regras:
        - envie `number`
        - para recarregar do WhatsApp, use `/chat/notes/refresh`
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: JID completo do chat
                  example: 5511999999999@s.whatsapp.net
            examples:
              por_number:
                summary: Consultar nota por number
                value:
                  number: 5511999999999@s.whatsapp.net
      responses:
        '200':
          description: Nota do chat retornada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  chat:
                    $ref: ../schemas/chat.yaml#/Chat
                  wa_notes:
                    type: string
                    description: Conteúdo atual da nota do chat
                    example: Cliente prefere contato no período da tarde
                  source:
                    type: string
                    description: Origem usada para compor a resposta
                    enum:
                      - local
                    example: local
              examples:
                sucesso_local:
                  value:
                    chat:
                      wa_fastid: admin:5511999999999
                      wa_chatid: 5511999999999@s.whatsapp.net
                      wa_notes: Cliente prefere contato no período da tarde
                    wa_notes: Cliente prefere contato no período da tarde
                    source: local
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: number is required
        '404':
          description: Chat não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: chat not found
        '500':
          description: Erro interno ao consultar a nota local
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: failed to load chat notes from local database
  /chat/notes/refresh:
    post:
      operationId: refreshChatNotes
      tags:
        - Chats
      summary: Recarregar notas internas do chat no WhatsApp
      description: |
        Faz uma nova leitura das notas internas do chat no WhatsApp antes de retornar o valor atualizado.

        Uso recomendado:
        - tente primeiro com `force=false`
        - se isso não atualizar a nota corretamente, tente `force=true`
        - use `force=true` apenas como tentativa de correção, porque ele faz uma recarga mais pesada
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: JID completo do chat
                  example: 5511999999999@s.whatsapp.net
                force:
                  type: boolean
                  description: |
                    Tente primeiro com `false`.
                    Use `true` apenas quando a recarga padrão não funcionar bem,
                    pois esse modo faz uma nova leitura mais completa das notas.
                  default: false
                  example: false
            examples:
              recarregar:
                summary: Recarregar no modo padrão
                value:
                  number: 5511999999999@s.whatsapp.net
              reparar_full_sync:
                summary: Recarregar em modo forçado
                value:
                  number: 5511999999999@s.whatsapp.net
                  force: true
      responses:
        '200':
          description: Nota do chat recarregada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  chat:
                    $ref: ../schemas/chat.yaml#/Chat
                  wa_notes:
                    type: string
                    description: Conteúdo atual da nota do chat
                    example: Cliente prefere contato no período da tarde
                  source:
                    type: string
                    description: Origem usada para compor a resposta
                    enum:
                      - appstate_reload
                    example: appstate_reload
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: number is required
        '404':
          description: Chat não encontrado após o reload
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: chat not found
        '409':
          description: O reload não pode ser executado porque o history sync inicial ainda está em andamento
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: history sync still in progress, try again in a moment
        '500':
          description: Erro interno ao recarregar a nota
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: 'failed to fetch regular_low app state: connection closed'
  /chat/notes/edit:
    post:
      operationId: editChatNotes
      tags:
        - Chats
      summary: Editar notas internas do chat
      description: |
        Atualiza `wa_notes` de um chat via app state do WhatsApp e persiste o resultado localmente.

        Regras:
        - envie `number`
        - envie `notes` como campo principal
        - envie string vazia para limpar a nota do chat
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: JID completo do chat
                  example: 5511999999999@s.whatsapp.net
                notes:
                  type: string
                  description: Conteúdo da nota a persistir no chat
                  example: Cliente prefere contato no período da tarde
            examples:
              salvar:
                summary: Salvar nota
                value:
                  number: 5511999999999@s.whatsapp.net
                  notes: Cliente prefere contato no período da tarde
              limpar:
                summary: Limpar nota
                value:
                  number: 5511999999999@s.whatsapp.net
                  notes: ''
      responses:
        '200':
          description: Nota atualizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    example: Chat notes updated
                  chat:
                    $ref: ../schemas/chat.yaml#/Chat
                  wa_notes:
                    type: string
                    description: Conteúdo atual da nota após a atualização
                    example: Cliente prefere contato no período da tarde
                  source:
                    type: string
                    description: Origem da atualização
                    enum:
                      - api
                    example: api
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: notes is required
        '404':
          description: Chat não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: chat not found
        '409':
          description: A edição não pode ser executada porque o history sync inicial ainda está em andamento
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: history sync still in progress, try again in a moment
        '500':
          description: Erro interno ao atualizar a nota
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: 'error editing chat notes: client is not connected'
  /chat/editLead:
    post:
      operationId: editLead
      summary: Edita informações de lead
      description: |
        Atualiza as informações de lead associadas a um chat. Permite modificar status do ticket, 
        atribuição de atendente, posição no kanban, tags e outros campos customizados.

        As alterações são refletidas imediatamente no banco de dados e disparam eventos webhook/SSE
        para manter a aplicação sincronizada.
      tags:
        - CRM
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - id
              properties:
                id:
                  type: string
                  description: |
                    Identificador do chat. Pode ser:
                    - wa_chatid (ex: "5511999999999@s.whatsapp.net")
                    - wa_fastid (ex: "5511888888888:5511999999999")
                  example: 5511999999999@s.whatsapp.net
                chatbot_disableUntil:
                  type: integer
                  format: int64
                  description: |
                    Timestamp UTC até quando o chatbot deve ficar desativado para este chat.
                    Use 0 para reativar imediatamente.
                  example: 1735686000
                lead_isTicketOpen:
                  type: boolean
                  description: |
                    Status do ticket associado ao lead.
                    - true: Ticket está aberto/em atendimento
                    - false: Ticket está fechado/resolvido
                  example: true
                lead_assignedAttendant_id:
                  type: string
                  description: |
                    ID do atendente atribuído ao lead.
                    Use string vazia ("") para remover a atribuição.
                  example: att_123456
                lead_kanbanOrder:
                  type: integer
                  format: int64
                  description: |
                    Posição do card no quadro kanban.
                    Valores maiores aparecem primeiro.
                  example: 1000
                lead_tags:
                  type: array
                  items:
                    type: string
                  description: |
                    Lista de tags associadas ao lead.
                    Tags inexistentes são criadas automaticamente.
                    Envie array vazio ([]) para remover todas as tags.
                  example:
                    - vip
                    - suporte
                    - prioridade-alta
                lead_name:
                  type: string
                  description: Nome principal do lead
                  example: João Silva
                lead_fullName:
                  type: string
                  description: Nome completo do lead
                  example: João Silva Pereira
                lead_email:
                  type: string
                  format: email
                  description: Email do lead
                  example: joao@exemplo.com
                lead_personalid:
                  type: string
                  description: |
                    Documento de identificação (CPF/CNPJ)
                    Apenas números ou formatado
                  example: 123.456.789-00
                lead_status:
                  type: string
                  description: Status do lead no funil de vendas
                  example: qualificado
                lead_notes:
                  type: string
                  description: Anotações sobre o lead
                  example: Cliente interessado em plano premium
                lead_field01:
                  type: string
                  description: Campo personalizado 1
                lead_field02:
                  type: string
                  description: Campo personalizado 2
                lead_field03:
                  type: string
                  description: Campo personalizado 3
                lead_field04:
                  type: string
                  description: Campo personalizado 4
                lead_field05:
                  type: string
                  description: Campo personalizado 5
                lead_field06:
                  type: string
                  description: Campo personalizado 6
                lead_field07:
                  type: string
                  description: Campo personalizado 7
                lead_field08:
                  type: string
                  description: Campo personalizado 8
                lead_field09:
                  type: string
                  description: Campo personalizado 9
                lead_field10:
                  type: string
                  description: Campo personalizado 10
                lead_field11:
                  type: string
                  description: Campo personalizado 11
                lead_field12:
                  type: string
                  description: Campo personalizado 12
                lead_field13:
                  type: string
                  description: Campo personalizado 13
                lead_field14:
                  type: string
                  description: Campo personalizado 14
                lead_field15:
                  type: string
                  description: Campo personalizado 15
                lead_field16:
                  type: string
                  description: Campo personalizado 16
                lead_field17:
                  type: string
                  description: Campo personalizado 17
                lead_field18:
                  type: string
                  description: Campo personalizado 18
                lead_field19:
                  type: string
                  description: Campo personalizado 19
                lead_field20:
                  type: string
                  description: Campo personalizado 20
      responses:
        '200':
          description: Lead atualizado com sucesso
          content:
            application/json:
              schema:
                $ref: ../schemas/chat.yaml#/Chat
              example:
                wa_fastid: '5511888888888:5511999999999'
                wa_chatid: 5511999999999@s.whatsapp.net
                lead_name: João Silva
                lead_status: qualificado
                lead_tags:
                  - vip
                  - suporte
                lead_isTicketOpen: true
                lead_assignedAttendant_id: att_123456
        '400':
          description: Payload inválido
        '404':
          description: Chat não encontrado
        '500':
          description: Erro interno do servidor
  /contacts:
    get:
      operationId: checkContacts
      tags:
        - Contatos
      summary: Retorna lista de contatos do WhatsApp
      description: |
        Retorna a lista de contatos do WhatsApp conforme o filtro informado em `contactScope`.

        O endpoint realiza:
        - Busca todos os contatos armazenados
        - Filtra para contatos da agenda, fora da agenda ou todos
        - Usa `address_book` como padrao quando `contactScope` nao for informado
        - Retorna dados formatados incluindo JID e informações de nome
      security:
        - token: []
      parameters:
        - in: query
          name: contactScope
          required: false
          schema:
            type: string
            enum:
              - address_book
              - outside_address_book
              - all
            default: address_book
          description: Define se a busca retorna apenas contatos da agenda, apenas fora da agenda ou todos os contatos conhecidos.
      responses:
        '200':
          description: Lista de contatos retornada com sucesso
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    jid:
                      type: string
                      description: 'ID único do contato no WhatsApp (formato: número@s.whatsapp.net)'
                      example: 5511999999999@s.whatsapp.net
                    contactName:
                      type: string
                      description: Nome completo do contato
                      example: João Silva
                    contact_FirstName:
                      type: string
                      description: Primeiro nome do contato
                      example: João
        '401':
          description: Sem sessão ativa
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Internal server error
  /contacts/list:
    post:
      operationId: listContacts
      tags:
        - Contatos
      summary: Listar todos os contatos com paginacao
      description: >
        Retorna uma lista paginada de contatos da conta do WhatsApp atualmente conectada.

        Use este endpoint (POST) para controlar `limit` e `offset` via corpo da requisicao.

        O campo `contactScope` permite escolher entre contatos da agenda, fora da agenda ou todos os contatos
        conhecidos.

        A rota GET `/contacts` continua disponivel para quem prefere a lista completa sem paginacao.
      security:
        - token: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                limit:
                  type: integer
                  description: Quantidade maxima de resultados por pagina (padrao 100, maximo 1000)
                  default: 100
                offset:
                  type: integer
                  description: Deslocamento base zero para paginacao
                  default: 0
                contactScope:
                  type: string
                  description: >-
                    Define se a busca retorna apenas contatos da agenda, apenas fora da agenda ou todos os contatos
                    conhecidos.
                  enum:
                    - address_book
                    - outside_address_book
                    - all
                  default: address_book
      responses:
        '200':
          description: Lista de contatos recuperada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  contacts:
                    type: array
                    items:
                      type: object
                      properties:
                        jid:
                          type: string
                          description: 'ID unico do contato no WhatsApp (formato: numero@s.whatsapp.net)'
                          example: 5511999999999@s.whatsapp.net
                        contact_name:
                          type: string
                          description: Nome completo do contato (quando salvo)
                          example: Joao Silva
                        contact_FirstName:
                          type: string
                          description: Primeiro nome do contato
                          example: Joao
                  totalDeviceContacts:
                    type: integer
                    description: Total bruto de contatos no dispositivo
                  pagination:
                    type: object
                    properties:
                      totalRecords:
                        type: integer
                        description: Total de contatos apos filtragem
                      limit:
                        type: integer
                        description: Limite aplicado na pagina atual
                      offset:
                        type: integer
                        description: Offset efetivamente usado na pagina atual
        '401':
          description: Token nao fornecido ou invalido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
        '500':
          description: Erro interno do servidor ao recuperar contatos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
  /contact/add:
    post:
      operationId: addContact
      tags:
        - Contatos
      summary: Adiciona um contato à agenda
      description: |
        Adiciona um novo contato à agenda do celular.

        O endpoint realiza:
        - Adiciona o contato à agenda usando o WhatsApp
        - Usa o campo 'name' tanto para o nome completo quanto para o primeiro nome
        - Salva as informações do contato na agenda do WhatsApp
        - Retorna informações do contato adicionado
      security:
        - token: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - number
                - name
              properties:
                number:
                  type: string
                  description: |
                    Número de telefone no formato internacional com código do país obrigatório. 
                    Para Brasil, deve começar com 55. Aceita variações com/sem símbolo +, 
                    com/sem parênteses, com/sem hífen e com/sem espaços. Também aceita formato 
                    JID do WhatsApp (@s.whatsapp.net). Não aceita contatos comerciais (@lid) 
                    nem grupos (@g.us).
                  examples:
                    - +55 (21) 99999-9999
                    - +55 21 99999-9999
                    - +55 21 999999999
                    - '+5521999999999'
                    - '5521999999999'
                    - 5521999999999@s.whatsapp.net
                name:
                  type: string
                  description: Nome completo do contato (será usado como primeiro nome e nome completo)
                  example: João Silva
      responses:
        '200':
          description: Contato adicionado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Contato adicionado com sucesso
                  contact:
                    type: object
                    properties:
                      jid:
                        type: string
                        description: 'ID único do contato no WhatsApp (formato: número@s.whatsapp.net)'
                        example: 5511999999999@s.whatsapp.net
                      name:
                        type: string
                        description: Nome completo do contato
                        example: João Silva
                      phone:
                        type: string
                        description: Número de telefone
                        example: '5511999999999'
        '400':
          description: Dados inválidos na requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Número inválido
        '401':
          description: Sem sessão ativa
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Erro ao adicionar contato
  /contact/remove:
    post:
      operationId: removeContact
      tags:
        - Contatos
      summary: Remove um contato da agenda
      description: |
        Remove um contato da agenda do celular.

        O endpoint realiza:
        - Remove o contato da agenda usando o WhatsApp AppState
        - Atualiza a lista de contatos sincronizada
        - Retorna confirmação da remoção
      security:
        - token: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - number
              properties:
                number:
                  type: string
                  description: |
                    Número de telefone no formato internacional com código do país obrigatório. 
                    Para Brasil, deve começar com 55. Aceita variações com/sem símbolo +, 
                    com/sem parênteses, com/sem hífen e com/sem espaços. Também aceita formato 
                    JID do WhatsApp (@s.whatsapp.net). Não aceita contatos comerciais (@lid) 
                    nem grupos (@g.us).
                  examples:
                    - +55 (21) 99999-9999
                    - +55 21 99999-9999
                    - +55 21 999999999
                    - '+5521999999999'
                    - '5521999999999'
                    - 5521999999999@s.whatsapp.net
      responses:
        '200':
          description: Contato removido com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Contato removido com sucesso
                  removed_contact:
                    type: object
                    properties:
                      jid:
                        type: string
                        description: 'ID único do contato no WhatsApp (formato: número@s.whatsapp.net)'
                        example: 5511999999999@s.whatsapp.net
                      phone:
                        type: string
                        description: Número de telefone removido
                        example: '5511999999999'
        '400':
          description: Dados inválidos na requisição
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Número inválido
        '401':
          description: Sem sessão ativa
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
        '404':
          description: Contato não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Contato não encontrado na agenda
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Erro ao remover contato
  /chat/details:
    post:
      operationId: getChatDetails
      tags:
        - Contatos
      summary: Obter Detalhes Completos
      description: >
        Retorna informações **completas** sobre um contato ou chat, incluindo **todos os campos disponíveis** do modelo
        Chat.


        ### Funcionalidades:

        - **Retorna chat completo**: Todos os campos do modelo Chat (mais de 60 campos)

        - **Busca informações para contatos individuais e grupos**

        - **URLs de imagem em dois tamanhos**: preview (menor) ou full (original)

        - **Combina informações de diferentes fontes**: WhatsApp, contatos salvos, leads

        - **Atualiza automaticamente dados desatualizados** no banco


        ### Campos Retornados:

        - **Informações básicas**: id, wa_fastid, wa_chatid, owner, name, phone

        - **Dados do WhatsApp**: wa_name, wa_contactName, wa_archived, wa_isBlocked, etc.

        - **Dados de lead/CRM**: lead_name, lead_email, lead_status, lead_field01-20, etc.

        - **Informações de grupo**: wa_isGroup, wa_isGroup_admin, wa_isGroup_announce, etc.

        - **Chatbot**: chatbot_summary, chatbot_lastTrigger_id, chatbot_disableUntil, etc.

        - **Configurações**: wa_muteEndTime, wa_isPinned, wa_unreadCount, etc.


        **Comportamento**:

        - Para contatos individuais:
          - Busca nome verificado do WhatsApp
          - Verifica nome salvo nos contatos
          - Formata número internacional
          - Calcula grupos em comum
        - Para grupos:
          - Busca nome do grupo
          - Verifica status de comunidade
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: Número do telefone ou ID do grupo
                  example: '5511999999999'
                preview:
                  type: boolean
                  description: |
                    Controla o tamanho da imagem de perfil retornada:
                    - `true`: Retorna imagem em tamanho preview (menor, otimizada para listagens)
                    - `false` (padrão): Retorna imagem em tamanho full (resolução original, maior qualidade)
                  default: false
              required:
                - number
      responses:
        '200':
          description: Informações completas do chat retornadas com sucesso
          content:
            application/json:
              schema:
                allOf:
                  - $ref: ../schemas/chat.yaml#/Chat
                  - type: object
                    properties:
                      common_groups:
                        type: string
                        description: 'Grupos em comum separados por vírgula, formato: nome_grupo(id_grupo)'
                        example: Grupo Família(120363123456789012@g.us),Trabalho(987654321098765432@g.us)
                      imagePreview:
                        type: string
                        description: URL da imagem de perfil em tamanho preview (menor) - apenas se preview=true
                      image:
                        type: string
                        description: URL da imagem de perfil em tamanho full (resolução original) - apenas se preview=false
              examples:
                contact_example:
                  summary: Contato individual
                  description: Exemplo de resposta para um contato individual
                  value:
                    id: r1a2b3c4d5e6f7
                    wa_fastid: admin:5511999999999
                    wa_chatid: 5511999999999@s.whatsapp.net
                    wa_name: João Silva
                    name: João Silva
                    phone: +55 11 99999-9999
                    owner: admin
                    wa_archived: false
                    wa_isBlocked: false
                    wa_isGroup: false
                    lead_name: João
                    lead_fullName: João Silva
                    lead_email: joao@exemplo.com
                    lead_status: ativo
                    wa_contactName: João Silva
                    common_groups: Grupo Família(120363123456789012@g.us),Trabalho(987654321098765432@g.us)
                    image: https://pps.whatsapp.net/v/t61.24694-24/12345_image.jpg
                group_example:
                  summary: Grupo
                  description: Exemplo de resposta para um grupo
                  value:
                    id: r9z8y7x6w5v4u3
                    wa_fastid: admin:120363123456789012@g.us
                    wa_chatid: 120363123456789012@g.us
                    wa_name: Grupo Família
                    name: Grupo Família
                    phone: ''
                    owner: admin
                    wa_archived: false
                    wa_isBlocked: false
                    wa_isGroup: true
                    wa_isGroup_admin: true
                    wa_isGroup_announce: false
                    wa_isGroup_community: false
                    wa_isGroup_member: true
                    image: https://pps.whatsapp.net/v/t61.24694-24/67890_group.jpg
        '400':
          description: Payload inválido ou número inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Invalid request payload
        '401':
          description: Token não fornecido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Unauthorized
        '500':
          description: Erro interno do servidor ou sessão não iniciada
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No session
  /chat/check:
    post:
      operationId: checkChat
      tags:
        - Contatos
      summary: Verificar Números no WhatsApp
      description: |
        Verifica se números fornecidos estão registrados no WhatsApp e retorna informações detalhadas.

        ### Funcionalidades:
        - Verifica múltiplos números simultaneamente
        - Suporta números individuais e IDs de grupo
        - Retorna nome verificado quando disponível
        - Identifica grupos e comunidades
        - Verifica subgrupos de comunidades

        **Comportamento específico**:
        - Para números individuais:
          - Verifica registro no WhatsApp
          - Retorna nome verificado se disponível
          - Normaliza formato do número
        - Para grupos:
          - Verifica existência
          - Retorna nome do grupo
          - Retorna id do grupo de anúncios se buscado por id de comunidade
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                numbers:
                  type: array
                  items:
                    type: string
                  description: Lista de números ou IDs de grupo para verificar
                  example:
                    - '5511999999999'
                    - 123456789@g.us
      responses:
        '200':
          description: Resultado da verificação
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    query:
                      type: string
                      description: Número/ID original consultado
                    jid:
                      type: string
                      description: JID do WhatsApp
                    lid:
                      type: string
                      description: LID do WhatsApp
                    isInWhatsapp:
                      type: boolean
                      description: Indica se está no WhatsApp
                    verifiedName:
                      type: string
                      description: Nome verificado se disponível
                    groupName:
                      type: string
                      description: Nome do grupo se aplicável
                    error:
                      type: string
                      description: Mensagem de erro se houver
        '400':
          description: Payload inválido ou sem números
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Missing numbers in payload
        '401':
          description: Sem sessão ativa
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No active session
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: WhatsApp client is not connected
  /label/edit:
    post:
      operationId: editLabel
      tags:
        - Etiquetas
      summary: Criar, editar ou deletar etiqueta
      description: |
        Cria, edita ou deleta uma etiqueta da instância.

        Regras de uso:
        - Para editar uma etiqueta existente, envie o `labelid` real da etiqueta.
        - Para criar uma nova etiqueta, envie `labelid: "new"` com `delete: false`.
          O backend irá gerar o próximo `labelid` numérico disponível para a instância.
        - Para deletar uma etiqueta existente, envie o `labelid` real com `delete: true`.

        Observações:
        - A resposta de sucesso retorna `"Label created"` para criação e `"Label edited"` para edição.
        - Para descobrir o `labelid` final criado, consulte `GET /labels` após a operação
          ou consuma o webhook/evento de labels da instância.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                labelid:
                  type: string
                  description: |
                    ID da etiqueta.

                    Use o ID real para editar/deletar uma etiqueta existente.
                    Use `"new"` para criar uma nova etiqueta quando `delete` for `false`.
                  example: '25'
                name:
                  type: string
                  description: Novo nome da etiqueta
                  example: responder editado
                color:
                  type: integer
                  description: Código numérico da nova cor (0-19)
                  minimum: 0
                  maximum: 19
                  example: 2
                delete:
                  type: boolean
                  description: Indica se a etiqueta deve ser deletada
                  example: false
              required:
                - labelid
            examples:
              criar_label:
                summary: Criar nova etiqueta
                description: |
                  Cria uma nova etiqueta usando o placeholder `labelid: "new"`.
                value:
                  labelid: new
                  name: responder editado
                  color: 2
                  delete: false
              editar_label:
                summary: Editar etiqueta existente
                description: Edita nome e cor de uma etiqueta já existente
                value:
                  labelid: '25'
                  name: responder editado
                  color: 2
                  delete: false
              deletar_label:
                summary: Deletar etiqueta existente
                description: Remove uma etiqueta já existente
                value:
                  labelid: '25'
                  name: ''
                  color: 0
                  delete: true
      responses:
        '200':
          description: Operação concluída com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    enum:
                      - Label created
                      - Label edited
                    example: Label edited
              examples:
                created:
                  summary: Resposta ao criar uma etiqueta
                  value:
                    response: Label created
                edited:
                  summary: Resposta ao editar uma etiqueta
                  value:
                    response: Label edited
        '400':
          description: Payload inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid payload
        '500':
          description: Erro interno do servidor ou sessão inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: error editing label
  /labels:
    get:
      operationId: listLabels
      tags:
        - Etiquetas
      summary: Buscar todas as etiquetas
      description: |
        Retorna a lista completa de etiquetas da instância.
      responses:
        '200':
          description: Lista de etiquetas retornada com sucesso
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: ../schemas/label.yaml#/Label
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Failed to fetch labels from database
  /labels/refresh:
    post:
      operationId: refreshLabels
      tags:
        - Etiquetas
      summary: Recarregar etiquetas do WhatsApp
      description: |
        Faz uma nova leitura das etiquetas no WhatsApp antes de retornar a lista atualizada.

        Uso recomendado:
        - tente primeiro com `force=false`
        - se isso não trouxer as etiquetas corretamente, tente `force=true`
        - use `force=true` apenas como tentativa de correção, porque ele faz uma recarga mais pesada
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                force:
                  type: boolean
                  default: false
                  description: |
                    Tente primeiro com `false`.
                    Use `true` apenas quando a recarga padrão não funcionar bem,
                    pois esse modo faz uma nova leitura mais completa das etiquetas.
                  example: false
      responses:
        '200':
          description: Lista de etiquetas recarregada com sucesso
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: ../schemas/label.yaml#/Label
        '409':
          description: O reload não pôde ser executado porque o history sync ainda está em andamento
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: history sync still in progress, try again in a moment
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: failed to reload labels from WhatsApp
  /quickreply/edit:
    post:
      operationId: editQuickReply
      tags:
        - Respostas Rápidas
      summary: Criar, atualizar ou excluir resposta rápida
      description: |
        Gerencia templates de respostas rápidas para agilizar o atendimento. Suporta mensagens de texto e mídia.

        - Para criar: não inclua o campo `id`
        - Para atualizar: inclua o `id` existente
        - Para excluir: defina `delete: true` e inclua o `id`

        Observação: Templates originados do WhatsApp (onWhatsApp=true) não podem ser modificados ou excluídos.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - shortCut
                - type
              properties:
                id:
                  type: string
                  description: Necessário para atualizações/exclusões, omitir para criação
                  example: rb9da9c03637452
                delete:
                  type: boolean
                  description: Definir como true para excluir o template
                  default: false
                shortCut:
                  type: string
                  description: Atalho para acesso rápido ao template
                  example: saudacao1
                type:
                  type: string
                  enum:
                    - text
                    - audio
                    - myaudio
                    - ptt
                    - document
                    - video
                    - image
                  description: Tipo da mensagem
                text:
                  type: string
                  description: Obrigatório para mensagens do tipo texto
                  example: Olá! Como posso ajudar hoje?
                file:
                  type: string
                  description: URL ou Base64 para tipos de mídia
                  example: https://exemplo.com/arquivo.pdf
                docName:
                  type: string
                  description: Nome do arquivo opcional para tipo documento
                  example: apresentacao.pdf
      responses:
        '200':
          description: Operação concluída com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Operação concluída com sucesso
                  quickReplies:
                    type: array
                    items:
                      $ref: ../schemas/quick_reply.yaml#/QuickReply
        '400':
          description: Requisição inválida (erro de validação)
        '403':
          description: Não é possível modificar template originado do WhatsApp
        '404':
          description: Template não encontrado
        '500':
          description: Erro no servidor
  /quickreply/showall:
    get:
      operationId: listQuickReplies
      tags:
        - Respostas Rápidas
      summary: Listar todas as respostas rápidas
      description: Retorna todas as respostas rápidas cadastradas para a instância autenticada
      responses:
        '200':
          description: Lista de respostas rápidas
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: ../schemas/quick_reply.yaml#/QuickReply
        '500':
          description: Erro no servidor
  /call/make:
    post:
      operationId: makeCall
      tags:
        - Chamadas
      summary: Iniciar chamada de voz
      description: >
        Inicia uma chamada de voz para um contato específico. Este endpoint permite:

        1. Iniciar chamadas de voz para contatos

        2. Funciona apenas com números válidos do WhatsApp

        3. O contato receberá uma chamada de voz


        **Nota**: O telefone do contato tocará normalmente, mas ao contato atender, ele não ouvirá nada, e você também
        não ouvirá nada. 

        Este endpoint apenas inicia a chamada, não estabelece uma comunicação de voz real.


        **Opcional**: Use `call_duration` para definir por quantos segundos a chamada deve tocar.

        Após esse período a chamada é encerrada automaticamente, sem precisar chamar `/call/reject`.


        Exemplo de requisição:

        ```json

        {
          "number": "5511999999999",
          "call_duration": 15
        }

        ```


        Exemplo de resposta:

        ```json

        {
          "response": "Call successful"
        }

        ```


        Erros comuns:

        - 401: Token inválido ou expirado

        - 400: Número inválido ou ausente

        - 500: Erro ao iniciar chamada
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: 'Número do contato no formato internacional (ex: 5511999999999)'
                  example: '5511999999999'
                call_duration:
                  type: integer
                  description: Duração da chamada em segundos (opcional). Após esse tempo a chamada é encerrada automaticamente.
                  example: 15
              required:
                - number
      responses:
        '200':
          description: Chamada iniciada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    description: Mensagem de confirmação
                    example: Call successful
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro
              examples:
                missing_number:
                  summary: Numero nao informado
                  value:
                    error: missing number in payload
                invalid_number:
                  summary: Numero invalido
                  value:
                    error: invalid number JID
                invalid_duration:
                  summary: Duracao invalida
                  value:
                    error: invalid call_duration
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro de autenticação
                    example: client not found
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro interno
                    example: 'error making call: network timeout'
  /call/reject:
    post:
      operationId: rejectCall
      tags:
        - Chamadas
      summary: Rejeitar chamada recebida
      description: >
        Rejeita uma chamada recebida do WhatsApp.


        O body pode ser enviado vazio `{}`. Os campos `number` e `id` são opcionais e podem ser usados para especificar
        uma chamada específica.


        Exemplo de requisição (recomendado):

        ```json

        {}

        ```


        Exemplo de requisição com campos opcionais:

        ```json

        {
          "number": "5511999999999",
          "id": "ABEiGmo8oqkAcAKrBYQAAAAA_1"
        }

        ```


        Exemplo de resposta:

        ```json

        {
          "response": "Call rejected"
        }

        ```


        Erros comuns:

        - 401: Token inválido ou expirado

        - 400: Número inválido

        - 500: Erro ao rejeitar chamada
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              example: {}
              properties:
                number:
                  type: string
                  description: '(Opcional) Número do contato no formato internacional (ex: 5511999999999)'
                id:
                  type: string
                  description: (Opcional) ID único da chamada a ser rejeitada
      responses:
        '200':
          description: Chamada rejeitada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    description: Mensagem de confirmação
                    example: Call rejected
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro
                    examples:
                      - invalid number
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro de autenticação
                    example: client not found
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Descrição do erro interno
                    example: 'error rejecting call: timeout'
  /chatwoot/config:
    get:
      operationId: getChatwootConfig
      tags:
        - Integração Chatwoot
      summary: Obter configuração do Chatwoot
      description: |
        Retorna a configuração atual da integração com Chatwoot para a instância.

        ### Funcionalidades:
        - Retorna todas as configurações do Chatwoot incluindo credenciais
        - Mostra status de habilitação da integração
        - Útil para verificar configurações atuais antes de fazer alterações
      responses:
        '200':
          description: Configuração obtida com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  chatwoot_enabled:
                    type: boolean
                    description: Se a integração com Chatwoot está habilitada
                    example: true
                  chatwoot_url:
                    type: string
                    description: URL base da instância Chatwoot
                    example: https://app.chatwoot.com
                  chatwoot_account_id:
                    type: integer
                    format: int64
                    description: ID da conta no Chatwoot
                    example: 1
                  chatwoot_inbox_id:
                    type: integer
                    format: int64
                    description: ID da inbox no Chatwoot
                    example: 5
                  chatwoot_access_token:
                    type: string
                    description: Token de acesso da API Chatwoot
                    example: pXXGHHHyJPYHYgWHJHYHgJjj
                  chatwoot_ignore_groups:
                    type: boolean
                    description: Se deve ignorar mensagens de grupos na sincronização
                    example: false
                  chatwoot_sign_messages:
                    type: boolean
                    description: Se deve assinar mensagens enviadas para o WhatsApp
                    example: true
                  chatwoot_create_new_conversation:
                    type: boolean
                    description: Sempre criar nova conversa ao invés de reutilizar conversas existentes
                    example: false
        '401':
          description: Token inválido/expirado
        '500':
          description: Erro interno do servidor
    put:
      operationId: updateChatwootConfig
      tags:
        - Integração Chatwoot
      summary: Atualizar configuração do Chatwoot
      description: |
        Atualiza a configuração da integração com Chatwoot para a instância.

        ### Funcionalidades:
        - Configura todos os parâmetros da integração Chatwoot
        - Reinicializa automaticamente o cliente Chatwoot quando habilitado
        - Retorna URL do webhook para configurar no Chatwoot
        - Sincronização bidirecional de mensagens novas entre WhatsApp e Chatwoot
        - Sincronização automática de contatos (nome e telefone)
        - Atualização automática LID → PN (Local ID para Phone Number)
        - Sistema de nomes inteligentes com til (~)

        ### Configuração no Chatwoot:
        1. Após configurar via API, use a URL retornada no webhook settings da inbox no Chatwoot
        2. Configure como webhook URL na sua inbox do Chatwoot
        3. A integração ficará ativa e sincronizará mensagens e contatos automaticamente

        ### 🏷️ Sistema de Nomes Inteligentes:
        - **Nomes com til (~)**: São atualizados automaticamente quando o contato modifica seu nome no WhatsApp
        - **Nomes específicos**: Para definir um nome fixo, remova o til (~) do nome no Chatwoot
        - **Exemplo**: "~João Silva" será atualizado automaticamente, "João Silva" (sem til) permanecerá fixo
        - **Atualização LID→PN**: Contatos migram automaticamente de Local ID para Phone Number quando disponível
        - **Sem duplicação**: Durante a migração LID→PN, não haverá duplicação de conversas
        - **Respostas nativas**: Todas as respostas dos agentes aparecem nativamente no Chatwoot

        ### 🚧 AVISO IMPORTANTE - INTEGRAÇÃO BETA:
        - **Fase Beta**: Esta integração está em fase de desenvolvimento e testes
        - **Uso por conta e risco**: O usuário assume total responsabilidade pelo uso
        - **Recomendação**: Teste em ambiente não-produtivo antes de usar em produção
        - **Suporte limitado**: Funcionalidades podem mudar sem aviso prévio

        ### ⚠️ Limitações Conhecidas:
        - **Sincronização de histórico**: Não implementada - apenas mensagens novas são sincronizadas
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                enabled:
                  type: boolean
                  description: Habilitar/desabilitar integração com Chatwoot
                  example: true
                url:
                  type: string
                  description: URL base da instância Chatwoot (sem barra final)
                  example: https://app.chatwoot.com
                access_token:
                  type: string
                  description: Token de acesso da API Chatwoot (obtido em Profile Settings > Access Token)
                  example: pXXGHHHyJPYHYgWHJHYHgJjj
                account_id:
                  type: integer
                  format: int64
                  description: ID da conta no Chatwoot (visível na URL da conta)
                  example: 1
                inbox_id:
                  type: integer
                  format: int64
                  description: ID da inbox no Chatwoot (obtido nas configurações da inbox)
                  example: 5
                ignore_groups:
                  type: boolean
                  description: Ignorar mensagens de grupos do WhatsApp na sincronização
                  example: false
                sign_messages:
                  type: boolean
                  description: Assinar mensagens enviadas para WhatsApp com identificação do agente
                  example: true
                create_new_conversation:
                  type: boolean
                  description: Sempre criar nova conversa ao invés de reutilizar conversas existentes
                  example: false
              required:
                - enabled
                - url
                - access_token
                - account_id
                - inbox_id
      responses:
        '200':
          description: Configuração atualizada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: Mensagem de confirmação
                    example: 'Chatwoot config updated successfully, put this URL in Chatwoot inbox webhook settings:'
                  chatwoot_inbox_webhook_url:
                    type: string
                    description: URL do webhook para configurar na inbox do Chatwoot
                    example: https://sua-api.com/chatwoot/webhook/inst_abc123
        '400':
          description: Dados inválidos no body da requisição
        '401':
          description: Token inválido/expirado
        '500':
          description: Erro interno ao salvar configuração
  /business/get/profile:
    post:
      tags:
        - Business
      summary: Obter o perfil comercial
      description: |
        Retorna o perfil comercial da conta do WhatsApp Business atualmente conectada.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                jid:
                  type: string
                  description: JID do perfil comercial a consultar
                  example: 5511999999999@s.whatsapp.net
      responses:
        '200':
          description: Perfil comercial recuperado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: object
                    description: Dados do perfil comercial
                    properties:
                      tag:
                        type: string
                        description: A tag do perfil comercial.
                      description:
                        type: string
                        description: A descrição do perfil comercial.
                      address:
                        type: string
                        description: O endereço do perfil comercial.
                      email:
                        type: string
                        description: O email do perfil comercial.
                      websites:
                        type: array
                        items:
                          type: string
                        description: Os websites do perfil comercial.
                      categories:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                            localized_display_name:
                              type: string
                        description: As categorias do perfil comercial.
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de validação do payload ou do JID
                    example: invalid payload
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de autenticação
                    example: client not found
        '500':
          description: Erro interno do servidor ao recuperar o perfil comercial
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
  /business/get/categories:
    get:
      tags:
        - Business
      summary: Obter as categorias de negócios
      description: |
        Retorna as categorias de negócios disponíveis.
      responses:
        '200':
          description: Categorias de negócios recuperadas com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: array
                    description: Lista de categorias de negócios
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        localized_display_name:
                          type: string
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de autenticação
                    example: client not found
        '500':
          description: Erro interno do servidor ao recuperar as categorias de negócios
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
  /business/update/profile:
    post:
      tags:
        - Business
      summary: Atualizar o perfil comercial
      description: |
        Atualiza os dados do perfil comercial da conta do WhatsApp Business atualmente conectada.
        Todos os campos são opcionais; apenas os enviados serão atualizados.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                description:
                  type: string
                  description: Nova descrição do perfil comercial.
                  example: Loja de eletrônicos e acessórios
                address:
                  type: string
                  description: Novo endereço do perfil comercial.
                  example: Rua das Flores, 123 - Centro
                email:
                  type: string
                  description: Novo email do perfil comercial.
                  example: contato@empresa.com
            examples:
              todos_campos:
                summary: Atualizar todos os campos
                value:
                  description: Loja de eletrônicos e acessórios
                  address: Rua das Flores, 123 - Centro
                  email: contato@empresa.com
              apenas_descricao:
                summary: Atualizar apenas a descrição
                value:
                  description: Nova descrição da empresa
              endereco_email:
                summary: Atualizar endereço e email
                value:
                  address: Av. Principal, 456
                  email: novo@email.com
      responses:
        '200':
          description: Todos os campos enviados foram atualizados
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: object
                    description: Resultado por campo
                  updated:
                    type: integer
                    description: Total de campos atualizados
                    example: 3
                  failed:
                    type: integer
                    description: Total de campos que falharam
                    example: 0
              examples:
                sucesso_todos:
                  summary: Todos os campos atualizados
                  value:
                    response:
                      description:
                        status: updated
                      address:
                        status: updated
                      email:
                        status: updated
                    updated: 3
                    failed: 0
        '207':
          description: Sucesso parcial — ao menos um campo falhou
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: object
                    description: Resultado por campo
                  updated:
                    type: integer
                    example: 1
                  failed:
                    type: integer
                    example: 1
              examples:
                parcial:
                  summary: Falha em um dos campos
                  value:
                    response:
                      description:
                        status: updated
                      address:
                        status: error
                        error: upstream unavailable
                    updated: 1
                    failed: 1
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de validação
              examples:
                payload_invalido:
                  value:
                    error: invalid payload
                campo_obrigatorio:
                  value:
                    error: at least one field (description, address, email) is required
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de autenticação
                    example: client not found
        '500':
          description: Falha total — nenhum campo foi atualizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: object
                    description: Resultado por campo
                  updated:
                    type: integer
                    example: 0
                  failed:
                    type: integer
                    example: 3
  /business/catalog/list:
    post:
      operationId: getCatalog
      tags:
        - Business
      summary: Listar os produtos do catálogo
      description: >
        Lista uma página de produtos do catálogo de um perfil comercial no WhatsApp.


        Observações:

        - envie apenas `jid` para buscar a primeira página

        - a paginação pública usa o campo `after`

        - copie exatamente o valor retornado em `response.Paging.After` e envie na próxima chamada

        - o valor de `after` é um token opaco: não tente decodificar ou modificar

        - a integração atual retorna até 10 produtos por chamada

        - o retorno espelha as structs atuais da camada `whatsmeow`, então os campos de `response` usam nomes em
        maiúsculas (`Products`, `Paging`, etc.)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                jid:
                  type: string
                  description: JID do catálogo a consultar
                  example: 5511999999999@s.whatsapp.net
                after:
                  type: string
                  description: Token da próxima página. Use exatamente o valor retornado em `response.Paging.After`.
                  example: Q1VSU09SX1BST1hJTUFfUEFHSU5B
              required:
                - jid
            examples:
              primeiraPagina:
                summary: Buscar a primeira página do catálogo
                value:
                  jid: 5511999999999@s.whatsapp.net
              proximaPagina:
                summary: Buscar a próxima página usando after
                value:
                  jid: 5511999999999@s.whatsapp.net
                  after: Q1VSU09SX1BST1hJTUFfUEFHSU5B
      responses:
        '200':
          description: Produtos do catálogo recuperados com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: object
                    description: Página atual do catálogo retornada pelo WhatsApp.
                    properties:
                      JID:
                        type: object
                        description: JID do catálogo consultado, serializado pela struct atual do backend.
                        properties:
                          User:
                            type: string
                            example: '5511999999999'
                          RawAgent:
                            type: integer
                            example: 0
                          Device:
                            type: integer
                            example: 0
                          Integrator:
                            type: integer
                            example: 0
                          Server:
                            type: string
                            example: s.whatsapp.net
                      CartEnabled:
                        type: boolean
                        description: Indica se o carrinho do catálogo está habilitado.
                        example: false
                      Source:
                        type: string
                        description: Origem do catálogo retornada pelo WhatsApp.
                        example: ''
                      Products:
                        type: array
                        description: Lista de produtos da página atual.
                        items:
                          type: object
                          properties:
                            ID:
                              type: string
                              example: '1234567890'
                            Name:
                              type: string
                              example: Produto Exemplo
                            Description:
                              type: string
                              example: Descrição do produto
                            Price:
                              type: object
                              nullable: true
                              properties:
                                Amount:
                                  type: string
                                  example: '1990'
                                Currency:
                                  type: string
                                  example: BRL
                            SalePrice:
                              type: string
                              example: ''
                            RetailerID:
                              type: string
                              example: sku-123
                            Url:
                              type: string
                              example: https://exemplo.com/produto
                            Availability:
                              type: string
                              example: in stock
                            IsHidden:
                              type: boolean
                              example: false
                            StatusInfo:
                              type: object
                              properties:
                                Status:
                                  type: string
                                  example: active
                                CanAppeal:
                                  type: boolean
                                  example: false
                            MaxAvailable:
                              type: integer
                              example: 10
                            ImageFetchStatus:
                              type: string
                              example: success
                            Images:
                              type: array
                              items:
                                type: object
                                properties:
                                  ID:
                                    type: string
                                    example: img-1
                                  OriginalDimensions:
                                    type: object
                                    properties:
                                      Height:
                                        type: integer
                                        example: 720
                                      Width:
                                        type: integer
                                        example: 720
                                  RequestImageUrl:
                                    type: string
                                    example: https://mmg.whatsapp.net/v/t62.7118-24/...
                                  OriginalImageUrl:
                                    type: string
                                    example: https://lookaside.whatsapp.net/...
                      Paging:
                        type: object
                        description: Cursores de paginação retornados pelo WhatsApp.
                        properties:
                          Before:
                            type: string
                            example: ''
                          After:
                            type: string
                            example: Q1VSU09SX1BST1hJTUFfUEFHSU5B
              examples:
                sucesso:
                  value:
                    response:
                      JID:
                        User: '5511999999999'
                        RawAgent: 0
                        Device: 0
                        Integrator: 0
                        Server: s.whatsapp.net
                      CartEnabled: false
                      Source: ''
                      Products:
                        - ID: '1234567890'
                          Name: Produto Exemplo
                          Description: Descrição do produto
                          Price:
                            Amount: '1990'
                            Currency: BRL
                          SalePrice: ''
                          RetailerID: sku-123
                          Url: https://exemplo.com/produto
                          Availability: in stock
                          IsHidden: false
                          StatusInfo:
                            Status: active
                            CanAppeal: false
                          MaxAvailable: 10
                          ImageFetchStatus: success
                          Images:
                            - ID: img-1
                              OriginalDimensions:
                                Height: 720
                                Width: 720
                              RequestImageUrl: https://mmg.whatsapp.net/v/t62.7118-24/...
                              OriginalImageUrl: https://lookaside.whatsapp.net/...
                      Paging:
                        Before: ''
                        After: Q1VSU09SX1BST1hJTUFfUEFHSU5B
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de validação do payload ou JID
                    example: invalid payload
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de autenticação
                    example: client not found
        '500':
          description: Erro interno do servidor ao recuperar os produtos do catálogo
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
  /business/catalog/info:
    post:
      tags:
        - Business
      summary: Obter informações de um produto do catálogo
      description: |
        Retorna as informações de um produto específico do catálogo.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                jid:
                  type: string
                  description: JID do catálogo a consultar
                  example: 5511999999999@s.whatsapp.net
                id:
                  type: string
                  description: O ID do produto.
              required:
                - jid
                - id
      responses:
        '200':
          description: Informações do produto recuperadas com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: object
                    description: Informações do produto
                    properties:
                      id:
                        type: string
                      name:
                        type: string
                      description:
                        type: string
                      price:
                        type: string
                      currency:
                        type: string
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de validação do payload ou JID
                    example: invalid payload
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de autenticação
                    example: client not found
        '500':
          description: Erro interno do servidor ao recuperar as informações do produto
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
  /business/catalog/delete:
    post:
      tags:
        - Business
      summary: Deletar um produto do catálogo
      description: |
        Deleta um produto específico do catálogo.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: O ID do produto.
              required:
                - id
      responses:
        '200':
          description: Produto deletado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    description: Mensagem de sucesso.
                    example: Deleted product
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de validação do payload
                    example: invalid payload
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de autenticação
                    example: client not found
        '500':
          description: Erro interno do servidor ao deletar o produto
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
  /business/catalog/show:
    post:
      tags:
        - Business
      summary: Mostrar um produto do catálogo
      description: |
        Mostra um produto específico do catálogo.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: O ID do produto.
              required:
                - id
      responses:
        '200':
          description: Produto mostrado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    description: Mensagem de sucesso.
                    example: Product shown
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de validação do payload
                    example: invalid payload
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de autenticação
                    example: client not found
        '500':
          description: Erro interno do servidor ao mostrar o produto
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
  /business/catalog/hide:
    post:
      tags:
        - Business
      summary: Ocultar um produto do catálogo
      description: |
        Oculta um produto específico do catálogo.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: O ID do produto.
              required:
                - id
      responses:
        '200':
          description: Produto ocultado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    type: string
                    description: Mensagem de sucesso.
                    example: Product hidden
        '400':
          description: Requisição inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de validação do payload
                    example: invalid payload
        '401':
          description: Token inválido ou expirado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem de erro de autenticação
                    example: client not found
        '500':
          description: Erro interno do servidor ao ocultar o produto
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado
  /admin/restart:
    post:
      tags:
        - Admininstração
      summary: Reiniciar a aplicação
      security:
        - admintoken: []
      description: |
        Reinicia toda a aplicação para forçar a reconexão de todas as instâncias de uma vez.

        Use apenas em situações realmente necessárias, como instabilidades gerais.
        Após o restart, os números entram em reconexão automática e não ficam desconectados permanentemente.
      responses:
        '202':
          description: Reinicio agendado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: Mensagem de sucesso.
        '500':
          description: Erro interno do servidor ao agendar o reinicio
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Mensagem detalhando o erro encontrado



