{
  "openapi": "3.1.0",
  "info": {
    "title": "Orkesio - WhatsApp API",
    "version": "2.4.2",
    "x-logo": {
      "url": "/orkesio-icon.svg"
    },
    "description": "API para gerenciamento de instâncias do WhatsApp e comunicações.\n\n## ⚠️ Recomendação Importante: WhatsApp Business\n**É 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.\n\n## Autenticação\n- Endpoints regulares requerem um header 'token' com o token da instância\n- Endpoints administrativos requerem um header 'admintoken'\n\n## Estados da Instância\nAs instâncias podem estar nos seguintes estados:\n- `disconnected`: Desconectado do WhatsApp\n- `connecting`: Em processo de conexão\n- `connected`: Conectado e autenticado com sucesso\n- `hibernated`: Sessão pausada, com credenciais preservadas para reconexão\n\n## Limites de Uso\n- O servidor possui um limite máximo de instâncias conectadas\n- Quando o limite é atingido, novas tentativas receberão erro 429\n- Servidores gratuitos/demo podem ter restrições adicionais de tempo de vida\n"
  },
  "servers": [
    {
      "url": "https://{subdomain}.orkesio.com",
      "description": "Servidor da API Orkesio",
      "variables": {
        "subdomain": {
          "enum": [
            "free",
            "api"
          ],
          "default": "free"
        }
      }
    }
  ],
  "x-release": {
    "channel": "stable",
    "apiVersion": "2.4.2"
  },
  "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",
            "description": "Identificador opaco gerado pelo servidor. Não presuma formato UUID."
          },
          "token": {
            "type": "string",
            "description": "Token de autenticação da instância"
          },
          "status": {
            "type": "string",
            "description": "Status atual da conexão",
            "enum": [
              "disconnected",
              "connecting",
              "connected",
              "hibernated"
            ]
          },
          "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",
            "description": "Data/hora textual 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 pela API"
          },
          "created": {
            "type": "string",
            "description": "Data de criação retornada pela API. Trate o valor como texto; o formato pode variar."
          },
          "updated": {
            "type": "string",
            "description": "Data da última atualização retornada pela API. Trate o valor como texto; o formato pode variar."
          }
        },
        "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": "uazapi",
          "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",
            "description": "Identificador opaco gerado pelo servidor. Não presuma formato UUID."
          },
          "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",
                "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.\nSó existe quando o número estiver salvo na agenda/contatos.\n",
            "default": ""
          },
          "wa_name": {
            "type": "string",
            "description": "Nome definido pelo usuário no perfil do WhatsApp (\"push name\").\nVem do perfil do contato e pode não estar disponível dependendo do contexto ou da origem dos dados.\n",
            "default": ""
          },
          "name": {
            "type": "string",
            "description": "Nome resolvido pelo sistema como fallback.\nNormalmente consolida o melhor valor disponível entre dados internos, nome vindo do WhatsApp e nome salvo nos contatos.\nPor isso, costuma ter maior chance de vir preenchido.\n",
            "default": ""
          },
          "image": {
            "type": "string",
            "description": "URL da imagem do chat",
            "default": ""
          },
          "imagePreview": {
            "type": "string",
            "description": "URL da miniatura da imagem",
            "default": ""
          },
          "parent_community": {
            "type": "object",
            "description": "Comunidade pai do chat quando ele representa um subgrupo",
            "properties": {
              "jid": {
                "type": "string",
                "format": "jid"
              },
              "name": {
                "type": "string"
              },
              "image_url": {
                "type": "string"
              },
              "image_preview_url": {
                "type": "string"
              },
              "default_subgroup_jid": {
                "type": "string",
                "format": "jid"
              }
            }
          },
          "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 livre do lead",
            "default": ""
          },
          "lead_tags": {
            "type": "array",
            "description": "Tags do lead. Tags configuradas com `kanban=true` também determinam as\ncolunas em que o cartão aparece no Kanban.\n",
            "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.\nExemplos comuns: `Queued`, `Canceled`, `Failed`, `Sent`, `Delivered`, `Read`.\n"
          },
          "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 usado no envio quando disponível. Dados de mídia em base64 são omitidos.",
            "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"
          },
          "callPeer": {
            "type": "object",
            "description": "Contato conhecido associado a uma ligação, quando disponível em `messageType: call`.",
            "properties": {
              "jid": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "imagePreviewUrl": {
                "type": "string"
              }
            }
          },
          "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": {
            "description": "JID PN resolvido do remetente (quando disponível)",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "sender_lid": {
            "description": "LID original do remetente (quando disponível)",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "sender_image_preview_url": {
            "type": "string",
            "format": "uri",
            "description": "URL temporária de preview do remetente, quando conhecida. A hidratação desta versão preenche mensagens recebidas em grupos; o campo pode ser omitido. Não provoca consulta de foto ao WhatsApp na listagem."
          }
        }
      },
      "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 está sincronizada com o WhatsApp Business",
            "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\n- true = apenas admins podem editar\n- false = todos podem editar\n",
            "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": {
            "description": "Lista de participantes. É null quando omitida por noParticipants e pode estar vazia quando participant_profiles estiver presente.",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/GroupParticipant"
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "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": "Indica privilégio de administrador confirmado. Pode estar ausente quando falso; dados parciais não concedem privilégio de administrador."
          },
          "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, exposto somente para administrador com permissão confirmada. Pode estar ausente; não assuma que toda leitura consulta o WhatsApp."
          },
          "request_participants": {
            "type": "string",
            "description": "Pedidos conhecidos de entrada, separados por vírgula. Exposto somente para administrador quando solicitado."
          },
          "image_url": {
            "type": "string",
            "description": "URL da imagem completa já persistida; a API não consulta o WhatsApp durante a listagem"
          },
          "image_preview_url": {
            "type": "string",
            "description": "URL do preview já persistido"
          },
          "picture_id": {
            "type": "string",
            "description": "Identificador da imagem completa no WhatsApp"
          },
          "picture_preview_id": {
            "type": "string",
            "description": "Identificador do preview no WhatsApp"
          },
          "picture_empty_at": {
            "type": "string",
            "format": "date-time",
            "description": "Última confirmação de que o grupo não possuía imagem"
          },
          "image_checked_at": {
            "type": "string",
            "format": "date-time",
            "description": "Última consulta da imagem completa"
          },
          "image_preview_checked_at": {
            "type": "string",
            "format": "date-time",
            "description": "Última consulta do preview"
          },
          "parent_community": {
            "type": "object",
            "description": "Resumo da comunidade pai de um subgrupo",
            "properties": {
              "jid": {
                "type": "string",
                "format": "jid"
              },
              "name": {
                "type": "string"
              },
              "image_url": {
                "type": "string"
              },
              "image_preview_url": {
                "type": "string"
              },
              "default_subgroup_jid": {
                "type": "string",
                "format": "jid"
              }
            }
          },
          "participant_profiles": {
            "type": "array",
            "description": "Perfis adicionais dos participantes, quando disponíveis. Campos ausentes não devem ser inferidos.",
            "items": {
              "type": "object",
              "description": "Perfil adicional de um participante; campos ausentes não devem ser inferidos.",
              "properties": {
                "jid": {
                  "type": "string",
                  "format": "jid"
                },
                "pn": {
                  "type": "string",
                  "format": "jid"
                },
                "lid": {
                  "type": "string",
                  "format": "jid"
                },
                "username": {
                  "type": "string"
                },
                "display_name": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "image_url": {
                  "type": "string"
                },
                "image_preview_url": {
                  "type": "string"
                },
                "picture_id": {
                  "type": "string"
                },
                "picture_preview_id": {
                  "type": "string"
                },
                "is_admin": {
                  "type": "boolean"
                },
                "is_super_admin": {
                  "type": "boolean"
                }
              }
            }
          },
          "ParticipantCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Quantidade conhecida de participantes. Pode diferir do tamanho da lista quando os dados estiverem parciais ou tiverem sido omitidos da resposta."
          },
          "request_participants_lid": {
            "type": "string",
            "description": "LIDs dos pedidos conhecidos de entrada, separados por vírgula; somente para administrador quando solicitado."
          }
        }
      },
      "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 ou resolvido localmente para o participante"
          },
          "ImagePreview": {
            "type": "string",
            "description": "Campo legado não preenchido. Use participant_profiles[].image_preview_url.",
            "deprecated": true
          },
          "Error": {
            "type": "integer",
            "description": "Código de erro ao adicionar participante",
            "minimum": 0
          },
          "AddRequest": {
            "description": "Informações da solicitação de entrada",
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "Code": {
                    "type": "string",
                    "description": "Código da solicitação"
                  },
                  "Expiration": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Data de expiração da solicitação"
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "Username": {
            "type": "string",
            "description": "Username observado no WhatsApp, quando disponível."
          }
        }
      },
      "BusinessCatalogPage": {
        "type": "object",
        "required": [
          "products"
        ],
        "properties": {
          "next": {
            "type": "string",
            "description": "Cursor da próxima página."
          },
          "previous": {
            "type": "string",
            "description": "Cursor da página anterior."
          },
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BusinessProduct"
            }
          }
        }
      },
      "BusinessProduct": {
        "type": "object",
        "required": [
          "id",
          "name",
          "price",
          "currency",
          "is_hidden",
          "is_sanctioned",
          "media",
          "status_info"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "retailer_id": {
            "type": "string"
          },
          "belongs_to": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "price": {
            "type": "string",
            "description": "Valor em milésimos da moeda (19990 = R$ 19,99)."
          },
          "currency": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "shimmed_url": {
            "type": "string"
          },
          "is_hidden": {
            "type": "boolean"
          },
          "is_sanctioned": {
            "type": "boolean"
          },
          "max_available": {
            "type": "integer"
          },
          "product_availability": {
            "type": "string"
          },
          "compliance_category": {
            "type": "string"
          },
          "compliance_info": {
            "type": "object",
            "properties": {
              "country_code_origin": {
                "type": "string"
              },
              "importer_name": {
                "type": "string"
              },
              "importer_address": {
                "type": "object",
                "properties": {
                  "street1": {
                    "type": "string"
                  },
                  "street2": {
                    "type": "string"
                  },
                  "city": {
                    "type": "string"
                  },
                  "region": {
                    "type": "string"
                  },
                  "postal_code": {
                    "type": "string"
                  },
                  "country_code": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "media": {
            "type": "object",
            "properties": {
              "images": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "id"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "original_image_url": {
                      "type": "string"
                    },
                    "request_image_url": {
                      "type": "string"
                    }
                  }
                }
              },
              "videos": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "id"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "original_video_url": {
                      "type": "string"
                    },
                    "thumbnail_url": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "sale_price": {
            "type": "object",
            "required": [
              "price"
            ],
            "properties": {
              "price": {
                "type": "string"
              },
              "start_date": {
                "type": "string"
              },
              "end_date": {
                "type": "string"
              }
            }
          },
          "status_info": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string"
              },
              "can_appeal": {
                "type": "boolean"
              }
            }
          },
          "variant_info": {
            "type": "object",
            "properties": {
              "listing_details": {
                "type": "object",
                "properties": {
                  "description": {
                    "type": "string"
                  },
                  "lowest_price": {
                    "type": "string"
                  },
                  "multi_price": {
                    "type": "string"
                  }
                }
              },
              "availability": {
                "type": "object",
                "additionalProperties": true
              },
              "types": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "variant_properties": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "name",
                    "value"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "value": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "LeadTag": {
        "type": "object",
        "description": "Tag de lead. Quando `kanban=true`, o registro também define uma coluna do\nKanban da instância.\n",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID opaco e estável gerado pelo sistema"
          },
          "name": {
            "type": "string",
            "description": "Nome da tag/marcação"
          },
          "kanban": {
            "type": "boolean",
            "description": "Indica se a tag aparece como coluna ativa no Kanban",
            "default": false
          },
          "kanbanOrder": {
            "type": "integer",
            "format": "int64",
            "description": "Ordem crescente da coluna no Kanban",
            "default": 0
          },
          "owner": {
            "type": "string",
            "description": "Dono da tag"
          },
          "created": {
            "type": "string",
            "description": "Data de criação. Valor textual do registro; pode usar YYYY-MM-DD HH:mm:ss.SSSZ."
          },
          "updated": {
            "type": "string",
            "description": "Data da última atualização. Valor textual do registro; pode usar YYYY-MM-DD HH:mm:ss.SSSZ."
          }
        },
        "required": [
          "id",
          "name",
          "kanban",
          "kanbanOrder",
          "owner",
          "created",
          "updated"
        ]
      },
      "WebhookEvent": {
        "type": "object",
        "description": "Envelope comum de callHook. Campos específicos ficam na raiz e variam por evento. O token é sensível; não registre o payload completo.",
        "required": [
          "EventType",
          "owner",
          "token",
          "BaseUrl"
        ],
        "properties": {
          "EventType": {
            "type": "string",
            "description": "Tipo de evento, por exemplo connection ou messages."
          },
          "owner": {
            "type": "string"
          },
          "token": {
            "type": "string",
            "description": "Token da instância; dado sensível."
          },
          "BaseUrl": {
            "type": "string"
          },
          "instanceName": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "BusinessAddress": {
        "type": "object",
        "properties": {
          "street1": {
            "type": "string"
          },
          "street2": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "region": {
            "type": "string"
          },
          "postal_code": {
            "type": "string"
          },
          "country_code": {
            "type": "string"
          }
        }
      },
      "BusinessComplianceInfo": {
        "type": "object",
        "properties": {
          "country_code_origin": {
            "type": "string"
          },
          "importer_name": {
            "type": "string"
          },
          "importer_address": {
            "$ref": "#/components/schemas/BusinessAddress"
          }
        }
      },
      "BusinessCollectionPage": {
        "type": "object",
        "required": [
          "collections"
        ],
        "properties": {
          "next": {
            "type": "string",
            "description": "Cursor da próxima página, quando houver."
          },
          "collections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BusinessCollection"
            }
          }
        }
      },
      "BusinessCollection": {
        "type": "object",
        "required": [
          "id",
          "name",
          "products",
          "status_info"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "next": {
            "type": "string"
          },
          "previous": {
            "type": "string"
          },
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BusinessProduct"
            }
          },
          "status_info": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string"
              },
              "can_appeal": {
                "type": "boolean"
              },
              "commerce_url": {
                "type": "string"
              },
              "reject_reason": {
                "type": "string"
              }
            }
          }
        }
      },
      "BusinessCollectionMutationResult": {
        "type": "object",
        "required": [
          "id",
          "review_status"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "review_status": {
            "type": "string"
          }
        }
      }
    }
  },
  "security": [
    {
      "token": []
    }
  ],
  "tags": [
    {
      "name": "Administração",
      "description": "Endpoints para **administração geral** do sistema.\nRequerem um `admintoken` para autenticação.\n"
    },
    {
      "name": "Instancia",
      "description": "Operações relacionadas ao ciclo de vida de uma instância, como conectar,\ndesconectar e verificar o status.\n"
    },
    {
      "name": "Proxy",
      "description": "A Orkesio opera com um proxy interno como padrão.\nVocê 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/uazapi/silver_proxy_apk (APK direto: https://github.com/uazapi/silver_proxy_apk/raw/refs/heads/main/silver_proxy.apk).\nSe nada for enviado, seguimos no proxy interno. IPs são brasileiros; para clientes internacionais, considere um proxy da região do cliente.\n"
    },
    {
      "name": "Perfil",
      "description": "Operações relacionadas ao perfil da conta do WhatsApp atualmente conectada, como alterar\nnome e imagem de perfil.\n"
    },
    {
      "name": "Business",
      "description": "⚠️ **EXPERIMENTAL** - Endpoints ainda não testados completamente.\n\nOperações relacionadas ao perfil comercial do WhatsApp Business.\nPermite consultar e atualizar dados do perfil comercial como descrição,\nendereço, email, categorias e gerenciar o catálogo de produtos.\n\n**Requisitos:**\n- A conta atualmente conectada deve ser uma conta **WhatsApp Business**\n- Contas pessoais do WhatsApp não possuem perfil comercial\n\n**Nota:** Estes endpoints podem não funcionar como esperado.\nReporte problemas encontrados.\n"
    },
    {
      "name": "Chamadas",
      "description": "Operações relacionadas a chamadas peloWhatsApp.\nPermite realizar e rejeitar chamadas programaticamente.\n"
    },
    {
      "name": "Webhooks e SSE"
    },
    {
      "name": "Enviar Mensagem",
      "description": "Endpoints para envio de mensagens do WhatsApp com diferentes tipos de conteúdo.\n\n## Campos Opcionais Comuns\n\nTodos os endpoints de envio de mensagem suportam os seguintes campos opcionais:\n\n- **`delay`** *(integer)*: Atraso em milissegundos antes do envio\n  - Durante o atraso aparecerá \"Digitando...\" ou \"Gravando áudio...\" dependendo do tipo\n  - Exemplo: `5000` (5 segundos)\n\n- **`readchat`** *(boolean)*: Marcar chat como lido após envio\n  - Remove o contador de mensagens não lidas do chat\n  - Exemplo: `true`\n\n- **`readmessages`** *(boolean)*: Marcar últimas mensagens recebidas como lidas\n  - Marca as últimas 10 mensagens **recebidas** (não enviadas por você) como lidas\n  - Útil para confirmar leitura de mensagens pendentes antes de responder\n  - Diferente do `readchat` que apenas remove contador de não lidas\n  - Exemplo: `true`\n\n- **`replyid`** *(string)*: ID da mensagem para responder\n  - Cria uma resposta vinculada à mensagem original\n  - Suporte varia por tipo de mensagem\n\n- **`viewOnce`** *(boolean)*: Recomendado quando quiser mídia de visualização única\n  - Use em `/send/media` com `type` compatível (`image`, `video`, `videoplay`, `ptv`, `audio`, `myaudio`, `ptt`)\n  - Nos demais endpoints de envio, o campo é aceito, mas é ignorado silenciosamente\n  - Exemplo: `\"3A12345678901234567890123456789012\"`\n\n- **`mentions`** *(string)*: Números para mencionar (apenas para envio em grupos)\n  - Números específicos: `\"5511999999999,5511888888888\"`\n  - Compatibilidade para mencionar todos: `\"all\"`\n  - Menção nativa a todos: inclua `@all` ou `@todos` diretamente no texto da mensagem\n  - `@todos` é normalizado para `@all` antes do envio\n\n- **`forward`** *(boolean)*: Marca a mensagem como encaminhada no WhatsApp\n  - Adiciona o indicador \"Encaminhada\" na mensagem\n  - Exemplo: `true`\n\n- **`track_source`** *(string)*: Origem do rastreamento da mensagem\n  - Identifica o sistema ou fonte que está enviando a mensagem\n  - Útil para integrações (ex: \"chatwoot\", \"crm\", \"chatbot\")\n  - Exemplo: `\"chatwoot\"`\n\n- **`track_id`** *(string)*: ID para rastreamento da mensagem\n  - Identificador livre para acompanhar a mensagem em sistemas externos\n  - Permite correlacionar mensagens entre diferentes plataformas\n  - **Nota**: O sistema aceita valores duplicados - não há validação de unicidade\n  - Use o mesmo ID em várias mensagens se fizer sentido para sua integração\n  - Exemplo: `\"msg_123456789\"`\n\n- **`async`** *(boolean)*: Envia pela fila interna sem bloquear a requisição\n  - Resposta 200 indica que a mensagem entrou na fila; o envio real pode falhar depois\n  - Em caso de falha, pesquise em `/message/find` com `status=failed`\n\n## Diagnóstico de limites do WhatsApp\n\nEm alguns casos, o WhatsApp pode recusar novas conversas por regras próprias de volume, qualidade ou limitação temporária.\n\nQuando isso acontecer, a resposta de erro pode incluir:\n- `error_source: \"whatsapp_server\"`\n- `provider: \"whatsapp\"`\n- `provider_code: 463`\n- `error_key`\n- `message`\n- `message_ptbr`\n- `provider_message`\n- `provider_message_ptbr`\n- `diagnostics_endpoint`\n- `details.new_chat_message_capping`\n- `details.reachout_timelock`\n\nPara consultar o estado atual desses limites para a conta atualmente conectada, use:\n- `GET /instance/wa_messages_limits`\n\n### Envio para Grupos\n- **`number`** *(string)*: Para enviar mensagem para grupo, use o ID do grupo que termina com `@g.us`\n  - Exemplo: `\"120363012345678901@g.us\"`\n  - **Como obter o ID do grupo:**\n    - Use o `chatid` do webhook recebido quando alguém envia mensagem no grupo\n    - Use o endpoint `GET /group/list` para listar todos os grupos e seus IDs\n\n## Placeholders Disponíveis\n\nCampos textuais das operações de envio que documentam esse recurso aceitam os placeholders abaixo:\n\n### Campos de Nome\n- **`{{name}}`**: Nome consolidado do chat, usando a primeira opção disponível:\n  1. Nome do lead (`lead_name`)\n  2. Nome completo do lead (`lead_fullName`)\n  3. Nome do contato no WhatsApp (`wa_contactName`)\n  4. Nome do perfil do WhatsApp (`wa_name`)\n\n- **`{{first_name}}`**: Primeira palavra válida do nome consolidado (mínimo 2 caracteres)\n\n### Campos do WhatsApp\n- **`{{wa_name}}`**: Nome do perfil do WhatsApp\n- **`{{wa_contactName}}`**: Nome do contato como salvo no WhatsApp\n\n### Campos do Lead\n- **`{{lead_name}}`**: Nome do lead\n- **`{{lead_fullName}}`**: Nome completo do lead\n- **`{{lead_personalid}}`**: ID pessoal (CPF, CNPJ, etc)\n- **`{{lead_email}}`**: Email do lead\n- **`{{lead_status}}`**: Status atual do lead\n- **`{{lead_notes}}`**: Anotações do lead\n- **`{{lead_assignedAttendant_id}}`**: ID do atendente designado\n\n### Campos Personalizados\nOs 20 campos personalizados são acessíveis somente por `{{lead_field01}}` até `{{lead_field20}}`.\n`/instance/updateFieldsMap` configura o rótulo de cada campo, mas não cria um novo nome de placeholder.\nPor exemplo, mesmo que `lead_field01` receba o rótulo `empresa`, use `{{lead_field01}}`, não `{{empresa}}`.\n\n### Exemplo de Uso\n```\nOlá {{first_name}}! Empresa: {{lead_field01}}.\nSeu email {{lead_email}} está correto?\n```\n\n**💡 Dica**: Use `/chat/find` para buscar dados do chat e ver os campos disponíveis antes de enviar mensagens com placeholders.\n"
    },
    {
      "name": "Mensagem Async",
      "description": "Controles operacionais da fila interna de envio assíncrono usada quando um endpoint de envio recebe `async=true`.\n\nEsta seção serve para:\n- consultar o estado atual da fila async\n- configurar o delay entre mensagens enviadas com `async=true`\n- limpar backlog pendente e cancelar mensagens ainda não concluídas\n\nEscopo:\n- cobre apenas a fila interna de mensagens diretas async\n- não cobre campanhas do sender (`/sender/*`)\n- não altera mensagens já enviadas com sucesso\n"
    },
    {
      "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).\n\nCasos de uso principais:\n- listar posts já publicados em um canal\n- editar posts recentes de um canal\n- deletar posts recentes de um canal\n- consultar updates de engajamento dos posts\n- integrar canais sem necessidade de persistir as mensagens localmente\n\nObservações:\n- `/newsletter/messages` retorna o conteúdo dos posts\n- `/newsletter/messages/edit` edita o conteúdo de posts recentes\n- `/newsletter/messages/delete` apaga posts recentes\n- `/newsletter/updates` retorna updates dos posts, como views e reactions\n- views e reactions de canal devem ser consultados por `/newsletter/updates`, não por evento de webhook\n- newsletters usam rotas próprias e não devem usar `/message/edit` ou `/message/delete`\n"
    },
    {
      "name": "Respostas Rápidas",
      "description": "Gerenciamento de respostas rápidas para agilizar o atendimento.\n\n**⚠️ Importante**: Este recurso tem serventia apenas se você utilizar um sistema frontend/interface\npersonalizada para registrar e utilizar as respostas. A API apenas armazena as respostas, \nmas não as aplica automaticamente.\n\n### Como funciona:\n- **Criar**: Cadastre respostas pré-definidas com títulos e conteúdo\n- **Listar**: Recupere todas as respostas cadastradas para exibir na sua interface\n- **Usar**: Seu sistema frontend pode usar essas respostas para agilizar digitação\n\n### Casos de uso:\n- Interfaces web personalizadas de atendimento\n- Apps mobile com sugestões de resposta\n- Sistemas CRM com templates de mensagem\n- Ferramentas de produtividade para atendentes\n\n**Não é um chatbot**: Para respostas automáticas, use os recursos de Chatbot.\n"
    },
    {
      "name": "CRM",
      "description": "Sistema completo de gestão de relacionamento com clientes integrado à API.\n\n**💾 Armazenamento interno**: Todos os dados dos leads ficam salvos diretamente na API,\neliminando a necessidade de bancos de dados externos. Sua aplicação pode focar apenas\nna interface e lógica de negócio.\n\n### Recursos disponíveis:\n- **📋 20+ campos personalizáveis**: Nome, telefone, email, empresa, observações, etc.\n- **🏷️ Sistema de etiquetas**: Organize e categorize seus contatos\n- **🔍 Busca avançada**: Filtre por qualquer campo ou etiqueta\n- **📊 Histórico completo**: Todas as interações ficam registradas automaticamente\n\n### 🎯 Placeholders em mensagens:\nUse variáveis dinâmicas nas mensagens para personalização automática:\n\n```\nOlá {{first_name}}! Empresa: {{lead_field01}}.\nSeu email {{lead_email}} está correto?\nObservações: {{lead_notes}}\n```\n\n### Fluxo típico:\n1. **Captura**: Leads chegam via WhatsApp ou formulários\n2. **Enriquecimento**: Adicione dados usando `/chat/editLead`\n3. **Segmentação**: Organize com etiquetas\n4. **Comunicação**: Envie mensagens personalizadas com placeholders\n5. **Acompanhamento**: Histórico fica salvo automaticamente\n\n**Ideal para**: Vendas, marketing, atendimento, qualificação de leads\n"
    },
    {
      "name": "Mensagem em massa"
    },
    {
      "name": "Integração Chatwoot",
      "description": "**🚧 INTEGRAÇÃO BETA - Sistema de integração com Chatwoot para atendimento unificado**\n\n**⚠️ 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.\n\nEsta 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.\n\n### Recursos disponíveis:\n- 🔧 **Configuração Completa**: Configure URL, tokens e credenciais do Chatwoot\n- 📬 **Sincronização Bidirecional**: Mensagens novas entre WhatsApp e Chatwoot são sincronizadas automaticamente\n- 📱 **Gerenciamento de Contatos**: Sincronização automática de nomes e telefones\n- 🔄 **Atualização LID→PN**: Migração automática de Local ID para Phone Number\n- 🏷️ **Nomes Inteligentes**: Sistema de nomes com til (~) para atualização automática\n- 🚫 **Separação de Grupos**: Opção para ignorar grupos na sincronização\n- 👤 **Assinatura de Mensagens**: Identificação do agente nas mensagens enviadas\n- 🔗 **Webhook Automático**: URL gerada automaticamente para configurar no Chatwoot\n\n### 🏷️ Sistema de Nomes Inteligentes:\n- **Nomes com til (~)**: Atualizados automaticamente quando contato modifica nome no WhatsApp\n- **Nomes específicos**: Para nome fixo, remover til (~) do nome no Chatwoot\n- **Exemplo**: \"~João Silva\" = automático, \"João Silva\" = fixo\n- **Migração LID→PN**: Sem duplicação de conversas durante a transição\n- **Respostas nativas**: Aparecem diretamente no Chatwoot sem marcações externas\n\n### ⚠️ Limitações conhecidas:\n- **Sincronização de histórico**: Não implementada - apenas mensagens novas são sincronizadas\n\n### Casos de uso:\n- Atendimento centralizado no Chatwoot\n- Equipes de suporte com múltiplos agentes\n- Integração com CRM via Chatwoot\n- Centralização de canais de comunicação\n- Gestão automática de contatos e nomes\n\n**Ideal para**: Empresas com equipes de atendimento, call centers, suporte técnico (em ambiente de testes)\n\n**Requer**: Instância do Chatwoot configurada, tokens de API e ambiente de testes\n\n**🚧 Lembre-se**: Integração em BETA - funcionalidades podem mudar sem aviso prévio\n"
    }
  ],
  "paths": {
    "/status": {
      "get": {
        "operationId": "getServerStatus",
        "tags": [
          "Administração"
        ],
        "summary": "Consultar status do servidor",
        "description": "Retorna a versão em execução, a distribuição das instâncias por estado e\num resumo da saúde do servidor. Este endpoint é público e não exige token.\n",
        "security": [],
        "responses": {
          "200": {
            "description": "Status atual do servidor",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "info",
                    "build",
                    "instance_counts",
                    "status"
                  ],
                  "properties": {
                    "info": {
                      "type": "string",
                      "example": "Server health check completed"
                    },
                    "build": {
                      "type": "object",
                      "required": [
                        "version",
                        "revision",
                        "date"
                      ],
                      "properties": {
                        "version": {
                          "type": "string",
                          "example": "2.2.2"
                        },
                        "revision": {
                          "type": "string",
                          "example": "a1b2c3d4e"
                        },
                        "date": {
                          "type": "string",
                          "example": "2026-08-31"
                        }
                      }
                    },
                    "instance_counts": {
                      "type": "object",
                      "required": [
                        "total",
                        "connected",
                        "reconnecting",
                        "connecting",
                        "queued_reconnect",
                        "disconnected",
                        "hibernated",
                        "other",
                        "observed_at"
                      ],
                      "properties": {
                        "total": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "connected": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "reconnecting": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "connecting": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "queued_reconnect": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "disconnected": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "hibernated": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "other": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "observed_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    },
                    "status": {
                      "type": "object",
                      "required": [
                        "server_status",
                        "total_instances",
                        "last_check",
                        "dc",
                        "node"
                      ],
                      "properties": {
                        "server_status": {
                          "type": "string",
                          "example": "running"
                        },
                        "total_instances": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "last_check": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "dc": {
                          "type": "string"
                        },
                        "node": {
                          "type": "string"
                        },
                        "database_status": {
                          "type": "string",
                          "description": "Presente quando a verificação do banco está degradada."
                        },
                        "database_error": {
                          "type": "string",
                          "description": "Diagnóstico do banco quando disponível."
                        },
                        "checked_instance": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "is_healthy": {
                              "type": "boolean"
                            },
                            "connection_status": {
                              "type": "string"
                            },
                            "message": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/instance/create": {
      "post": {
        "operationId": "createInstance",
        "tags": [
          "Administraçã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 exibido no aparelho ao conectar a instância. Se omitido, a API usa o nome padrão.",
                    "example": "Minha Empresa"
                  },
                  "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"
                  },
                  "proxy_managed_country": {
                    "type": "string",
                    "pattern": "^[a-z]{2}$",
                    "description": "País do proxy regional em ISO alpha-2 minúsculo. Use o valor retornado por `GET /proxy-managed/countries`.",
                    "example": "br"
                  },
                  "proxy_managed_state": {
                    "type": "string",
                    "description": "Estado/subdivisão da cidade, quando `GET /proxy-managed/cities` retornar `state`.",
                    "example": "sp"
                  },
                  "proxy_managed_city": {
                    "type": "string",
                    "description": "Cidade do proxy regional. Use `cities[].value` retornado por `GET /proxy-managed/cities`.",
                    "example": "campinas"
                  }
                },
                "required": [
                  "name"
                ]
              },
              "examples": {
                "basica": {
                  "summary": "Criar com região padrão",
                  "value": {
                    "name": "minha-instancia"
                  }
                },
                "com_regiao": {
                  "summary": "Criar com proxy regional",
                  "value": {
                    "name": "minha-instancia",
                    "proxy_managed_country": "br",
                    "proxy_managed_state": "sp",
                    "proxy_managed_city": "campinas"
                  }
                }
              }
            }
          }
        },
        "description": "Cria uma nova instância do WhatsApp. Para criar uma instância você precisa:\n\n1. Ter um admintoken válido\n2. Enviar pelo menos o nome da instância\n3. A instância será criada desconectada\n4. Será gerado um token único para autenticação\n\nApós criar a instância, guarde o token retornado pois ele será necessário\npara todas as outras operações.\n\nPara escolher o proxy regional desde a criação, consulte\n`GET /proxy-managed/countries` e `GET /proxy-managed/cities`. Envie\n`proxy_managed_country` e `proxy_managed_city` juntos; inclua\n`proxy_managed_state` quando a cidade retornada tiver `state`.\nSe os campos forem omitidos, a API usa a região padrão do servidor.\n\nEstados possíveis da instância:\n\n- `disconnected`: Desconectado do WhatsApp\n- `connecting`: Em processo de conexão\n- `connected`: Conectado e autenticado\n- `hibernated`: Sessão pausada, com credenciais preservadas para reconexão\n\nCampos administrativos (adminField01/adminField02) são opcionais e podem ser usados para armazenar metadados personalizados. \nOS 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.\n",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "response": {
                      "type": "string",
                      "example": "Instance created successfully"
                    },
                    "instance": {
                      "$ref": "#/components/schemas/Instance"
                    },
                    "status": {
                      "type": "object",
                      "properties": {
                        "connected": {
                          "type": "boolean",
                          "example": false
                        },
                        "loggedIn": {
                          "type": "boolean",
                          "example": false
                        },
                        "jid": {
                          "type": "null"
                        }
                      }
                    },
                    "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."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payload ou região de proxy inválidos"
          },
          "401": {
            "description": "Token inválido/expirado"
          },
          "429": {
            "description": "Limite de instâncias atingido"
          },
          "500": {
            "description": "Erro interno"
          },
          "503": {
            "description": "Catálogo de regiões temporariamente indisponível"
          }
        }
      }
    },
    "/instance/token/rotate": {
      "post": {
        "operationId": "rotateInstanceToken",
        "tags": [
          "Administração"
        ],
        "summary": "Rotacionar token da instância",
        "security": [
          {
            "admintoken": []
          }
        ],
        "description": "Gera um novo `token` para uma instância e invalida o anterior.\n\nExige `confirm_impacts: true`, não reinicia a aplicação e não faz reset da sessão WhatsApp.\n\nRevise os campos `impacts` e `warnings` e atualize o novo token no Chatwoot,\nproxy relay/APK e demais clientes que usavam a credencial anterior. Conexões\nHTTP ou SSE autenticadas com o token antigo devem ser abertas novamente com\na nova credencial. A sessão do WhatsApp continua pareada e não exige uma nova\nleitura do QR Code. O novo token também pode ser consultado depois em\n`/instance/all` com `admintoken`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "ID da instância que terá o token rotacionado.",
                    "example": "r183e2ef9597845"
                  },
                  "confirm_impacts": {
                    "type": "boolean",
                    "description": "Confirma que os impactos operacionais foram revisados.",
                    "example": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token da instância rotacionado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "message",
                    "instance_id",
                    "token",
                    "previous_token_invalidated",
                    "restart_requested",
                    "rotated_at",
                    "impacts",
                    "warnings"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "Instance token rotated successfully"
                    },
                    "instance_id": {
                      "type": "string",
                      "example": "r183e2ef9597845"
                    },
                    "token": {
                      "type": "string",
                      "description": "Novo token da instância.",
                      "example": "6faefb58-1270-46b8-a3b1-620e5148ceda"
                    },
                    "previous_token_invalidated": {
                      "type": "boolean",
                      "example": true
                    },
                    "restart_requested": {
                      "type": "boolean",
                      "description": "Sempre `false`; a rotação não reinicia a aplicação.",
                      "example": false
                    },
                    "rotated_at": {
                      "type": "integer",
                      "format": "int64",
                      "description": "Timestamp Unix em milissegundos.",
                      "example": 1776892800000
                    },
                    "impacts": {
                      "type": "object",
                      "required": [
                        "chatwoot_reconfigure_requested",
                        "proxy_relay_reconnect_required",
                        "long_lived_clients_closed"
                      ],
                      "properties": {
                        "chatwoot_reconfigure_requested": {
                          "type": "boolean",
                          "example": true
                        },
                        "proxy_relay_reconnect_required": {
                          "type": "boolean",
                          "example": true
                        },
                        "long_lived_clients_closed": {
                          "type": "boolean",
                          "example": true
                        }
                      }
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "Verify Chatwoot and proxy relay clients after rotation."
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payload inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "id is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "admintoken inválido ou ausente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Rotação bloqueada para container gratuito/demo",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Instance token rotation is disabled for free containers"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Instance not found"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Confirmação de impactos obrigatória",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "requires_confirmation",
                    "instance_id",
                    "impacts",
                    "warnings"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Instance token rotation requires confirm_impacts=true"
                    },
                    "requires_confirmation": {
                      "type": "boolean",
                      "example": true
                    },
                    "instance_id": {
                      "type": "string",
                      "example": "r183e2ef9597845"
                    },
                    "impacts": {
                      "type": "object",
                      "properties": {
                        "chatwoot_reconfigure_requested": {
                          "type": "boolean",
                          "example": true
                        },
                        "proxy_relay_reconnect_required": {
                          "type": "boolean",
                          "example": true
                        },
                        "long_lived_clients_closed": {
                          "type": "boolean",
                          "example": false
                        }
                      }
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro interno ao rotacionar token da instância",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Failed to rotate instance token"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/instance/all": {
      "get": {
        "operationId": "listAllInstances",
        "tags": [
          "Administração"
        ],
        "summary": "Listar todas as instâncias",
        "security": [
          {
            "admintoken": []
          }
        ],
        "description": "Retorna uma lista completa de todas as instâncias do sistema, incluindo:\n- ID e nome de cada instância\n- Status atual (disconnected, connecting, connected, hibernated)\n- Data de criação\n- Última desconexão e motivo\n- Informações de perfil (se conectado)\n\nRequer permissões de administrador.\n",
        "responses": {
          "200": {
            "description": "Lista de instâncias retornada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/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": "uazapi",
                    "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 a conexão da instância com o WhatsApp.\n\n- Sem `phone`, retorna um QR Code para leitura no celular.\n- Com `phone`, retorna um código de pareamento para esse número.\n\nA instância permanece em `connecting` até o pareamento ser confirmado ou o\nprazo expirar. Acompanhe a evolução em `GET /instance/status`; não repita a\nchamada enquanto o processo estiver em andamento.\n\nApós a conexão, o histórico disponível começa a chegar pelo evento\n`history` e pode ser consultado em `POST /message/find` e `POST /chat/find`.\nPara escolher uma região de conexão, consulte primeiro\n`GET /proxy-managed/countries` e `GET /proxy-managed/cities` e reutilize os\nvalores retornados nos campos `proxy_managed_*`.\n",
        "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}$"
                  },
                  "browser": {
                    "type": "string",
                    "description": "Browser usado no ciclo de autenticação/conexão. `auto` preserva um perfil válido já salvo ou escolhe Safari, Firefox ou Edge para novas conexões.",
                    "enum": [
                      "auto",
                      "safari",
                      "firefox",
                      "edge",
                      "chrome"
                    ],
                    "default": "auto",
                    "example": "auto"
                  },
                  "systemName": {
                    "type": "string",
                    "description": "Sistema/nome exibido no celular em aparelhos conectados. Ajuda a identificar a instância no WhatsApp; para maior estabilidade, recomendamos deixar em branco e usar o valor padrão do navegador escolhido.",
                    "example": "Minha Empresa"
                  },
                  "proxy_managed_country": {
                    "type": "string",
                    "description": "País desejado para o proxy regional, em ISO alpha-2 minúsculo. Use o valor retornado por `GET /proxy-managed/countries`.",
                    "example": "br",
                    "pattern": "^[a-z]{2}$"
                  },
                  "proxy_managed_state": {
                    "type": "string",
                    "description": "Estado/subdivisão da cidade escolhida. Quando o país/cidade exigir desambiguação, use o campo `state` retornado por `GET /proxy-managed/cities?country=br`.",
                    "example": "sp"
                  },
                  "proxy_managed_city": {
                    "type": "string",
                    "description": "Cidade escolhida para o proxy regional. Use sempre o campo `value` retornado por `GET /proxy-managed/cities`.",
                    "example": "campinas"
                  }
                }
              },
              "examples": {
                "qr_code_brasil_com_proxy_regional": {
                  "summary": "QR code com proxy regional em Campinas/SP",
                  "value": {
                    "browser": "auto",
                    "systemName": "Minha Empresa",
                    "proxy_managed_country": "br",
                    "proxy_managed_state": "sp",
                    "proxy_managed_city": "campinas"
                  }
                }
              }
            }
          }
        },
        "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": "#/components/schemas/Instance",
                      "description": "Detalhes completos da instância"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token inválido/expirado"
          },
          "404": {
            "description": "Instância não encontrada"
          },
          "409": {
            "description": "Já existe um fluxo de conexão em andamento para a instância"
          },
          "429": {
            "description": "Limite de conexões simultâneas atingido"
          },
          "500": {
            "description": "Erro interno"
          },
          "503": {
            "description": "Capacidade de conexão temporariamente indisponível",
            "headers": {
              "Retry-After": {
                "description": "Tempo recomendado, em segundos, para tentar novamente.",
                "schema": {
                  "type": "integer",
                  "example": 5
                }
              }
            }
          }
        }
      }
    },
    "/instance/disconnect": {
      "post": {
        "operationId": "disconnectInstance",
        "tags": [
          "Instancia"
        ],
        "summary": "Desconectar instância",
        "description": "Desconecta a conta do WhatsApp atualmente conectada, encerrando a sessão atual.\nEsta operação:\n\n- Encerra a conexão ativa\n\n- Requer novo QR code para reconectar\n\n\nDiferenças entre desconectar e hibernar:\n\n- Desconectar: Encerra completamente a sessão, exigindo novo login\n\n- Hibernar: Mantém a sessão ativa, apenas pausa a conexão\n\n\nUse este endpoint para:\n\n1. Encerrar completamente uma sessão\n\n2. Forçar uma nova autenticação\n\n3. Limpar credenciais da sessão atual\n\n4. Reiniciar o processo de conexão\n\n\nEstados possíveis após desconectar:\n\n- `disconnected`: Desconectado do WhatsApp\n\n- `connecting`: Em processo de reconexão (após usar /instance/connect)\n",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "instance": {
                      "$ref": "#/components/schemas/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 a conexão da instância",
        "description": "Solicita uma retomada controlada da conexão sem apagar a instância nem o\npareamento existente. Use quando a sessão estiver presa ou os envios não\nestiverem progredindo.\n\nComportamentos possíveis:\n- inicia um novo reset quando a instância está apta\n- informa que um reset já está em andamento\n- informa que existe cooldown ativo entre resets\n- retorna erro quando a sessão não pode ser recuperada ou quando a política de\n  reconexão bloqueia a operação\n\nA resposta informa:\n- `instanceId`: ID da instância autenticada\n- `resetting`: se há reset em andamento no momento\n- `queuedRecoveryAttempted`: se mensagens pendentes também entraram na tentativa de recuperação\n",
        "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:\n- Estado da conexão\n- QR code atualizado (se em processo de conexão)\n- Código de pareamento (se disponível)\n- Informações da última desconexão\n- Detalhes completos da instância\n\nEste endpoint é particularmente útil para:\n1. Monitorar o progresso da conexão\n2. Obter QR codes atualizados durante o processo de conexão\n3. Verificar o estado atual da instância\n4. Identificar problemas de conexão\n\nEstados possíveis:\n- `disconnected`: Desconectado do WhatsApp\n- `connecting`: Em processo de conexão (aguardando QR code ou código de pareamento)\n- `connected`: Conectado e autenticado com sucesso\n- `hibernated`: Sessão pausada, com credenciais preservadas para reconexão\n",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "instance": {
                      "$ref": "#/components/schemas/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.\n\nEste endpoint é útil para:\n- diagnosticar erros de envio com `provider_code: 463`\n- verificar se o WhatsApp indica que a conta atualmente conectada pode iniciar novas conversas\n- exibir informações de suporte antes de campanhas ou envios de alto volume\n\nA resposta consolida duas fontes internas do WhatsApp:\n- `new_chat_message_capping`: limite de mensagens para iniciar novas conversas\n- `reachout_timelock`: restrição temporária para iniciar novas conversas\n\nObservações:\n- este endpoint depende de sessão ativa e conectada\n- se o WhatsApp não retornar os dados esperados, a resposta pode marcar os blocos como indisponíveis via `available: false` e `lookup_error`\n- `message` descreve o estado atual da conta atualmente conectada\n- `provider_message` detalha o motivo reportado pelo WhatsApp quando houver restrição ativa\n",
        "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.\nPode ser `null` quando não foi possível concluir o diagnóstico.\n",
                      "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": "Nomear campos personalizados de leads",
        "description": "Configura os rótulos dos 20 campos personalizados de leads de uma instância.\nEsta operação não altera os valores armazenados nos chats e não cria aliases\npara placeholders.\n\nOs campos disponíveis são `lead_field01` a `lead_field20`. Mesmo depois de\ndefinir um rótulo, mensagens devem usar o nome original do slot. Por exemplo,\nse `lead_field01` for rotulado como `empresa`, o placeholder continua sendo\n`{{lead_field01}}`; `{{empresa}}` não será substituído.\n\nUse os rótulos para informar à sua interface o significado de cada slot. Os\nvalores de cada lead são gravados pelas operações de CRM no respectivo\n`lead_fieldXX`.\n\nExemplo de requisição:\n```json\n{\n  \"lead_field01\": \"nome\",\n  \"lead_field02\": \"email\",\n  \"lead_field03\": \"telefone\",\n  \"lead_field04\": \"cidade\",\n  \"lead_field05\": \"estado\",\n  \"lead_field06\": \"idade\",\n  \"lead_field07\": \"interesses\",\n  \"lead_field08\": \"origem\",\n  \"lead_field09\": \"status\",\n  \"lead_field10\": \"valor\",\n  \"lead_field11\": \"observacoes\",\n  \"lead_field12\": \"ultima_interacao\",\n  \"lead_field13\": \"proximo_contato\",\n  \"lead_field14\": \"vendedor\",\n  \"lead_field15\": \"produto_interesse\",\n  \"lead_field16\": \"fonte_captacao\",\n  \"lead_field17\": \"score\",\n  \"lead_field18\": \"tags\",\n  \"lead_field19\": \"historico\",\n  \"lead_field20\": \"custom\"\n}\n```\n\nExemplo de resposta:\n```json\n{\n  \"success\": true,\n  \"message\": \"Custom fields updated successfully\",\n  \"instance\": {\n    \"id\": \"r183e2ef9597845\",\n    \"name\": \"minha-instancia\",\n    \"fieldsMap\": {\n      \"lead_field01\": \"nome\",\n      \"lead_field02\": \"email\",\n      \"lead_field03\": \"telefone\",\n      \"lead_field04\": \"cidade\",\n      \"lead_field05\": \"estado\",\n      \"lead_field06\": \"idade\",\n      \"lead_field07\": \"interesses\",\n      \"lead_field08\": \"origem\",\n      \"lead_field09\": \"status\",\n      \"lead_field10\": \"valor\",\n      \"lead_field11\": \"observacoes\",\n      \"lead_field12\": \"ultima_interacao\",\n      \"lead_field13\": \"proximo_contato\",\n      \"lead_field14\": \"vendedor\",\n      \"lead_field15\": \"produto_interesse\",\n      \"lead_field16\": \"fonte_captacao\",\n      \"lead_field17\": \"score\",\n      \"lead_field18\": \"tags\",\n      \"lead_field19\": \"historico\",\n      \"lead_field20\": \"custom\"\n    }\n  }\n}\n```\n\nErros comuns:\n- 400: Campos inválidos ou payload mal formatado\n- 401: Token inválido ou expirado\n- 404: Instância não encontrada\n- 500: Erro ao atualizar campos no banco de dados\n\nEnvie o mapa completo. Campos omitidos são recebidos como vazios e podem\nsubstituir rótulos configurados anteriormente.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "lead_field01": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 01",
                    "maxLength": 255
                  },
                  "lead_field02": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 02",
                    "maxLength": 255
                  },
                  "lead_field03": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 03",
                    "maxLength": 255
                  },
                  "lead_field04": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 04",
                    "maxLength": 255
                  },
                  "lead_field05": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 05",
                    "maxLength": 255
                  },
                  "lead_field06": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 06",
                    "maxLength": 255
                  },
                  "lead_field07": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 07",
                    "maxLength": 255
                  },
                  "lead_field08": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 08",
                    "maxLength": 255
                  },
                  "lead_field09": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 09",
                    "maxLength": 255
                  },
                  "lead_field10": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 10",
                    "maxLength": 255
                  },
                  "lead_field11": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 11",
                    "maxLength": 255
                  },
                  "lead_field12": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 12",
                    "maxLength": 255
                  },
                  "lead_field13": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 13",
                    "maxLength": 255
                  },
                  "lead_field14": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 14",
                    "maxLength": 255
                  },
                  "lead_field15": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 15",
                    "maxLength": 255
                  },
                  "lead_field16": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 16",
                    "maxLength": 255
                  },
                  "lead_field17": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 17",
                    "maxLength": 255
                  },
                  "lead_field18": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 18",
                    "maxLength": 255
                  },
                  "lead_field19": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 19",
                    "maxLength": 255
                  },
                  "lead_field20": {
                    "type": "string",
                    "description": "Rótulo do campo personalizado 20",
                    "maxLength": 255
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/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 usado para identificar a instância em painéis, listagens e\nintegrações. A operação não altera o nome do perfil no WhatsApp; para isso,\nuse `POST /profile/name`. O nome da instância não precisa ser único.\n",
        "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": "#/components/schemas/Instance"
                }
              }
            }
          },
          "401": {
            "description": "Token inválido/expirado"
          },
          "404": {
            "description": "Instância não encontrada"
          },
          "500": {
            "description": "Erro interno"
          }
        }
      }
    },
    "/instance/updateAdminFields": {
      "post": {
        "operationId": "updateAdminFields",
        "tags": [
          "Administração"
        ],
        "summary": "Atualizar campos administrativos",
        "security": [
          {
            "admintoken": []
          }
        ],
        "description": "Atualiza os campos administrativos (adminField01/adminField02) de uma instância.\n\nCampos administrativos são opcionais e podem ser usados para armazenar metadados personalizados. \nEsses campos ficam associados à instância e podem guardar referências úteis\npara integrações e sistemas administrativos do cliente.\nOS 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.\n",
        "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": "#/components/schemas/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": "Mostra a configuração desejada e a rota de conexão usada pela instância no\nmomento. Use para confirmar se o proxy escolhido está ativo ou se uma rota\nalternativa foi aplicada para preservar a conexão.\n\n- `mode` informa a configuração escolhida: `custom`, `internal` ou `none`.\n- `effective_mode` informa a conexão em uso: `custom`, `internal` ou `direct`.\n- `fallback.active` indica que a rota principal não está disponível.\n- `proxy_url` retorna a URL configurada com credenciais mascaradas.\n- `last_test_error` ajuda a diagnosticar a última falha conhecida.\n\nEm condições normais, `mode` e `effective_mode` correspondem. Durante uma\ncontingência, eles podem divergir sem alterar a preferência salva. Não use\neste endpoint em polling contínuo; acompanhe também `GET /instance/status`.\n",
        "security": [
          {
            "token": []
          }
        ],
        "responses": {
          "200": {
            "description": "Configuração de proxy recuperada com sucesso",
            "content": {
              "application/json": {
                "examples": {
                  "custom_active": {
                    "summary": "Proxy do cliente ativo",
                    "value": {
                      "mode": "custom",
                      "effective_mode": "custom",
                      "fallback": {
                        "active": false,
                        "reason": "",
                        "since": 0
                      },
                      "proxy_url": "http://***:***@cliente-proxy.example:8080",
                      "proxy_fallback": "internal",
                      "managed": false,
                      "last_test_at": 0,
                      "last_test_error": "",
                      "validation_error": false
                    }
                  },
                  "custom_internal_fallback": {
                    "summary": "Proxy do cliente falhou e a sessão subiu no proxy interno",
                    "value": {
                      "mode": "custom",
                      "effective_mode": "internal",
                      "effective_detail": "managed_pool",
                      "fallback": {
                        "active": true,
                        "reason": "custom_failed_internal:dial tcp timeout",
                        "since": 1760000000000
                      },
                      "proxy_url": "http://***:***@cliente-proxy.example:8080",
                      "proxy_fallback": "internal",
                      "managed": true,
                      "last_test_at": 1760000000000,
                      "last_test_error": "dial tcp timeout",
                      "validation_error": true
                    }
                  },
                  "custom_direct_fallback": {
                    "summary": "Proxy do cliente falhou e a sessão caiu para direto como último recurso",
                    "value": {
                      "mode": "custom",
                      "effective_mode": "direct",
                      "fallback": {
                        "active": true,
                        "reason": "custom_failed_direct:dial tcp timeout",
                        "since": 1760000005000
                      },
                      "proxy_url": "http://***:***@cliente-proxy.example:8080",
                      "proxy_fallback": "internal",
                      "managed": false,
                      "last_test_at": 1760000005000,
                      "last_test_error": "dial tcp timeout",
                      "validation_error": true
                    }
                  },
                  "internal_dedicated_route": {
                    "summary": "Modo interno usando rota interna dedicada",
                    "value": {
                      "mode": "internal",
                      "effective_mode": "internal",
                      "effective_detail": "internal_route",
                      "fallback": {
                        "active": false,
                        "reason": "",
                        "since": 0
                      },
                      "proxy_url": "",
                      "proxy_fallback": "internal",
                      "managed": true,
                      "last_test_at": 0,
                      "last_test_error": "",
                      "validation_error": false
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "example": {
                    "mode": "custom",
                    "effective_mode": "internal",
                    "effective_detail": "managed_pool",
                    "fallback": {
                      "active": true,
                      "reason": "custom_failed_internal:dial tcp timeout",
                      "since": 1760000000000
                    },
                    "proxy_url": "http://***:***@cliente-proxy.example:8080",
                    "proxy_fallback": "internal",
                    "managed": true,
                    "last_test_at": 1760000000000,
                    "last_test_error": "dial tcp timeout",
                    "validation_error": true
                  },
                  "properties": {
                    "mode": {
                      "type": "string",
                      "enum": [
                        "custom",
                        "internal",
                        "none"
                      ],
                      "description": "Intenção persistida do cliente. Representa o modo salvo na instância, não necessariamente o transporte em uso agora.",
                      "example": "custom"
                    },
                    "effective_mode": {
                      "type": "string",
                      "enum": [
                        "custom",
                        "internal",
                        "direct"
                      ],
                      "description": "Conexão efetivamente usada pela sessão neste momento.",
                      "example": "internal"
                    },
                    "effective_detail": {
                      "type": "string",
                      "enum": [
                        "managed_pool",
                        "internal_route",
                        "relay"
                      ],
                      "description": "Detalhe opcional do transporte atual.\n`managed_pool` = proxy interno gerenciado.\n`internal_route` = rota interna dedicada do ambiente.\n`relay` = túnel relay do cliente.\nQuando não há detalhe adicional, o campo é omitido.\n",
                      "example": "managed_pool"
                    },
                    "fallback": {
                      "type": "object",
                      "description": "Estado da contingência. Fica ativo quando a instância precisou sair da rota principal configurada.",
                      "properties": {
                        "active": {
                          "type": "boolean",
                          "description": "Indica se a instância está operando em fallback neste momento.",
                          "example": true
                        },
                        "reason": {
                          "type": "string",
                          "description": "Motivo interno resumido do fallback atual, útil para observabilidade e suporte.",
                          "example": "custom_failed_internal:dial tcp timeout"
                        },
                        "since": {
                          "type": "integer",
                          "description": "Timestamp Unix em milissegundos desde quando o fallback atual está ativo.",
                          "example": 1760000000000
                        }
                      }
                    },
                    "proxy_url": {
                      "type": "string",
                      "description": "URL mascarada do proxy persistido. Em fallback de proxy custom, continua mostrando a URL do cliente; não troca para o proxy efetivo de contingência.",
                      "example": "http://***:***@cliente-proxy.example:8080"
                    },
                    "proxy_fallback": {
                      "type": "string",
                      "description": "Política de contingência persistida para `mode=custom`.\nValores aceitos:\n  - `internal`\n  - `never`\n  - uma URL de proxy HTTP/HTTPS/SOCKS para contingência explícita\n",
                      "example": "internal"
                    },
                    "managed": {
                      "type": "boolean",
                      "description": "Campo legado indicando participação da infraestrutura interna. Pode ficar `true` tanto em `mode=internal` quanto em fallback interno de `mode=custom`.",
                      "example": true
                    },
                    "last_test_at": {
                      "type": "integer",
                      "description": "Timestamp Unix em milissegundos do último teste ou da última falha persistida.",
                      "example": 1760000000000
                    },
                    "last_test_error": {
                      "type": "string",
                      "description": "Último erro persistido para diagnóstico. String vazia significa ausência de erro salvo.",
                      "example": "dial tcp timeout"
                    },
                    "validation_error": {
                      "type": "boolean",
                      "description": "Indica se `last_test_error` está preenchido.",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "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": "Define explicitamente um dos três estados aceitos:\n  - `mode=custom`: usa um proxy próprio informado em `proxy_url`;\n  - `mode=internal`: usa a infraestrutura interna; ou\n  - `mode=none`: conexão direta, permitida apenas com `confirm_no_proxy=true`.\n\nImportante: `POST /instance/proxy` confirma que a configuração foi salva, não que o proxy já foi comprovado em uso.\nA validação operacional principal acontece no próximo ciclo real de conexão da instância.\n\nEm termos práticos:\n  - `200 OK` aqui = configuração persistida com sucesso;\n  - falhas reais de conectividade podem aparecer depois; e\n  - para observar o estado real, consulte `GET /instance/proxy` e leia:\n    - `effective_mode`\n    - `effective_detail`\n    - `fallback.active`\n    - `last_test_error`\n    - `validation_error`\n\nQuando `mode=custom`, você também pode definir a contingência via `proxy_fallback`:\n  - `internal`: tenta a infraestrutura interna e, se ainda assim falhar, pode usar direto como último recurso;\n  - `never`: não usa contingência; ou\n  - uma URL de proxy de contingência controlada pelo próprio cliente.\n\nQuando `mode=internal`, `rotate_now: true` troca imediatamente o proxy interno persistido.\nSe houver mais de uma origem interna disponível, a plataforma escolhe outra origem sem expor o fornecedor.\nSe houver apenas uma origem, troca apenas o proxy/IP dentro dessa origem.\n\nProtocolos aceitos em URLs de proxy customizado:\n  - `http://usuario:senha@host:porta`\n  - `https://usuario:senha@host:porta`\n  - `socks5://usuario:senha@host:porta`\n  - `socks5h://usuario:senha@host:porta`\n\nO esquema `socks://` genérico não é aceito. Para proxies SOCKS, use `socks5://` ou `socks5h://`.\n",
        "security": [
          {
            "token": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "examples": {
                "custom_with_internal_fallback": {
                  "summary": "Proxy customizado com fallback interno",
                  "value": {
                    "mode": "custom",
                    "proxy_url": "http://usuario:senha@proxy-do-cliente.example:8080",
                    "proxy_fallback": "internal"
                  }
                },
                "custom_with_explicit_backup_proxy": {
                  "summary": "Proxy customizado com proxy de contingência próprio",
                  "value": {
                    "mode": "custom",
                    "proxy_url": "http://usuario:senha@proxy-principal.example:8080",
                    "proxy_fallback": "socks5://backup:senha@proxy-backup.example:1080"
                  }
                },
                "internal_now": {
                  "summary": "Modo interno",
                  "value": {
                    "mode": "internal"
                  }
                },
                "internal_rotate_now": {
                  "summary": "Rotacionar proxy interno agora",
                  "value": {
                    "mode": "internal",
                    "rotate_now": true
                  }
                },
                "no_proxy": {
                  "summary": "Direto explícito",
                  "value": {
                    "mode": "none",
                    "confirm_no_proxy": true
                  }
                }
              },
              "schema": {
                "type": "object",
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "custom",
                      "internal",
                      "none"
                    ],
                    "description": "Campo canônico para definir a estratégia de proxy."
                  },
                  "proxy_url": {
                    "type": "string",
                    "description": "Obrigatório quando `mode=custom`.\nProtocolos aceitos: `http://`, `https://`, `socks5://` e `socks5h://`.\nO esquema `socks://` genérico não é suportado; use `socks5://` ou `socks5h://`.\n",
                    "example": "http://usuario:senha@ip:porta"
                  },
                  "proxy_fallback": {
                    "type": "string",
                    "description": "Política de contingência para `mode=custom`.\nAceita `internal`, `never` ou uma URL de proxy de contingência usando `http://`, `https://`, `socks5://` ou `socks5h://`.\n"
                  },
                  "confirm_no_proxy": {
                    "type": "boolean",
                    "description": "Obrigatório quando `mode=none`."
                  },
                  "rotate_now": {
                    "type": "boolean",
                    "description": "Quando `true` com `mode=internal`, troca imediatamente o proxy interno persistido sem expor o fornecedor usado.",
                    "default": false
                  },
                  "proxy_managed_country": {
                    "type": "string",
                    "description": "País ISO alpha-2 usado para validar a saída do proxy gerenciado. Use somente com `mode=internal`.",
                    "example": "br"
                  },
                  "proxy_managed_state": {
                    "type": "string",
                    "description": "Estado/UF do alvo geográfico retornado pelo catálogo de cidades.",
                    "example": "sp"
                  },
                  "proxy_managed_city": {
                    "type": "string",
                    "description": "Slug da cidade retornado por `GET /proxy-managed/cities`.",
                    "example": "campinas"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Proxy configurado com sucesso",
            "content": {
              "application/json": {
                "examples": {
                  "custom_internal_fallback_saved": {
                    "summary": "Configuração salva; o uso real será confirmado no próximo ciclo de conexão",
                    "value": {
                      "details": "Proxy configurado",
                      "proxy": {
                        "mode": "custom",
                        "effective_mode": "custom",
                        "fallback": {
                          "active": false,
                          "reason": "",
                          "since": 0
                        },
                        "proxy_url": "http://***:***@proxy-do-cliente.example:8080",
                        "proxy_fallback": "internal",
                        "managed": false,
                        "last_test_at": 0,
                        "last_test_error": "",
                        "validation_error": false
                      },
                      "restart_requested": true
                    }
                  },
                  "after_connect_failure_example": {
                    "summary": "Exemplo do que o GET pode mostrar depois se o proxy salvo falhar",
                    "value": {
                      "details": "Proxy configurado",
                      "proxy": {
                        "mode": "custom",
                        "effective_mode": "custom",
                        "fallback": {
                          "active": false,
                          "reason": "",
                          "since": 0
                        },
                        "proxy_url": "http://***:***@proxy-do-cliente.example:8080",
                        "proxy_fallback": "internal",
                        "managed": false,
                        "last_test_at": 0,
                        "last_test_error": "",
                        "validation_error": false
                      },
                      "restart_requested": true
                    }
                  },
                  "direct_explicit": {
                    "summary": "Direto explícito",
                    "value": {
                      "details": "Proxy configurado",
                      "proxy": {
                        "mode": "none",
                        "effective_mode": "direct",
                        "fallback": {
                          "active": false,
                          "reason": "",
                          "since": 0
                        },
                        "proxy_url": "",
                        "proxy_fallback": "internal",
                        "managed": false,
                        "last_test_at": 0,
                        "last_test_error": "",
                        "validation_error": false
                      }
                    }
                  },
                  "internal_rotated": {
                    "summary": "Proxy interno rotacionado",
                    "value": {
                      "details": "Proxy configurado",
                      "rotated": true,
                      "proxy": {
                        "mode": "internal",
                        "effective_mode": "internal",
                        "effective_detail": "managed_pool",
                        "fallback": {
                          "active": false,
                          "reason": "",
                          "since": 0
                        },
                        "proxy_url": "managed_pool://hidden",
                        "proxy_fallback": "internal",
                        "managed": true,
                        "last_test_at": 0,
                        "last_test_error": "",
                        "validation_error": false
                      }
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "example": {
                    "details": "Proxy configurado",
                    "proxy": {
                      "mode": "custom",
                      "effective_mode": "custom",
                      "fallback": {
                        "active": false,
                        "reason": "",
                        "since": 0
                      },
                      "proxy_url": "http://***:***@proxy-do-cliente.example:8080",
                      "proxy_fallback": "internal",
                      "managed": false,
                      "last_test_at": 0,
                      "last_test_error": "",
                      "validation_error": false
                    },
                    "restart_requested": true
                  },
                  "properties": {
                    "details": {
                      "type": "string",
                      "example": "Proxy configurado"
                    },
                    "proxy": {
                      "type": "object",
                      "properties": {
                        "mode": {
                          "type": "string",
                          "enum": [
                            "custom",
                            "internal",
                            "none"
                          ],
                          "description": "Intenção persistida do cliente após a gravação."
                        },
                        "effective_mode": {
                          "type": "string",
                          "enum": [
                            "custom",
                            "internal",
                            "direct"
                          ],
                          "description": "Transporte efetivo no momento da resposta."
                        },
                        "effective_detail": {
                          "type": "string",
                          "enum": [
                            "managed_pool",
                            "internal_route",
                            "relay"
                          ],
                          "description": "Detalhe complementar do transporte efetivo. Quando não há detalhe adicional, o campo é omitido."
                        },
                        "fallback": {
                          "type": "object",
                          "description": "Estado atual da contingência.",
                          "properties": {
                            "active": {
                              "type": "boolean",
                              "description": "Indica se a instância está operando em fallback neste momento."
                            },
                            "reason": {
                              "type": "string",
                              "description": "Motivo interno resumido do fallback atual."
                            },
                            "since": {
                              "type": "integer",
                              "description": "Timestamp Unix em milissegundos desde quando o fallback atual está ativo."
                            }
                          }
                        },
                        "proxy_url": {
                          "type": "string",
                          "description": "URL mascarada do proxy persistido."
                        },
                        "proxy_fallback": {
                          "type": "string",
                          "description": "Política de contingência persistida para `mode=custom`."
                        },
                        "managed": {
                          "type": "boolean",
                          "description": "Campo legado ligado ao uso da infraestrutura interna."
                        },
                        "last_test_at": {
                          "type": "integer",
                          "description": "Timestamp do último teste/erro persistido."
                        },
                        "last_test_error": {
                          "type": "string",
                          "description": "Último erro persistido para diagnóstico."
                        },
                        "validation_error": {
                          "type": "boolean",
                          "description": "Indica se `last_test_error` está preenchido."
                        }
                      }
                    },
                    "restart_requested": {
                      "type": "boolean",
                      "description": "Indica se uma reinicialização da conexão foi solicitada para aplicar o proxy."
                    },
                    "rotated": {
                      "type": "boolean",
                      "description": "Presente como `true` quando `rotate_now` troca o proxy interno com sucesso."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payload inválido ou falha na validação do proxy",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "confirm_no_proxy é obrigatório para desabilitar proxy"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token inválido ou expirado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Não há proxy alternativo disponível para rotação interna",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "nao foi possivel rotacionar proxy interno: nenhum proxy alternativo disponível para rotação"
                    }
                  }
                }
              }
            }
          },
          "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"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/proxy-managed/countries": {
      "get": {
        "operationId": "listRegionCountries",
        "tags": [
          "Proxy"
        ],
        "summary": "Proxy Interno - Listar países disponíveis",
        "security": [],
        "description": "Retorna a lista de países aceitos pelo campo `proxy_managed_country` de\n`POST /instance/create` e `POST /instance/connect`.\n\nRespostas de sucesso enviam `Cache-Control: public, max-age=300`. Quando o\ncatálogo estiver temporariamente indisponível, o endpoint responde `503`.\n\n- Autenticação: endpoint público, sem `token` ou `admintoken`.\n- Proteção: limite de 120 requisições por minuto por IP; excesso retorna `429` com `Retry-After`.\n- Sem parâmetros de query.\n\nOs valores retornados em `countries[].value` são exatamente os aceitos em\n`proxy_managed_country` no `/instance/create` e no `/instance/connect`. Os valores em\n`countries[].label` são apenas rótulos para exibição; envie sempre o campo\n`value` nas operações de criação ou conexão.\n\nExemplo de requisição:\n```\nGET /proxy-managed/countries\n```\n",
        "responses": {
          "200": {
            "description": "Lista de países disponíveis",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "countries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "value": {
                            "type": "string",
                            "description": "Código ISO alpha-2 (minúsculo) aceito em `proxy_managed_country`.",
                            "example": "br",
                            "pattern": "^[a-z]{2}$"
                          },
                          "label": {
                            "type": "string",
                            "description": "Rótulo humano em inglês para dropdowns.",
                            "example": "Brazil"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate-limit excedido. Aguarde o tempo indicado no header `Retry-After`."
          },
          "500": {
            "description": "Erro interno"
          },
          "503": {
            "description": "Provider indisponível ou catálogo de países inacessível"
          }
        }
      }
    },
    "/proxy-managed/cities": {
      "get": {
        "operationId": "listRegionCities",
        "tags": [
          "Proxy"
        ],
        "summary": "Proxy Interno - Listar cidades disponíveis",
        "security": [],
        "description": "Retorna a lista de cidades disponíveis para uso nos campos\n`proxy_managed_country`, `proxy_managed_state` e `proxy_managed_city` dos endpoints\n`POST /instance/create` e `POST /instance/connect`.\n\nRespostas de sucesso enviam `Cache-Control: public, max-age=300`. Se o\ncatálogo de cidades estiver temporariamente indisponível, tente novamente\ndepois do intervalo indicado pela resposta.\n\n- Autenticação: endpoint público, sem `token` ou `admintoken`.\n- Proteção: limite de 120 requisições por minuto por IP; excesso retorna `429` com `Retry-After`.\n- Query `country` (opcional): ISO alpha-2 minúsculo. Default `br`.\n- Query `state` (opcional): UF/subdivisão minúscula, como `sp`.\n- Query `search` (opcional): filtro parcial por nome/slug, insensível a acento/caixa.\n\nComo escolher a cidade:\n1. Use `br` em `proxy_managed_country`.\n2. Chame `GET /proxy-managed/cities?country=br` para obter as cidades brasileiras.\n3. Quando a cidade retornar `state`, envie também esse valor em `proxy_managed_state`.\n4. Quando o usuário escolher uma cidade, envie em `/instance/create` ou `/instance/connect`:\n   - `proxy_managed_country`: o país escolhido, ex. `br`\n   - `proxy_managed_state`: o `state` retornado pela cidade, ex. `sp`, quando disponível\n   - `proxy_managed_city`: sempre o `cities[].value`\n\nSe `state` não vier na cidade selecionada, envie apenas `proxy_managed_country` e `proxy_managed_city`.\nA API valida a combinação e retorna erro se faltar algum dado necessário.\n\nExemplo de requisição:\n```\nGET /proxy-managed/cities?country=br&state=sp&search=camp\n```\n",
        "parameters": [
          {
            "in": "query",
            "name": "country",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{2}$",
              "default": "br"
            },
            "description": "ISO alpha-2 (minúsculo). Default `br`."
          },
          {
            "in": "query",
            "name": "state",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]{1,16}$"
            },
            "description": "Filtra por UF/subdivisão quando o catálogo traz `state`. Para Brasil, use valores como `sp`, `rj`, `mg`."
          },
          {
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filtro parcial por nome/slug (insensível a acento/caixa)."
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de cidades disponíveis",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "country": {
                      "type": "string",
                      "example": "br"
                    },
                    "state": {
                      "type": "string",
                      "description": "Retornado apenas quando a query `state` foi informada.",
                      "example": "sp"
                    },
                    "cities": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "value": {
                            "type": "string",
                            "description": "Slug aceito em `proxy_managed_city`.",
                            "example": "saopaulo"
                          },
                          "label": {
                            "type": "string",
                            "description": "Nome apresentável da cidade.",
                            "example": "São Paulo"
                          },
                          "state": {
                            "type": "string",
                            "description": "Código ISO 3166-2 da subdivisão/estado quando disponível.",
                            "example": "sp"
                          },
                          "state_label": {
                            "type": "string",
                            "description": "Nome apresentável do estado/subdivisão quando disponível.",
                            "example": "São Paulo"
                          },
                          "raw_city": {
                            "type": "string",
                            "description": "Campo técnico para diagnóstico. Não envie este campo no `/instance/connect`; use `value`.",
                            "example": "sao_paulo"
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "brasil_enriquecido": {
                    "summary": "Cidade brasileira enriquecida",
                    "value": {
                      "country": "br",
                      "state": "sp",
                      "cities": [
                        {
                          "value": "campinas",
                          "label": "Campinas",
                          "state": "sp",
                          "state_label": "São Paulo",
                          "raw_city": "campinas"
                        },
                        {
                          "value": "saopaulo",
                          "label": "São Paulo",
                          "state": "sp",
                          "state_label": "São Paulo",
                          "raw_city": "sao_paulo"
                        }
                      ]
                    }
                  },
                  "pais_sem_enriquecimento": {
                    "summary": "Cidade fora do Brasil",
                    "value": {
                      "country": "us",
                      "cities": [
                        {
                          "value": "losangeles",
                          "label": "Los Angeles"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "country inválido (não é ISO alpha-2)"
          },
          "429": {
            "description": "Rate-limit excedido. Aguarde o tempo indicado no header `Retry-After`."
          },
          "500": {
            "description": "Erro interno"
          },
          "503": {
            "description": "Provider indisponível ou catálogo de cidades inacessível"
          }
        }
      }
    },
    "/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.\n\nO endpoint realiza:\n- Atualiza o nome do perfil usando o WhatsApp AppState\n- Sincroniza a mudança com o servidor do WhatsApp\n- Retorna confirmação da alteração\n\n**Importante**: \n- A conta do WhatsApp deve estar conectada\n- O nome será visível para todos os contatos\n- Pode haver um limite de alterações por período (conforme WhatsApp)\n",
        "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.\n\nO endpoint realiza:\n- Atualiza a imagem do perfil usando \n- Processa a imagem (URL, base64 ou comando de remoção)\n- Sincroniza a mudança com o servidor do WhatsApp\n- Retorna confirmação da alteração\n\n**Importante**: \n- A conta do WhatsApp deve estar conectada\n- A imagem será visível para todos os contatos\n- A imagem deve estar em formato JPEG e tamanho 640x640 pixels\n",
        "security": [
          {
            "token": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "image"
                ],
                "properties": {
                  "image": {
                    "type": "string",
                    "description": "Imagem do perfil. Pode ser:\n- URL da imagem (http/https)\n- String base64 da imagem\n- \"remove\" ou \"delete\" para remover a imagem atual\n",
                    "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. Quando a remoção não puder ser concluída imediatamente, a API retorna `202` e finaliza o processo de forma assíncrona. Repetir a requisição durante esse período é seguro.\n",
        "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."
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Exclusão agendada e ainda em andamento",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response",
                    "deleteCompleted",
                    "deleteStatus",
                    "runtimeCleanup"
                  ],
                  "properties": {
                    "response": {
                      "type": "string",
                      "example": "Instance deletion scheduled"
                    },
                    "deleteCompleted": {
                      "type": "boolean",
                      "example": false
                    },
                    "deleteStatus": {
                      "type": "string",
                      "enum": [
                        "pending"
                      ]
                    },
                    "runtimeCleanup": {
                      "type": "string",
                      "enum": [
                        "pending"
                      ]
                    },
                    "info": {
                      "type": "string",
                      "description": "A instância deixou de aceitar operações e será removida quando a limpeza terminar."
                    }
                  }
                }
              }
            }
          },
          "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.\n\n**Importante - Diferença entre Status e Broadcast:**\n\n- **Status**: Refere-se ao recado personalizado que aparece embaixo do nome do usuário (ex: \"Disponível\", \"Ocupado\", texto personalizado)\n- **Broadcast**: Refere-se ao envio de \"stories/reels\" (fotos/vídeos temporários)\n\n**Limitação**: As configurações de privacidade do broadcast (stories/reels) não estão disponíveis para alteração via API.\n\nRetorna todas as configurações de privacidade como quem pode:\n- Adicionar aos grupos\n- Ver visto por último\n- Ver status (recado embaixo do nome)\n- Ver foto de perfil\n- Receber confirmação de leitura\n- Ver status online\n- Fazer chamadas\n",
        "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.\n\n**Importante - Diferença entre Status e Broadcast:**\n\n- **Status**: Refere-se ao recado personalizado que aparece embaixo do nome do usuário (ex: \"Disponível\", \"Ocupado\", texto personalizado)\n- **Broadcast**: Refere-se ao envio de \"stories/reels\" (fotos/vídeos temporários)\n\n**Limitação**: As configurações de privacidade do broadcast (stories/reels) não estão disponíveis para alteração via API.\n\n**Características:**\n- ✅ **Eficiência**: Altera apenas configurações que realmente mudaram\n- ✅ **Flexibilidade**: Pode alterar uma ou múltiplas configurações na mesma requisição\n- ✅ **Feedback completo**: Retorna todas as configurações atualizadas\n\n**Formato de entrada:**\n```json\n{\n  \"groupadd\": \"contacts\",\n  \"last\": \"none\",\n  \"status\": \"contacts\"\n}\n```\n\n**Tipos de privacidade disponíveis:**\n- `groupadd`: Quem pode adicionar aos grupos\n- `last`: Quem pode ver visto por último\n- `status`: Quem pode ver status (recado embaixo do nome)\n- `profile`: Quem pode ver foto de perfil\n- `readreceipts`: Confirmação de leitura\n- `online`: Quem pode ver status online\n- `calladd`: Quem pode fazer chamadas\n\n**Valores possíveis:**\n- `all`: Todos\n- `contacts`: Apenas contatos\n- `contact_blacklist`: Contatos exceto bloqueados\n- `none`: Ninguém\n- `match_last_seen`: Corresponder ao visto por último (apenas para online)\n- `known`: Números conhecidos (apenas para calladd)\n",
        "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:\n1. Definir se a conta aparece como disponível (\"online\") ou indisponível\n2. Controlar o status de presença para todos os contatos\n3. Salvar o estado atual da presença para a conta conectada\n\nTipos de presença suportados:\n- available: Marca a conta como disponível/online\n- unavailable: Marca a conta como indisponível/offline\n\n**Atenção**:\n- 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.\n- 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\".\n\n**⚠️ Importante - Limitação do Presence \"unavailable\"**:\n- **Quando a API é o único dispositivo ativo**: Confirmações de entrega/leitura (ticks cinzas/azuis) não são enviadas nem recebidas\n- **Impacto**: Eventos `message_update` com status de entrega podem não ser recebidos\n- **Solução**: Se precisar das confirmações, mantenha WhatsApp Web ou aplicativo móvel ativo ou use presence \"available\" \n\nExemplo de requisição:\n```json\n{\n  \"presence\": \"available\"\n}\n```\n\nExemplo de resposta:\n```json\n{\n  \"response\": \"Presence updated successfully\"\n}\n```\n\nErros comuns:\n- 401: Token inválido ou expirado\n- 400: Valor de presença inválido\n- 500: Erro ao atualizar presença\n",
        "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"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/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.\n\n## Recursos Específicos\n\n- **Preview de links** com suporte a personalização automática ou customizada\n- **Formatação básica** do texto\n- **Substituição automática de placeholders** dinâmicos\n\n## Envio para Newsletter\n\nPara enviar texto para um canal, use o mesmo campo `number`, mas informe o JID completo do canal:\n- Exemplo: `120363123456789012@newsletter`\n\n```json\n{\n  \"number\": \"120363123456789012@newsletter\",\n  \"text\": \"Post publicado no canal\"\n}\n```\n\n## Responder enquete, lista ou botão\n\nUse este mesmo endpoint para responder uma mensagem interativa que esteja\nsalva no histórico local da instância. Envie:\n\n- `number`: chat onde a mensagem original foi recebida ou enviada;\n- `replyid`: ID da mensagem interativa original;\n- `text`: seleção iniciada por `>`.\n\nO marcador `>` é obrigatório para gerar uma resposta interativa. Sem ele,\na API envia apenas uma mensagem de texto citando a original.\n\n### Responder uma enquete\n\nUse a posição da opção, começando em 1. Nesta documentação pública,\nresponda somente uma opção por requisição.\n\n```json\n{\n  \"number\": \"5511999999999\",\n  \"replyid\": \"3EB0ID_DA_ENQUETE\",\n  \"text\": \">1\"\n}\n```\n\n### Responder uma lista\n\nPrefira o `rowId` configurado ao criar a lista. Também são aceitos o texto\nexato do item ou sua posição (`>1`).\n\n```json\n{\n  \"number\": \"5511999999999\",\n  \"replyid\": \"3EB0ID_DA_LISTA\",\n  \"text\": \">plano_pro\"\n}\n```\n\n### Responder um botão\n\nPrefira o ID do botão de resposta rápida. Também são aceitos o texto exato\nexibido ou sua posição (`>1`). Isso vale para botões rápidos legados,\ntemplates, native flow e carrossel. Botões de URL, ligação ou cópia executam\na própria ação e não são respondidos por este fluxo.\n\n```json\n{\n  \"number\": \"5511999999999\",\n  \"replyid\": \"3EB0ID_DOS_BOTOES\",\n  \"text\": \">confirmar\"\n}\n```\n\nA API devolve erro quando a mensagem original não está disponível ou a\nopção informada não existe.\n\n## Campos Comuns\n\nEste endpoint suporta todos os **campos opcionais comuns** documentados na tag **\"Enviar Mensagem\"**, incluindo:\n`delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `forward`, `track_source`, `track_id`, placeholders e envio para grupos.\n\n## Preview de Links\n\n### Preview Automático\n```json\n{\n  \"number\": \"5511999999999\",\n  \"text\": \"Confira: https://exemplo.com\",\n  \"linkPreview\": true\n}\n```\n\n### Preview Personalizado\n```json\n{\n  \"number\": \"5511999999999\",\n  \"text\": \"Confira nosso site! https://exemplo.com\",\n  \"linkPreview\": true,\n  \"linkPreviewTitle\": \"Título Personalizado\",\n  \"linkPreviewDescription\": \"Uma descrição personalizada do link\",\n  \"linkPreviewImage\": \"https://exemplo.com/imagem.jpg\",\n  \"linkPreviewLarge\": true\n}\n```\n",
        "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. Para responder enquete, lista ou botão, use uma seleção iniciada por `>` junto com `replyid`. Aceita placeholders em mensagens de texto comuns.",
                    "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.\n\nComportamento:\n- Se apenas linkPreview=true: gera preview automático do primeiro link encontrado no texto\n- Se fornecidos campos personalizados (title, description, image): usa os valores fornecidos\n- Se campos personalizados parciais: combina com dados automáticos do link como fallback\n",
                    "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 original. Com `text` iniciado por `>`, gera a resposta nativa de enquete, lista ou botão quando o tipo original for suportado.",
                    "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 placeholders nativos e um campo personalizado",
                  "value": {
                    "number": "5511999999999",
                    "text": "Olá {{first_name}}! Empresa: {{lead_field01}}. Seu email {{lead_email}} está correto?"
                  }
                },
                "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"
                  }
                },
                "pollReply": {
                  "summary": "Responder enquete",
                  "description": "Seleciona a opção 1 da enquete identificada por replyid.",
                  "value": {
                    "number": "5511999999999",
                    "replyid": "3EB0ID_DA_ENQUETE",
                    "text": ">1"
                  }
                },
                "listReply": {
                  "summary": "Responder lista",
                  "description": "Seleciona pelo rowId configurado no item da lista.",
                  "value": {
                    "number": "5511999999999",
                    "replyid": "3EB0ID_DA_LISTA",
                    "text": ">plano_pro"
                  }
                },
                "buttonReply": {
                  "summary": "Responder botão",
                  "description": "Seleciona pelo ID configurado no botão de resposta rápida.",
                  "value": {
                    "number": "5511999999999",
                    "replyid": "3EB0ID_DOS_BOTOES",
                    "text": ">confirmar"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mensagem enviada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Message"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "response": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "example": "success"
                            },
                            "message": {
                              "type": "string",
                              "example": "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.\n\n## Tipos de Mídia Suportados\n- **`image`**: Imagens (JPG preferencialmente)\n- **`video`**: Vídeos (apenas MP4)\n- **`videoplay`**: Vídeo com comportamento visual de autoplay/loop no WhatsApp\n- **`document`**: Documentos (PDF, DOCX, XLSX, etc)\n- **`audio`**: Áudio comum (MP3 ou OGG)\n- **`myaudio`**: Mensagem de voz (alternativa ao PTT)\n- **`ptt`**: Mensagem de voz (Push-to-Talk)\n- **`ptv`**: Mensagem de vídeo (Push-to-Video)\n- **`sticker`**: Figurinha/Sticker\n\n## Recursos Específicos\n- **Upload por URL ou base64**\n- **Caption/legenda** opcional com suporte a placeholders\n- **Nome personalizado** para documentos (`docName`)\n- **Geração automática de thumbnails para imagens e vídeos** quando `thumbnail` não é informado\n- **Compressão otimizada** conforme o tipo\n- **`viewOnce`** recomendado para mídia compatível\n\n## Envio para Newsletter\n\nPara enviar mídia para um canal, use o mesmo campo `number`, mas informe o JID completo do canal:\n- Exemplo: `120363123456789012@newsletter`\n\n```json\n{\n  \"number\": \"120363123456789012@newsletter\",\n  \"type\": \"image\",\n  \"file\": \"https://exemplo.com/foto.jpg\",\n  \"text\": \"Imagem publicada no canal\"\n}\n```\n\n## Campos Comuns\n\nEste endpoint suporta todos os **campos opcionais comuns** documentados na tag **\"Enviar Mensagem\"**, incluindo:\n`delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `forward`, `track_source`, `track_id`, placeholders e envio para grupos.\n\n## Exemplos Básicos\n\n## Visualização Única (`viewOnce`)\n\nO campo `viewOnce` é recomendado quando quiser mídia de visualização única e hoje produz efeito para os tipos:\n`image`, `video`, `videoplay`, `ptv`, `audio`, `myaudio` e `ptt`.\n\nPara `document`, `sticker` e demais endpoints de envio, o campo é ignorado silenciosamente.\n\n## Thumbnail personalizado\n\nUse `thumbnail` em `image`, `video`, `videoplay`, `ptv` ou\n`document`. Aceita URL HTTP/HTTPS, Data URL ou base64 de imagem com até\n1 MiB e 4096 px por dimensão. A API converte para JPEG e prioriza essa\nimagem em relação à miniatura automática. Para documentos, envie uma\nimagem de pelo menos 480 px para uma prévia mais nítida no WhatsApp Web.\nDocumentos sem `thumbnail` não recebem miniatura automática.\n\nAo reenviar o mesmo documento, reutilize a mesma miniatura: o WhatsApp\npode associar a prévia ao conteúdo do arquivo também em mensagens antigas.\n\n### Imagem Simples\n```json\n{\n  \"number\": \"5511999999999\",\n  \"type\": \"image\",\n  \"file\": \"https://exemplo.com/foto.jpg\"\n}\n```\n\n### Documento com Nome\n```json\n{\n  \"number\": \"5511999999999\",\n  \"type\": \"document\",\n  \"file\": \"https://exemplo.com/contrato.pdf\",\n  \"docName\": \"Contrato.pdf\",\n  \"text\": \"Segue o documento solicitado\"\n}\n```\n",
        "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 HTTP/HTTPS, Data URL ou base64 de imagem para image, video, videoplay, ptv e document. Até 1 MiB e 4096 px por dimensão. Tem prioridade sobre a miniatura automática; documentos sem este campo não recebem miniatura automática.",
                    "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": "#/components/schemas/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.\n\n## Recursos Específicos\n\n- **vCard completo** com nome, telefones, organização, email e URL\n- **Múltiplos números de telefone** (separados por vírgula)\n- **Cartão clicável** no WhatsApp para salvar na agenda\n- **Informações profissionais** (organização/empresa)\n\n## Campos Comuns\n\nEste endpoint suporta todos os **campos opcionais comuns** documentados na tag **\"Enviar Mensagem\"**, incluindo:\n`delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `forward`, `track_source`, `track_id`, placeholders e envio para grupos.\n\n## Exemplo Básico\n```json\n{\n  \"number\": \"5511999999999\",\n  \"fullName\": \"João Silva\",\n  \"phoneNumber\": \"5511999999999,5511888888888\",\n  \"organization\": \"Empresa XYZ\",\n  \"email\": \"joao.silva@empresa.com\",\n  \"url\": \"https://empresa.com/joao\"\n}\n```\n",
        "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": "#/components/schemas/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.\n\n## Recursos Específicos\n\n- **Coordenadas precisas** (latitude e longitude obrigatórias)\n- **Nome do local** para identificação\n- **Endereço completo** para exibição detalhada\n- **Mapa interativo** no WhatsApp para navegação\n- **Pin personalizado** com nome do local\n\n## Campos Comuns\n\nEste endpoint suporta todos os **campos opcionais comuns** documentados na tag **\"Enviar Mensagem\"**, incluindo:\n`delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `forward`, `track_source`, `track_id`, placeholders e envio para grupos.\n\n## Exemplo Básico\n```json\n{\n  \"number\": \"5511999999999\",\n  \"name\": \"Maracanã\",\n  \"address\": \"Av. Pres. Castelo Branco - Maracanã, Rio de Janeiro - RJ\",\n  \"latitude\": -22.912982815767986,\n  \"longitude\": -43.23028153499254\n}\n```\n",
        "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": "#/components/schemas/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**.\n\n## 🔄 Comportamento Assíncrono:\n- **Execução independente**: A presença é gerenciada em background, não bloqueia o retorno da API\n- **Limite máximo**: 5 minutos de duração (300 segundos)\n- **Tick de atualização**: Reenvia a presença a cada 10 segundos\n- **Cancelamento automático**: Presença é cancelada automaticamente ao enviar uma mensagem para o mesmo chat\n\n## 📱 Tipos de presença suportados:\n- **composing**: Indica que você está digitando uma mensagem\n- **recording**: Indica que você está gravando um áudio\n- **paused**: Remove/cancela a indicação de presença atual\n\n## ⏱️ Controle de duração:\n- **Sem delay**: Usa limite padrão de 5 minutos\n- **Com delay**: Usa o valor especificado (máximo 5 minutos)\n- **Cancelamento**: Envio de mensagem cancela presença automaticamente\n\n## 📋 Exemplos de uso:\n\n### Digitar por 30 segundos:\n```json\n{\n  \"number\": \"5511999999999\",\n  \"presence\": \"composing\",\n  \"delay\": 30000\n}\n```\n\n### Gravar áudio por 1 minuto:\n```json\n{\n  \"number\": \"5511999999999\",\n  \"presence\": \"recording\",\n  \"delay\": 60000\n}\n```\n\n### Cancelar presença atual:\n```json\n{\n  \"number\": \"5511999999999\",\n  \"presence\": \"paused\"\n}\n```\n\n### Usar limite máximo (5 minutos):\n```json\n{\n  \"number\": \"5511999999999\",\n  \"presence\": \"composing\"\n}\n```\n",
        "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).\nSe não informado ou valor maior que 5 minutos, usa o limite padrão de 5 minutos.\nA presença é reenviada a cada 10 segundos durante este período.\n",
                    "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 status (stories)",
        "description": "Envia um status do WhatsApp com suporte para texto, imagem, vídeo e áudio.\n\nEste endpoint possui 3 modos de uso:\n\n- envio normal: omita `recipients` e `max_recipients`\n- envio explícito: informe `recipients` para enviar apenas para números específicos; a API aproveita os válidos e descarta os inválidos com motivo no `debug`\n- envio parcial: informe `max_recipients` para limitar a audiência ou aplicar um cap de segurança sobre `recipients`\n\n## Observação importante sobre `recipients`\nQuando `recipients` é informado, a API:\n\n- aceita números em formato WhatsApp, JIDs `@s.whatsapp.net` e JIDs `@lid`\n- quando recebe `@lid`, tenta resolver esse identificador para o PN (`@s.whatsapp.net`) usando os vínculos conhecidos pela instância\n- se o `@lid` não puder ser resolvido para PN, esse item é descartado com motivo `lid_unresolved`\n- valida se o destinatário existe no WhatsApp usando o mesmo fluxo de verificação do envio normal, com batch para evitar uma chamada remota por recipient\n- cruza os destinatários verificados com a audiência permitida pela privacidade do status, aceitando equivalência PN/LID quando esse vínculo é conhecido\n- recipients descartados aparecem em `debug.discarded_recipients`, com motivos como `invalid_format`, `lid_unresolved`, `not_on_whatsapp`, `outside_status_audience` e `duplicate`\n- a requisição só retorna `400` quando nenhum recipient válido sobra para envio\n\n## Observação importante sobre `max_recipients`\nO campo `max_recipients` foi adicionado como mitigação operacional.\nJá observamos casos em que o WhatsApp bloqueia imediatamente o envio de status quando a audiência é muito grande\n(por exemplo, agendas com milhares de contatos, como ~3.000).\nA causa exata ainda não está totalmente clara, então a recomendação é começar com limites menores e aumentar gradualmente.\n\n## Tipos suportados\n- `text`: texto com cor de fundo e fonte\n- `image`: imagem com legenda opcional\n- `video`: vídeo com legenda opcional\n- `audio`: áudio normal\n- `myaudio`: áudio enviado como voz\n- `ptt`: áudio enviado como voz\n\n## Cores de fundo\nInforme um valor de `1` a `19`. A API converte esse índice para a cor usada pelo WhatsApp.\n\n- `1`: amarelo esverdeado suave\n- `2`: amarelo pálido\n- `3`: amarelo alaranjado vibrante\n- `4`: verde vibrante\n- `5`: verde musgo\n- `6`: verde claro\n- `7`: azul piscina\n- `8`: azul intenso\n- `9`: azul claro acinzentado\n- `10`: lilás claro\n- `11`: lilás quente\n- `12`: roxo azulado\n- `13`: magenta profundo\n- `14`: rosa suave\n- `15`: salmão rosado\n- `16`: marrom claro\n- `17`: cinza claro azulado\n- `18`: cinza médio\n- `19`: cinza profundo padrão\n\nExemplo rápido:\n- `7`: azul piscina\n- `13`: magenta profundo\n- `19`: cinza profundo (padrão)\n\n## Fontes válidas para `type=text`\nValores aceitos atualmente: `0`, `1`, `2`, `6`, `7`, `8`, `9`, `10`.\n\n## Limites\n- `text`: máximo de 656 caracteres\n- `max_recipients`: não pode ser negativo\n- `recipients`: aceita números, JIDs `@s.whatsapp.net` e JIDs `@lid`\n- `@lid` só entra no envio quando puder ser resolvido localmente para um PN válido; caso contrário, é descartado\n- para tipos de mídia, `file` é obrigatório\n\nExemplo de envio explícito:\n```json\n{\n  \"type\": \"text\",\n  \"text\": \"Novidades chegando!\",\n  \"recipients\": [\n    \"5511999999999\",\n    \"5511888888888@s.whatsapp.net\"\n  ]\n}\n```\n\nExemplo de envio parcial:\n```json\n{\n  \"type\": \"text\",\n  \"text\": \"Novidades chegando!\",\n  \"background_color\": 7,\n  \"font\": 1,\n  \"max_recipients\": 100\n}\n```\n",
        "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": "Índice da cor de fundo para status em texto.",
                    "example": 7
                  },
                  "font": {
                    "type": "integer",
                    "enum": [
                      0,
                      1,
                      2,
                      6,
                      7,
                      8,
                      9,
                      10
                    ],
                    "description": "Fonte aceita 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": "Campo aceito no payload; a API gera a miniatura automaticamente quando necessário.",
                    "example": "https://example.com/thumb.jpg"
                  },
                  "mimetype": {
                    "type": "string",
                    "description": "MIME type do arquivo, quando necessário.",
                    "example": "video/mp4"
                  },
                  "recipients": {
                    "type": "array",
                    "description": "Lista explícita de destinatários. Aceita números em formato WhatsApp, JIDs `@s.whatsapp.net` e JIDs `@lid`. A API valida item a item, descarta os inválidos com motivo no `debug` e envia para o subconjunto válido restante. Entradas `@lid` dependem de resolução conhecida para PN.",
                    "items": {
                      "type": "string"
                    },
                    "example": [
                      "5511999999999",
                      "5511888888888@s.whatsapp.net"
                    ]
                  },
                  "max_recipients": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Limita o envio a um subconjunto determinístico da audiência. Quando `recipients` for informado, funciona como cap de segurança sobre a lista explícita já validada.",
                    "example": 100
                  }
                },
                "required": [
                  "type"
                ]
              },
              "examples": {
                "text": {
                  "summary": "Status de texto",
                  "value": {
                    "type": "text",
                    "text": "Novidades chegando!"
                  }
                },
                "image": {
                  "summary": "Status com imagem",
                  "value": {
                    "type": "image",
                    "file": "https://exemplo.com/status.jpg",
                    "text": "Confira a novidade"
                  }
                },
                "audio": {
                  "summary": "Status com áudio",
                  "value": {
                    "type": "audio",
                    "file": "https://exemplo.com/audio.mp3"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status enviado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "Id": {
                      "type": "string",
                      "description": "ID da mensagem quando há envio real.",
                      "example": "ABCD1234"
                    },
                    "content": {
                      "type": "object",
                      "description": "Conteúdo processado da mensagem quando há envio real."
                    },
                    "messageTimestamp": {
                      "type": "integer",
                      "description": "Timestamp em milissegundos quando há envio real.",
                      "example": 1672531200000
                    },
                    "status": {
                      "type": "string",
                      "description": "Status do envio quando há envio real.",
                      "example": "Pending"
                    },
                    "debug": {
                      "type": "object",
                      "description": "Métricas agregadas da audiência e da seleção aplicada.",
                      "properties": {
                        "status_privacy_type": {
                          "type": "string",
                          "example": "contacts"
                        },
                        "audience_recipient_count": {
                          "type": "integer",
                          "example": 245
                        },
                        "total_contacts_in_store": {
                          "type": "integer",
                          "example": 300
                        },
                        "contacts_with_full_name": {
                          "type": "integer",
                          "example": 245
                        },
                        "contacts_with_push_name_only": {
                          "type": "integer",
                          "example": 32
                        },
                        "contacts_with_business_name_only": {
                          "type": "integer",
                          "example": 23
                        },
                        "used_default_privacy_fallback": {
                          "type": "boolean",
                          "example": false
                        },
                        "privacy_lookup_error": {
                          "type": "string",
                          "example": "privacy unavailable"
                        },
                        "explicit_recipients": {
                          "type": "boolean",
                          "example": true
                        },
                        "requested_recipient_count": {
                          "type": "integer",
                          "example": 25
                        },
                        "resolved_recipient_count": {
                          "type": "integer",
                          "example": 20
                        },
                        "discarded_recipient_count": {
                          "type": "integer",
                          "example": 5
                        },
                        "discarded_recipients": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "input": {
                                "type": "string",
                                "example": "144637553594388@lid"
                              },
                              "reason": {
                                "type": "string",
                                "example": "lid_unresolved"
                              }
                            }
                          }
                        },
                        "max_recipients": {
                          "type": "integer",
                          "example": 100
                        },
                        "selected_recipient_count": {
                          "type": "integer",
                          "example": 100
                        },
                        "partial_send": {
                          "type": "boolean",
                          "example": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Requisição inválida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Invalid font"
                    },
                    "debug": {
                      "type": "object",
                      "description": "Presente especialmente quando `recipients` foi informado, para indicar quais itens foram descartados antes de concluir que nenhum recipient válido sobrou."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado"
          },
          "500": {
            "description": "Erro interno do servidor",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "failed to determine status audience: privacy unavailable"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/send/menu": {
      "post": {
        "operationId": "sendMenu",
        "tags": [
          "Enviar Mensagem"
        ],
        "summary": "Enviar menu interativo (botões, carrossel, lista ou enquete)",
        "description": "Este endpoint oferece uma interface unificada para envio de quatro tipos principais de mensagens interativas:\n- Botões: Para ações rápidas e diretas\n- Carrossel de botões: Para uma lista horizontal de botões com imagens\n- Listas: Para menus organizados em seções\n- Enquetes: Para coleta de opiniões e votações\n\n**Suporte a campos de rastreamento**: Este endpoint também suporta `track_source` e `track_id` documentados na tag **\"Enviar Mensagem\"**.\n\n## Estrutura Base do Payload\n\nTodas as requisições seguem esta estrutura base:\n\n```json\n{\n  \"number\": \"5511999999999\",\n  \"type\": \"button|button_legacy|list|poll|carousel\",\n  \"text\": \"Texto principal da mensagem\",\n  \"choices\": [\"opções baseadas no tipo escolhido\"],\n  \"footerText\": \"Texto do rodapé (opcional para botões e listas)\",\n  \"listButton\": \"Texto do botão (para listas)\",\n  \"selectableCount\": \"Número de opções selecionáveis (apenas para enquetes)\"\n}\n```\n\n## Tipos de Mensagens Interativas\n\n### 1. Botões (type: \"button\")\n\nCria botões interativos com diferentes funcionalidades de ação.\n\n#### Campos Específicos\n- `footerText`: Texto opcional exibido abaixo da mensagem principal\n- `choices`: Array de opções que serão convertidas em botões\n\n#### Formatos de Botões\nCada botão pode ser configurado usando `|` (pipe) ou `\\n` (quebra de linha) como separadores:\n\n- **Botão de Resposta**: \n  - `\"texto|id\"` ou \n  - `\"texto\\nid\"` ou \n  - `\"texto\"` (ID será igual ao texto)\n\n- **Botão de Cópia**: \n  - `\"texto|copy:código\"` ou \n  - `\"texto\\ncopy:código\"`\n\n- **Botão de Chamada**: \n  - `\"texto|call:+5511999999999\"` ou \n  - `\"texto\\ncall:+5511999999999\"`\n\n- **Botão de URL**: \n  - `\"texto|https://exemplo.com\"` ou \n  - `\"texto|url:https://exemplo.com\"`\n\n#### Botões com Imagem\nPara adicionar uma imagem aos botões, use o campo `imageButton` no payload:\n\n#### Exemplo com Imagem\n```json\n{\n  \"number\": \"5511999999999\",\n  \"type\": \"button\",\n  \"text\": \"Escolha um produto:\",\n  \"imageButton\": \"https://exemplo.com/produto1.jpg\",\n  \"choices\": [\n    \"Produto A|prod_a\",\n    \"Mais Info|https://exemplo.com/produto-a\",\n    \"Produto B|prod_b\",\n    \"Ligar|call:+5511999999999\"\n  ],\n  \"footerText\": \"Produtos em destaque\"\n}\n```\n\n> **Suporte**: O campo `imageButton` aceita URLs ou imagens em base64.\n\n#### Botões no formato legado (type: \"button_legacy\")\n\nUse `button_legacy` somente quando precisar enviar os botões de resposta do\nformato anterior. O formato de `choices` é:\n\n- `\"texto|id\"`\n- `\"texto\\nid\"`\n- `\"texto|reply:id\"`\n- `\"texto\"` — o próprio texto será usado como ID\n\nEste modo cria apenas botões de resposta. Ações de URL, chamada e cópia e o\ncampo `imageButton` continuam disponíveis no formato atual `type: \"button\"`.\n\n```json\n{\n  \"number\": \"5511999999999\",\n  \"type\": \"button_legacy\",\n  \"text\": \"Deseja continuar?\",\n  \"choices\": [\n    \"Sim|confirmar\",\n    \"Não|reply:cancelar\"\n  ],\n  \"footerText\": \"Escolha uma opção\"\n}\n```\n\n#### Exemplo Completo\n```json\n{\n  \"number\": \"5511999999999\",\n  \"type\": \"button\",\n  \"text\": \"Como podemos ajudar?\",\n  \"choices\": [\n    \"Suporte Técnico|suporte\",\n    \"Fazer Pedido|pedido\",\n    \"Nosso Site|https://exemplo.com\",\n    \"Falar Conosco|call:+5511999999999\"\n  ],\n  \"footerText\": \"Escolha uma das opções abaixo\"\n}\n```\n\n#### Limitações e Compatibilidade\n> **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.\"\n\n### 2. Listas (type: \"list\")\n\nCria menus organizados em seções com itens selecionáveis.\n\n#### Campos Específicos\n- `listButton`: Texto do botão que abre a lista\n- `footerText`: Texto opcional do rodapé\n- `choices`: Array com seções e itens da lista\n\n#### Formato das Choices\n- `\"[Título da Seção]\"`: Inicia uma nova seção\n- `\"texto|id|descrição\"`: Item da lista com:\n  - texto: Label do item\n  - id: Identificador único, opcional\n  - descrição: Texto descritivo adicional e opcional\n\n#### Exemplo Completo\n```json\n{\n  \"number\": \"5511999999999\",\n  \"type\": \"list\",\n  \"text\": \"Catálogo de Produtos\",\n  \"choices\": [\n    \"[Eletrônicos]\",\n    \"Smartphones|phones|Últimos lançamentos\",\n    \"Notebooks|notes|Modelos 2024\",\n    \"[Acessórios]\",\n    \"Fones|fones|Bluetooth e com fio\",\n    \"Capas|cases|Proteção para seu device\"\n  ],\n  \"listButton\": \"Ver Catálogo\",\n  \"footerText\": \"Preços sujeitos a alteração\"\n}\n```\n\n### 3. Enquetes (type: \"poll\")\n\nCria enquetes interativas para votação.\n\n#### Campos Específicos\n- `selectableCount`: Número de opções que podem ser selecionadas (padrão: 1)\n- `choices`: Array simples com as opções de voto\n\n#### Exemplo Completo\n```json\n{\n  \"number\": \"5511999999999\",\n  \"type\": \"poll\",\n  \"text\": \"Qual horário prefere para atendimento?\",\n  \"choices\": [\n    \"Manhã (8h-12h)\",\n    \"Tarde (13h-17h)\",\n    \"Noite (18h-22h)\"\n  ],\n  \"selectableCount\": 1\n}\n```\n\n### 4. Carousel (type: \"carousel\")\n\nCria um carrossel de cartões com imagens e botões interativos.\n\n#### Campos Específicos\n- `choices`: Array com elementos do carrossel na seguinte ordem:\n  - `[Texto do cartão]`: Texto do cartão entre colchetes\n  - `{URL ou base64 da imagem}`: Imagem entre chaves\n  - Botões do cartão (um por linha):\n    - `\"texto|copy:código\"` para botão de copiar\n    - `\"texto|https://url\"` para botão de link\n    - `\"texto|call:+número\"` para botão de ligação\n\n#### Exemplo Completo\n```json\n{\n  \"number\": \"5511999999999\",\n  \"type\": \"carousel\",\n  \"text\": \"Conheça nossos produtos\",\n  \"choices\": [\n    \"[Smartphone XYZ\\nO mais avançado smartphone da linha]\",\n    \"{https://exemplo.com/produto1.jpg}\",\n    \"Copiar Código|copy:PROD123\",\n    \"Ver no Site|https://exemplo.com/xyz\",\n    \"Fale Conosco|call:+5511999999999\",\n    \"[Notebook ABC\\nO notebook ideal para profissionais]\",\n    \"{https://exemplo.com/produto2.jpg}\",\n    \"Copiar Código|copy:NOTE456\",\n    \"Comprar Online|https://exemplo.com/abc\",\n    \"Suporte|call:+5511988888888\"\n  ]\n}\n```\n\n> **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ê.\n\n## Termos de uso\n\nOs 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.\n\n### Alternativas e Compatibilidade\n\nConsiderando 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). \n\nRecomendamos criar seus fluxos de forma flexível, preparados para alternar entre os diferentes tipos.\n\nEm 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.\n",
        "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. Use button para o formato atual e button_legacy apenas para botões de resposta no formato anterior.",
                    "enum": [
                      "button",
                      "button_legacy",
                      "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"
                ]
              },
              "examples": {
                "button": {
                  "summary": "Botões de resposta",
                  "value": {
                    "number": "5511999999999",
                    "type": "button",
                    "text": "Como podemos ajudar?",
                    "choices": [
                      "Suporte|suporte",
                      "Fazer pedido|pedido"
                    ]
                  }
                },
                "list": {
                  "summary": "Lista de opções",
                  "value": {
                    "number": "5511999999999",
                    "type": "list",
                    "text": "Escolha uma categoria",
                    "listButton": "Ver opções",
                    "choices": [
                      "[Atendimento]",
                      "Suporte|suporte|Falar com o suporte",
                      "Financeiro|financeiro|Falar com o financeiro"
                    ]
                  }
                },
                "poll": {
                  "summary": "Enquete com uma escolha",
                  "value": {
                    "number": "5511999999999",
                    "type": "poll",
                    "text": "Qual horário prefere?",
                    "selectableCount": 1,
                    "choices": [
                      "Manhã",
                      "Tarde"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Menu enviado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Message"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "response": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "example": "success"
                            },
                            "message": {
                              "type": "string",
                              "example": "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.\nFunciona de maneira igual ao endpoint `/send/menu` com type: carousel, porém usando outro formato de payload.\n\n## Campos Comuns\n\nEste endpoint suporta todos os **campos opcionais comuns** documentados na tag **\"Enviar Mensagem\"**, incluindo:\n`delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `forward`, `track_source`, `track_id`, placeholders e envio para grupos.\n\n## Estrutura do Payload\n\n```json\n{\n  \"number\": \"5511999999999\",\n  \"text\": \"Texto principal\",\n  \"carousel\": [\n    {\n      \"text\": \"Texto do cartão\",\n      \"image\": \"URL da imagem\",\n      \"buttons\": [\n        {\n          \"id\": \"resposta1\",\n          \"text\": \"Texto do botão\",\n          \"type\": \"REPLY\"\n        }\n      ]\n    }\n  ]\n}\n```\n\n## Tipos de Botões\n\n- `REPLY`: Botão de resposta rápida\n  - Quando clicado, envia o valor do id como resposta ao chat\n  - O id será o texto enviado como resposta\n\n- `URL`: Botão com link\n  - Quando clicado, abre a URL especificada\n  - O id deve conter a URL completa (ex: https://exemplo.com)\n\n- `COPY`: Botão para copiar texto\n  - Quando clicado, copia o texto para a área de transferência\n  - O id será o texto que será copiado\n\n- `CALL`: Botão para realizar chamada\n  - Quando clicado, inicia uma chamada telefônica\n  - O id deve conter o número de telefone\n\n## Exemplo de Botões\n```json\n{\n  \"buttons\": [\n    {\n      \"id\": \"Sim, quero comprar!\",\n      \"text\": \"Confirmar Compra\",\n      \"type\": \"REPLY\"\n    },\n    {\n      \"id\": \"https://exemplo.com/produto\",\n      \"text\": \"Ver Produto\",\n      \"type\": \"URL\"\n    },\n    {\n      \"id\": \"CUPOM20\",\n      \"text\": \"Copiar Cupom\",\n      \"type\": \"COPY\"\n    },\n    {\n      \"id\": \"5511999999999\",\n      \"text\": \"Falar com Vendedor\",\n      \"type\": \"CALL\"\n    }\n  ]\n}\n```\n\n## Exemplo Completo de Carrossel\n```json\n{\n  \"number\": \"5511999999999\",\n  \"text\": \"Nossos Produtos em Destaque\",\n  \"carousel\": [\n    {\n      \"text\": \"Smartphone XYZ\\nO mais avançado smartphone da linha\",\n      \"image\": \"https://exemplo.com/produto1.jpg\",\n      \"buttons\": [\n        {\n          \"id\": \"SIM_COMPRAR_XYZ\",\n          \"text\": \"Comprar Agora\",\n          \"type\": \"REPLY\"\n        },\n        {\n          \"id\": \"https://exemplo.com/xyz\",\n          \"text\": \"Ver Detalhes\",\n          \"type\": \"URL\"\n        }\n      ]\n    },\n    {\n      \"text\": \"Cupom de Desconto\\nGanhe 20% OFF em qualquer produto\",\n      \"image\": \"https://exemplo.com/cupom.jpg\",\n      \"buttons\": [\n        {\n          \"id\": \"DESCONTO20\",\n          \"text\": \"Copiar Cupom\",\n          \"type\": \"COPY\"\n        },\n        {\n          \"id\": \"5511999999999\",\n          \"text\": \"Falar com Vendedor\",\n          \"type\": \"CALL\"\n        }\n      ]\n    }\n  ]\n}\n```\n",
        "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\nO 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:\n* REPLY - O id será enviado como resposta ao chat\n* URL - O id deve ser a URL completa que será aberta\n* COPY - O id será o texto copiado para área de transferência\n* CALL - O id deve ser o número de telefone para a chamada\n",
                                "enum": [
                                  "REPLY",
                                  "URL",
                                  "CALL",
                                  "COPY"
                                ],
                                "example": "REPLY"
                              }
                            },
                            "required": [
                              "id",
                              "text",
                              "type"
                            ]
                          }
                        }
                      },
                      "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",
                  "carousel"
                ]
              },
              "examples": {
                "basic": {
                  "summary": "Carrossel com um cartão",
                  "value": {
                    "number": "5511999999999",
                    "text": "Nossos produtos",
                    "carousel": [
                      {
                        "text": "Smartphone XYZ",
                        "image": "https://exemplo.com/produto.jpg",
                        "buttons": [
                          {
                            "id": "comprar_xyz",
                            "text": "Comprar agora",
                            "type": "REPLY"
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Carrossel enviado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Message"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "response": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "example": "success"
                            },
                            "message": {
                              "type": "string",
                              "example": "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.\nQuando o usuário clica no botão, o WhatsApp abre a interface para compartilhar a localização atual.\n\n## Campos Comuns\n\nEste endpoint suporta todos os **campos opcionais comuns** documentados na tag **\"Enviar Mensagem\"**, incluindo:\n`delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `forward`, `track_source`, `track_id`, placeholders e envio para grupos.\n\n## Estrutura do Payload\n\n```json\n{\n  \"number\": \"5511999999999\",\n  \"text\": \"Por favor, compartilhe sua localização\",\n  \"delay\": 0,\n  \"readchat\": true\n}\n```\n\n## Exemplo de Uso\n\n```json\n{\n  \"number\": \"5511999999999\",\n  \"text\": \"Para continuar o atendimento, clique no botão abaixo e compartilhe sua localização\"\n}\n```\n\n> **Nota**: O botão de localização é adicionado automaticamente à mensagem\n",
        "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": "#/components/schemas/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.\nO fluxo suporta PIX (estático, dinâmico ou desabilitado), boleto, link de pagamento e cartão,\ncombinando tudo em uma única mensagem interativa.\n\n## Como funciona\n- Define o valor em `amount` (BRL por padrão) e opcionalmente personaliza título, texto e nota adicional.\n- Por padrão exige `pixKey`.\n- O arquivo apontado por `fileUrl` é anexado como documento (boleto ou fatura em PDF, por exemplo).\n- `paymentLink` habilita o botão externo.\n- Para cobrar um pedido recebido pelo WhatsApp, informe `orderMessageId`\n  com o ID da mensagem `OrderMessage` desse mesmo contato. A API obtém\n  itens, moeda e total do pedido; `amount` não é necessário nesse caso.\n  Ainda é preciso informar um método de pagamento.\n\n\n\n## Campos comuns\nEste endpoint também suporta os campos padrão: `delay`, `readchat`, `readmessages`, `replyid`,\n`mentions`, `track_source`, `track_id` e `async`.\n",
        "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"
                  },
                  "orderMessageId": {
                    "type": "string",
                    "description": "ID de uma `OrderMessage` recebida do mesmo contato. Vincula a cobrança ao pedido real."
                  },
                  "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"
                ],
                "anyOf": [
                  {
                    "required": [
                      "amount"
                    ]
                  },
                  {
                    "required": [
                      "orderMessageId"
                    ]
                  }
                ]
              },
              "examples": {
                "pedidoRecebido": {
                  "summary": "Cobrar um pedido enviado pelo cliente",
                  "value": {
                    "number": "5511999999999",
                    "orderMessageId": "3EB0ID_DO_PEDIDO",
                    "pixKey": "123e4567-e89b-12d3-a456-426614174000",
                    "text": "Confira os dados para pagamento"
                  }
                },
                "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": "#/components/schemas/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"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/message/payment/status": {
      "post": {
        "operationId": "updatePaymentStatus",
        "tags": [
          "Enviar Mensagem"
        ],
        "summary": "Atualizar pagamento e pedido",
        "description": "Envia ao cliente uma atualização de um pedido originado por\n`POST /send/request-payment`. No campo `id`, envie o `id` ou o\n`messageid` retornado pela solicitação. `paid` é opcional: quando\nomitido, somente o estado do pedido é enviado. `note` aparece na\natualização do pedido.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "status"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Aceita o `id` ou o `messageid` da solicitação de pagamento enviada."
                  },
                  "status": {
                    "type": "string",
                    "description": "Novo estado do pedido.",
                    "enum": [
                      "payment_requested",
                      "preparing_to_ship",
                      "shipped",
                      "delivered",
                      "completed",
                      "canceled"
                    ]
                  },
                  "paid": {
                    "type": "boolean",
                    "description": "`true` confirma o pagamento; `false` marca como pendente. Omitir para não alterar."
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              },
              "examples": {
                "por_messageid": {
                  "summary": "Usar o messageid",
                  "value": {
                    "id": "3EB012345678",
                    "status": "shipped",
                    "paid": true,
                    "note": "Seu pedido saiu para entrega."
                  }
                },
                "por_id": {
                  "summary": "Usar o id",
                  "value": {
                    "id": "5511999999999:3EB012345678",
                    "status": "shipped"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Atualização enviada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "referenceId",
                    "orderStatus",
                    "paymentChanged",
                    "manual"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Estado da mensagem de atualização enviada (por exemplo, `Pending`)."
                    },
                    "referenceId": {
                      "type": "string"
                    },
                    "orderStatus": {
                      "type": "string",
                      "description": "Estado do pedido aplicado; não confundir com o estado da mensagem em `status`."
                    },
                    "paymentChanged": {
                      "type": "boolean"
                    },
                    "paymentStatusMessageID": {
                      "type": "string",
                      "description": "Presente quando `paid` foi informado."
                    },
                    "paid": {
                      "type": "boolean",
                      "description": "Presente quando `paid` foi informado."
                    },
                    "manual": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Campos inválidos ou mensagem original incompatível"
          },
          "401": {
            "description": "Token inválido"
          },
          "404": {
            "description": "Solicitação original não encontrada"
          },
          "500": {
            "description": "Erro ao consultar a solicitação ou preparar a atualização"
          },
          "502": {
            "description": "Falha no envio. Confira o chat antes de tentar novamente; parte da atualização pode ter sido enviada.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "partial": {
                      "type": "boolean",
                      "description": "`true` quando o pagamento foi atualizado, mas a mensagem do pedido não foi enviada."
                    },
                    "paymentStatusMessageID": {
                      "type": "string",
                      "description": "ID da atualização de pagamento já enviada, quando `partial=true`."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "WhatsApp desconectado"
          }
        }
      }
    },
    "/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.\nO usuário visualiza o detalhe do recebedor, nome e chave.\n\n## Regras principais\n- `pixType` aceita: `CPF`, `CNPJ`, `PHONE`, `EMAIL`, `EVP` (case insensitive)\n- `pixName` padrão: `\"Pix\"` quando não informado - nome de quem recebe o pagamento\n\n\n## Campos comuns\nEste endpoint herda os campos opcionais padronizados da tag **\"Enviar Mensagem\"**:\n`delay`, `readchat`, `readmessages`, `replyid`, `mentions`, `track_source`, `track_id` e `async`.\n\n## Exemplo de payload\n```json\n{\n  \"number\": \"5511999999999\",\n  \"pixType\": \"EVP\",\n  \"pixKey\": \"123e4567-e89b-12d3-a456-426614174000\",\n  \"pixName\": \"Loja Exemplo\"\n}\n```\n",
        "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": "#/components/schemas/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.\n\nEste endpoint cobre apenas mensagens diretas enviadas com `async=true`. Ele **não** representa:\n- campanhas de envio em massa do sender (`/sender/*`)\n\nA resposta padrão foi pensada para clientes:\n- `status`: visão resumida da fila (`idle`, `queued`, `processing`, `waiting_connection`, `waiting_warmup`, `waiting_history`, `resetting`)\n- `pending`: quantidade total estimada de mensagens pendentes\n- `processingNow`: indica se uma mensagem está sendo processada neste momento\n- `acceptingNewMessages`: indica se a fila aceita novos envios async\n- `sessionReady`: indica se a sessão WhatsApp está pronta para envio\n- `resetting`: indica se a fila está pausada por reset/clear\n",
        "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",
                          "enum": [
                            "idle",
                            "queued",
                            "processing",
                            "waiting_connection",
                            "waiting_warmup",
                            "waiting_history",
                            "resetting"
                          ],
                          "example": "waiting_connection"
                        },
                        "pending": {
                          "type": "integer",
                          "format": "int64",
                          "description": "Quantidade total estimada de mensagens pendentes",
                          "example": 3
                        },
                        "processingNow": {
                          "type": "boolean",
                          "description": "Indica se há uma mensagem sendo processada 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
                        },
                        "historyReady": {
                          "type": "boolean",
                          "description": "Indica se o histórico necessário para processar a fila está pronto",
                          "example": true
                        },
                        "warmupRemainingMs": {
                          "type": "integer",
                          "format": "int64",
                          "description": "Tempo estimado restante da preparação da sessão, em milissegundos",
                          "example": 1500
                        },
                        "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`.\n\nEste endpoint atua apenas nos envios diretos com `async=true`. Ele **não** afeta:\n- campanhas do sender (`/sender/*`)\n- mensagens já enviadas com sucesso\n- mensagens em massa agendadas\n\nUse quando houver uma fila acumulada ou quando for necessário cancelar todos\nos envios assíncronos ainda não concluídos. Depois da limpeza, a instância\nvolta a aceitar novos envios com `async=true`.\n",
        "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
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/instance/updateDelaySettings": {
      "post": {
        "operationId": "updateDelaySettings",
        "tags": [
          "Mensagem Async"
        ],
        "summary": "Configurar delay entre mensagens async",
        "description": "Configura o intervalo de tempo entre mensagens diretas enviadas com `async=true`.\n\n### Detalhes\n- Configuração aplicada apenas à fila interna de mensagens async\n- Afeta mensagens enviadas pelos endpoints de envio com `async=true`\n- Não afeta campanhas do sender (`/sender/*`)\n- Delay mínimo (msg_delay_min): 0 ou mais segundos (0 = sem delay)\n- Delay máximo (msg_delay_max): se menor que min, será ajustado para o mesmo valor de min\n- Sistema ajusta automaticamente valores negativos para 0\n\n### Exemplo\n```json\n{\n  \"msg_delay_min\": 0,\n  \"msg_delay_max\": 2\n}\n```\n",
        "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": "#/components/schemas/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"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/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).\n\n## Parâmetros\n\n- **id** (string, obrigatório): ID da mensagem\n- **return_base64** (boolean, default: false): Inclui o arquivo em base64. Evite esta opção porque aumenta o uso de memória, processamento e o tamanho da resposta. Versões futuras poderão limitar base64 para arquivos maiores que 5 MB.\n- **generate_mp3** (boolean, default: true): Para áudios, define formato de retorno\n  - `true`: Retorna MP3\n  - `false`: Retorna OGG\n- **return_link** (boolean, mantido para compatibilidade): A resposta inclui a URL pública do arquivo\n- **transcribe** (boolean, default: false): Transcreve áudios para texto\n- **openai_apikey** (string, opcional): Chave OpenAI para transcrição\n  - Se não informada, usa a chave salva na instância\n  - Se informada, atualiza e salva na instância para próximas chamadas\n- **download_quoted** (boolean, default: false): Baixa mídia da mensagem citada\n  - Útil para baixar conteúdo original de status do WhatsApp\n  - Quando uma mensagem é resposta a um status, permite baixar a mídia do status original\n  - **Contextualização**: Ao baixar a mídia citada, você identifica o contexto da conversa\n    - Exemplo: Se alguém responde a uma promoção, baixando a mídia você saberá que a pergunta é sobre aquela promoção específica\n\n## Exemplos\n\n### Baixar áudio como MP3:\n```json\n{\n  \"id\": \"7EB0F01D7244B421048F0706368376E0\",\n  \"generate_mp3\": true\n}\n```\n\n### Transcrever áudio:\n```json\n{\n  \"id\": \"7EB0F01D7244B421048F0706368376E0\",\n  \"transcribe\": true\n}\n```\n\n### Incluir o conteúdo em base64:\n```json\n{\n  \"id\": \"7EB0F01D7244B421048F0706368376E0\",\n  \"return_base64\": true\n}\n```\n\n### Baixar mídia de status (mensagem citada):\n```json\n{\n  \"id\": \"7EB0F01D7244B421048F0706368376E0\",\n  \"download_quoted\": true\n}\n```\n*Ú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.*\n\n## Resposta\n\n```json\n{\n  \"fileURL\": \"https://api.exemplo.com/files/arquivo.mp3\",\n  \"mimetype\": \"audio/mpeg\",\n  \"base64Data\": \"UklGRkj...\",\n  \"transcription\": \"Texto transcrito\"\n}\n```\n\n**Nota**: \n- Por padrão, áudios são retornados como MP3 e todos os downloads incluem uma URL pública em `fileURL`.\n- Evite `return_base64: true`: a conversão aumenta o uso de memória e processamento no servidor e produz uma resposta maior. Prefira baixar o arquivo por `fileURL`.\n- Compatibilidade futura: o retorno em base64 poderá ser limitado para arquivos maiores que 5 MB. Não dependa de base64 para arquivos grandes.\n- Transcrição requer chave OpenAI válida. A chave pode ser configurada uma vez na instância e será reutilizada automaticamente.\n- Retenção de mídia: o arquivo fica disponível no nosso CDN por 2 dias. Depois disso, `fileURL` deixa de funcionar. Chame este endpoint novamente para gerar uma nova URL, enquanto a mensagem e a mídia original ainda estiverem disponíveis.\n- Para conservar a mídia por mais de 2 dias, baixe o arquivo pela `fileURL` e salve-o em um armazenamento próprio. Guardar somente a URL não aumenta o prazo de retenção.\n",
        "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": "Inclui o conteúdo em base64. Evite em arquivos grandes; versões futuras poderão limitar arquivos maiores que 5 MB",
                    "default": false
                  },
                  "generate_mp3": {
                    "type": "boolean",
                    "description": "Para áudios, define formato de retorno (true=MP3, false=OGG)",
                    "default": true
                  },
                  "return_link": {
                    "type": "boolean",
                    "description": "Mantido para compatibilidade. A URL pública é sempre retornada em fileURL",
                    "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 do arquivo, disponível por 2 dias",
                      "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:\n\n1. **Busca por ID específico**: Use `id` para encontrar uma mensagem exata\n2. **Filtrar por chat**: Use `chatid` para mensagens de uma conversa específica\n3. **Filtrar por rastreamento**: Use `track_source` e `track_id` para mensagens com dados de tracking\n4. **Histórico de ligações**: Use apenas `messageType: call`, `limit` e `offset`\n   para listar as chamadas mais recentes. A resposta pode trazer\n   `callPeer` (identidade conhecida do contato) e `content.isVideo`.\n5. **Limitar resultados**: Use `limit` para controlar quantas mensagens retornar\n6. **Ordenação**: Resultados ordenados por data (mais recentes primeiro)\n",
        "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"
                  },
                  "messageType": {
                    "type": "string",
                    "description": "Tipo da mensagem. Use `call` com `limit` e `offset` para o histórico de ligações.",
                    "example": "call"
                  },
                  "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
                  }
                },
                "callHistory": {
                  "summary": "Histórico de ligações",
                  "value": {
                    "messageType": "call",
                    "limit": 40,
                    "offset": 0
                  }
                }
              }
            }
          }
        },
        "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": "#/components/schemas/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\nou tenta recuperar uma mensagem exata já conhecida localmente.\n\nModos suportados:\n- `history` (padrão): busca histórico para trás a partir de uma mensagem âncora\n- `exact`: tenta recarregar a mensagem exata informada em `messageid`\n\nRegras:\n- envie `number`\n- `mode` é opcional; quando omitido, assume `history`\n- em `mode=history`, `count` é opcional e limitado a 100\n- em `mode=history`, `messageid` é opcional; quando informado, a API usa essa mensagem como referência para buscar mensagens mais antigas do chat\n- em `mode=exact`, `messageid` é obrigatório e `count` não é necessário\n\nObservação:\n- **Importante:** a recuperação pode só acontecer depois de abrir o WhatsApp no celular ou deixá-lo ativo em segundo plano\n- em `mode=history`, `messageid` define a mensagem de referência para carregar histórico anterior\n- em `mode=history`, esse campo não serve para buscar essa mensagem específica\n- em `mode=history`, o histórico é buscado para trás a partir da mensagem de referência informada\n- se você quiser recuperar apenas uma mensagem específica `X` via histórico, informe como `messageid` a mensagem logo depois de `X` e use `count=1`\n- se `messageid` não for informado em `mode=history`, a API usa a mensagem mais antiga conhecida localmente desse chat como referência para buscar histórico anterior\n- em `mode=exact`, a API tenta um rerequest da mensagem exata informada em `messageid`\n- **`mode=exact` está em teste** e funciona melhor quando a mensagem já existe no histórico local da instância\n- as mensagens retornam depois via webhook/SSE em eventos do tipo `history` e também ficam disponíveis em `/message/find`\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "number"
                ],
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "history",
                      "exact"
                    ],
                    "default": "history",
                    "description": "Define o comportamento da operação.\n- `history`: busca mensagens mais antigas a partir de uma âncora\n- `exact`: tenta recuperar a mensagem exata informada em `messageid`\n",
                    "example": "history"
                  },
                  "messageid": {
                    "type": "string",
                    "description": "Em `mode=history`, ID da mensagem de referência usada para buscar mensagens mais antigas do chat.\nEm `mode=exact`, ID exato da mensagem que deve ser recarregada.\n",
                    "example": "3EB01234567890ABCDEF"
                  },
                  "number": {
                    "type": "string",
                    "description": "JID completo do chat. Mantido obrigatório em todos os modos para simplificar o contrato público e restringir a busca ao chat esperado.",
                    "example": "5511999999999@s.whatsapp.net"
                  },
                  "count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "description": "Quantidade desejada de mensagens no sync em `mode=history`. Em `mode=exact`, este campo é ignorado.",
                    "example": 20
                  }
                }
              },
              "examples": {
                "recuperar_mensagem_exata": {
                  "summary": "Recuperar a mensagem exata informada",
                  "value": {
                    "number": "5511999999999@s.whatsapp.net",
                    "mode": "exact",
                    "messageid": "3EB01234567890ABCDEF"
                  }
                },
                "usando_ancora_explicita": {
                  "summary": "Buscar histórico anterior a uma mensagem de referência",
                  "value": {
                    "number": "5511999999999@s.whatsapp.net",
                    "mode": "history",
                    "messageid": "3EB01234567890ABCDEF",
                    "count": 20
                  }
                },
                "recuperar_mensagem_especifica": {
                  "summary": "Recuperar apenas a mensagem imediatamente anterior à referência",
                  "value": {
                    "number": "5511999999999@s.whatsapp.net",
                    "mode": "history",
                    "messageid": "3EB0MENSAGEM_LOGO_APOS_X",
                    "count": 1
                  }
                },
                "usando_ancora_local": {
                  "summary": "Reutilizar âncora local já persistida",
                  "value": {
                    "number": "5511999999999@s.whatsapp.net",
                    "mode": "history",
                    "count": 50
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Solicitação enviada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "mode": {
                      "type": "string",
                      "example": "history"
                    },
                    "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 de histórico enviada",
                    "value": {
                      "success": true,
                      "mode": "history",
                      "message": "History sync request sent. Messages will be received as history sync events."
                    }
                  },
                  "exact_padrão": {
                    "summary": "Solicitação de mensagem exata enviada",
                    "value": {
                      "success": true,
                      "mode": "exact",
                      "message": "Exact message reload request sent. The message will be received if available."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payload inválido, modo inválido ou âncora insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "number is required"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Mensagem exata não encontrada no histórico local",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "messageid not found in local history for chat; use mode=history to fetch older messages first"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro interno ao solicitar o history sync ou o rerequest exato",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Failed to request history: connection closed"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/instance/history-sync/status": {
      "get": {
        "operationId": "getHistorySyncStatus",
        "security": [
          {
            "token": []
          }
        ],
        "tags": [
          "Instancia"
        ],
        "summary": "Consultar o processamento do histórico inicial",
        "description": "Retorna o diagnóstico em memória da sincronização de histórico iniciada no\npareamento mais recente desta instância. Não inicia uma nova sincronização.\n\n`deliveryStatus` pode ser `pending`, `delivered`, `partial`, `failed`,\n`no_webhook` ou `no_batches`. O progresso informado pelo WhatsApp chegar a\n100 não significa, sozinho, que todos os lotes já foram entregues.\n\nO rastreamento é isolado por instância, limitado aos eventos recentes e\nreiniciado junto com o processo. URLs de webhook podem aparecer no\ndiagnóstico; trate a resposta como informação operacional sensível.\n",
        "responses": {
          "200": {
            "description": "Estado observado da sincronização mais recente, ou diagnóstico sem rastreamento.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "diagnosis"
                  ],
                  "properties": {
                    "progress": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 100
                    },
                    "processingStopped": {
                      "type": "boolean"
                    },
                    "processingComplete": {
                      "type": "boolean"
                    },
                    "pendingEmissions": {
                      "type": "integer"
                    },
                    "totalBatches": {
                      "type": "integer"
                    },
                    "deliveryStatus": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "delivered",
                        "partial",
                        "failed",
                        "no_webhook",
                        "no_batches"
                      ]
                    },
                    "pairedAt": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "diagnosis": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "noWebhookConfigured": {
                      "type": "boolean"
                    },
                    "serializationFailures": {
                      "type": "integer"
                    },
                    "received": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "emitted": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "batches": {
                            "type": "integer"
                          },
                          "items": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "webhooks": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "events": {
                      "type": "array",
                      "maxItems": 100,
                      "items": {
                        "type": "object",
                        "properties": {
                          "at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "stage": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "detail": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "sem_rastreamento": {
                    "value": {
                      "pairedAt": null,
                      "diagnosis": [
                        "no_trace"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token da instância ausente ou inválido."
          }
        }
      }
    },
    "/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:\n1. Marcar múltiplas mensagens como lidas de uma vez\n2. Atualizar o status de leitura no WhatsApp\n3. Sincronizar o status de leitura entre dispositivos\n\nExemplo de requisição básica:\n```json\n{\n  \"id\": [\n    \"62AD1AD844E518180227BF68DA7ED710\",\n    \"ECB9DE48EB41F77BFA8491BFA8D6EF9B\"  \n  ]\n}\n```\n\nExemplo de resposta:\n```json\n{\n  \"success\": true,\n  \"message\": \"Messages marked as read\",\n  \"markedMessages\": [\n    {\n      \"id\": \"62AD1AD844E518180227BF68DA7ED710\",\n      \"timestamp\": 1672531200000\n    },\n    {\n      \"id\": \"ECB9DE48EB41F77BFA8491BFA8D6EF9B\",\n      \"timestamp\": 1672531300000\n    }\n  ]\n}\n```\n\nParâmetros disponíveis:\n- id: Lista de IDs das mensagens a serem marcadas como lidas\n\nErros comuns:\n- 401: Token inválido ou expirado\n- 400: Lista de IDs vazia ou inválida\n- 404: Uma ou mais mensagens não encontradas\n- 500: Erro ao marcar mensagens como lidas\n",
        "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.\n\nInforme apenas `id` e `text`. O chat e o autor da mensagem alvo são obtidos\nda mensagem salva na instância. O campo legado `number` é opcional e ignorado.\n\nEste endpoint permite:\n\n1. Adicionar ou remover reações em mensagens\n\n2. Usar qualquer emoji Unicode válido\n\n3. Reagir a mensagens em chats individuais ou grupos\n\n4. Remover reações existentes\n\n5. Verificar o status da reação enviada\n\n\nTipos de reações suportados:\n\n- Qualquer emoji Unicode válido (👍, ❤️, 😂, etc)\n\n- String vazia para remover reação\n\n\nExemplo de requisição básica:\n\n```json\n\n{\n  \"text\": \"👍\",\n  \"id\": \"3EB0538DA65A59F6D8A251\"\n}\n\n```\n\n\nExemplo de requisição para remover reação:\n\n```json\n\n{\n  \"text\": \"\",\n  \"id\": \"3EB0538DA65A59F6D8A251\"\n}\n\n```\n\n\nExemplo de resposta:\n\n```json\n\n{\n  \"success\": true,\n  \"message\": \"Reaction sent\",\n  \"reaction\": {\n    \"id\": \"3EB0538DA65A59F6D8A251\",\n    \"emoji\": \"👍\",\n    \"timestamp\": 1672531200000,\n    \"status\": \"sent\"\n  }\n}\n\n```\n\n\nExemplo de resposta ao remover reação:\n\n```json\n\n{\n  \"success\": true,\n  \"message\": \"Reaction removed\",\n  \"reaction\": {\n    \"id\": \"3EB0538DA65A59F6D8A251\",\n    \"emoji\": null,\n    \"timestamp\": 1672531200000,\n    \"status\": \"removed\"\n  }\n}\n\n```\n\n\nParâmetros disponíveis:\n\n- text: Emoji Unicode da reação (ou string vazia para remover reação)\n\n- id: ID da mensagem que receberá a reação\n\n\nErros comuns:\n\n- 401: Token inválido ou expirado\n\n- 400: ID ausente ou dados inválidos\n\n- 404: Mensagem não encontrada\n\n- 500: Erro ao enviar reação\n\n\nLimitações:\n\n- Só é possível reagir a mensagens enviadas por outros usuários\n\n- Não é possível reagir a mensagens antigas (mais de 7 dias)\n\n- O mesmo usuário só pode ter uma reação ativa por mensagem\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "examples": {
                "react": {
                  "summary": "Adicionar uma reação",
                  "value": {
                    "id": "3EB0538DA65A59F6D8A251",
                    "text": "👍"
                  }
                },
                "remove": {
                  "summary": "Remover a reação",
                  "value": {
                    "id": "3EB0538DA65A59F6D8A251",
                    "text": ""
                  }
                }
              },
              "schema": {
                "type": "object",
                "properties": {
                  "number": {
                    "type": "string",
                    "deprecated": true,
                    "description": "Campo legado opcional e ignorado. O chat é obtido da mensagem identificada por id."
                  },
                  "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": [
                  "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.\n\n### Funcionalidades:\n- Apaga mensagens em conversas individuais ou grupos\n- Funciona com mensagens enviadas pelo usuário ou recebidas\n- Atualiza o status no histórico da instância\n- Envia webhook de atualização\n\n**Notas Técnicas**:\n1. O ID da mensagem pode ser fornecido em dois formatos:\n   - ID completo (contém \":\"): usado diretamente\n   - ID curto: associado automaticamente à instância autenticada\n2. Gera evento webhook do tipo \"messages_update\"\n3. Atualiza o status da mensagem para \"Deleted\"\n4. Para newsletters/canais, use `POST /newsletter/messages/delete`\n",
        "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.\n\nUse esta operação para corrigir o texto de uma mensagem enviada pela própria\ninstância. A resposta retorna a mensagem atualizada e a alteração também\naparece nos eventos configurados.\n\n**Importante**:\n- Só é possível editar mensagens enviadas pela própria instância\n- A mensagem precisa estar disponível no histórico da instância\n- O ID pode ser fornecido no formato completo retornado pela API ou apenas como `messageid`\n- A mensagem deve estar dentro do prazo permitido pelo WhatsApp para edição\n- Para newsletters/canais, use `POST /newsletter/messages/edit`\n",
        "security": [
          {
            "token": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "text"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "ID completo retornado pela API ou apenas o 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 completo da mensagem retornado pela API",
                      "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.\n\nUse esta operação para destacar uma mensagem importante em uma conversa\nindividual ou grupo. A resposta registra a ação e ela também aparece nos\neventos configurados.\n\n**Importante**:\n- O ID pode ser fornecido no formato completo retornado pela API ou apenas como `messageid`\n- Em conversas `1:1`, a ação é suportada normalmente\n- Em grupos, a permissão depende da configuração do WhatsApp do grupo (`apenas admins` ou `qualquer membro`)\n- Em grupos, a permissão final depende das configurações do próprio grupo\n- Newsletters/canais não são suportados neste endpoint\n- Se `pin` não for enviado, o valor padrão é `true`\n- Ao fixar mensagem, `duration` aceita dias (`1`, `7` ou `30`)\n- Se `duration` não for enviado ou vier com qualquer outro valor, a API usa `30` dias\n- Ao desafixar (`pin: false`), `duration` é ignorado\n",
        "security": [
          {
            "token": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "ID completo retornado pela API ou apenas o `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 grupo com participantes iniciais opcionais. O WhatsApp inclui o criador automaticamente.\n\nEnvie `participants: []`, omita o campo ou use `null` para criar um grupo somente com o criador. Informar apenas o próprio PN/LID tem o mesmo efeito; não é necessário adicionar o criador manualmente.\n\nPara convidar outras pessoas, informe números com DDI (apenas dígitos) ou JIDs PN completos, como `5511999999999@s.whatsapp.net`. JIDs LID conhecidos pela instância também são aceitos. Participantes são verificados e duplicatas/aliases do criador são removidos. Uma lista com convidados inválidos e nenhum convidado válido continua retornando 400; ela não é convertida silenciosamente em grupo vazio.\n\nA resposta contém `group` e `failed`. Depois da criação, o administrador pode obter o convite em `GET /group/invitelink/{groupJID}`, usando `group.JID`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Nome do grupo",
                    "minLength": 1,
                    "maxLength": 100,
                    "example": "Orkesio grupo"
                  },
                  "participants": {
                    "description": "Convidados iniciais opcionais. Vazio, omitido ou null cria o grupo somente com o criador, incluído automaticamente pelo WhatsApp.",
                    "oneOf": [
                      {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "description": "Número com DDI, JID PN completo ou LID conhecido pela instância."
                        },
                        "minItems": 0,
                        "example": [
                          "5521987905995",
                          "5511912345678"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "name"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "name": "Meu Novo Grupo",
                    "participants": [
                      "5521987905995"
                    ]
                  }
                },
                "multiple_participants": {
                  "value": {
                    "name": "Equipe de Projeto",
                    "participants": [
                      "5521987905995",
                      "5511912345678",
                      "5519987654321"
                    ]
                  }
                },
                "only_creator": {
                  "summary": "Grupo somente com o criador, para entrada posterior por convite",
                  "value": {
                    "name": "Nome do grupo",
                    "participants": []
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Grupo criado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "group",
                    "failed"
                  ],
                  "properties": {
                    "group": {
                      "$ref": "#/components/schemas/Group"
                    },
                    "failed": {
                      "type": "array",
                      "description": "JIDs dos convidados que falharam na validação ou inclusão. Vazio quando não houve falhas.",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payload inválido ou lista de convidados sem nenhum participante válido. Lista vazia ou somente com o criador é aceita.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "no valid WhatsApp participants"
                    },
                    "failed": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Presente quando o erro vem da preparação dos participantes."
                    }
                  }
                }
              }
            }
          },
          "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": "Consultar detalhes e membros de um grupo",
        "description": "Use esta operação depois de selecionar um grupo na listagem. Informe apenas `groupjid` para receber dados, participantes conhecidos e permissões daquele grupo.\n\nFotos e informações da comunidade relacionada são incluídas quando disponíveis.\n\n### Opções avançadas\n- getInviteLink e getRequestsParticipants solicitam dados adicionais, somente para administrador com permissão confirmada. Os campos podem estar ausentes sem essa permissão.\n- force solicita atualização remota; deixe false no fluxo normal.\n- O uso normal precisa apenas de `groupjid`; adicione opções avançadas somente quando necessárias.\n",
        "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": "Opcional/avançado: solicita o convite, disponível somente para administrador com permissão confirmada.",
                    "default": false,
                    "example": true
                  },
                  "getRequestsParticipants": {
                    "type": "boolean",
                    "description": "Opcional/avançado: solicita pedidos de entrada, disponíveis somente para administrador com permissão confirmada.",
                    "default": false,
                    "example": false
                  },
                  "force": {
                    "type": "boolean",
                    "description": "Avançado: solicita atualização remota. O uso normal precisa apenas de groupjid.",
                    "default": false,
                    "example": false
                  }
                },
                "required": [
                  "groupjid"
                ]
              },
              "example": {
                "groupjid": "120363153742561022@g.us"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Informações do grupo obtidas com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Group"
                },
                "example": {
                  "JID": "120363153742561022@g.us",
                  "Name": "Orkesio Community",
                  "Participants": [
                    {
                      "JID": "5521987654321@s.whatsapp.net",
                      "IsAdmin": true
                    }
                  ],
                  "IsLocked": false,
                  "IsAnnounce": false
                }
              }
            }
          },
          "400": {
            "description": "Payload ou groupjid inválido.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Could not parse Group JID"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Falha ao obter informações de um grupo inexistente, indisponível ou do qual a conta não participa mais.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Failed to retrieve group information"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "token": []
          }
        ]
      }
    },
    "/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.\n\nEsta rota permite:\n- Recuperar informações básicas sobre um grupo antes de entrar\n- Validar um link de convite\n- Obter detalhes como nome do grupo, número de participantes e restrições de entrada\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "invitecode": {
                    "type": "string",
                    "description": "Código de convite ou URL completo do grupo.\nPode ser um código curto ou a URL completa do WhatsApp.\n",
                    "examples": [
                      "IYnl5Zg9bUcJD32rJrDzO7",
                      "https://chat.whatsapp.com/IYnl5Zg9bUcJD32rJrDzO7"
                    ]
                  }
                },
                "required": [
                  "invitecode"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Informações do grupo obtidas com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Group"
                },
                "example": {
                  "JID": "120363153742561022@g.us",
                  "Name": "Orkesio 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/invitelink/{groupJID}": {
      "get": {
        "operationId": "getGroupInviteLink",
        "tags": [
          "Grupos e Comunidades"
        ],
        "summary": "Gerar link de convite para um grupo",
        "description": "Retorna o link de convite para o grupo especificado. \nEsta operação requer que a conta conectada seja administradora do grupo.\n",
        "security": [
          {
            "token": []
          }
        ],
        "parameters": [
          {
            "name": "groupJID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "JID (ID do grupo) no formato WhatsApp.",
              "example": "120363153742561022@g.us"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Link de convite gerado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "inviteLink"
                  ],
                  "properties": {
                    "inviteLink": {
                      "type": "string",
                      "description": "Link de convite completo para o grupo",
                      "example": "https://chat.whatsapp.com/AbCdEfGhIjKlMnOpQrStUv"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Erro ao processar a solicitação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Descrição do erro"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token inválido ou ausente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro interno do servidor",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Detalhes do erro interno"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/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. \n\nCaracterísticas:\n- Suporta código de convite ou URL completo\n- Valida o código antes de tentar entrar no grupo\n- Retorna informações básicas do grupo após entrada bem-sucedida\n- Trata possíveis erros como convite inválido ou expirado\n",
        "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. \nFormatos aceitos:\n- Código completo: \"IYnl5Zg9bUcJD32rJrDzO7\"\n- URL completa: \"https://chat.whatsapp.com/IYnl5Zg9bUcJD32rJrDzO7\"\n",
                    "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": "#/components/schemas/Group"
                    },
                    "needs_refresh": {
                      "type": "boolean",
                      "description": "Indica se os detalhes do grupo precisam ser consultados novamente",
                      "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.\n\nRequisitos:\n- O usuário deve estar conectado a uma instância válida\n- O usuário deve ser um membro do grupo\n\nComportamentos:\n- Se o usuário for o último administrador, o grupo será dissolvido\n- Se o usuário for um membro comum, será removido do grupo\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "groupjid": {
                    "type": "string",
                    "description": "Identificador único do grupo (JID)\n- Formato: número@g.us\n- Exemplo válido: 120363324255083289@g.us\n",
                    "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 (legado)",
        "description": "Mantido para integrações existentes. Retorna a coleção de grupos sem paginação e pode produzir uma resposta grande. Para novas integrações, prefira POST /group/list.\n\n### Opções avançadas\n`noParticipants=true` retorna a lista sem membros, como no POST. `force`\npode reutilizar uma atualização recente. Para consultar membros, use\nPOST /group/info no grupo escolhido.\n",
        "parameters": [
          {
            "name": "force",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Solicita atualização da lista. Pode reutilizar a última atualização bem-sucedida durante o intervalo mínimo local de 20 segundos."
          },
          {
            "name": "noParticipants",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Use true para retornar a lista sem os participantes."
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de grupos recuperada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "groups": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Group"
                      },
                      "description": "Lista detalhada de grupos"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Parâmetro inválido.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "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"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "token": []
          }
        ]
      },
      "post": {
        "operationId": "refreshGroups",
        "tags": [
          "Grupos e Comunidades"
        ],
        "summary": "Listar grupos em páginas (recomendado)",
        "description": "Use esta operação para buscar grupos e escolher qual abrir. Prefira uma página de resumos sem a lista de membros; consulte POST /group/info quando precisar dos detalhes de um grupo.\n\n### Uso recomendado\nEnvie search, limit e offset, com noParticipants=true. O padrão de página é 50 e o máximo é 1000. A busca considera nome, JID, descrição do grupo e nome da comunidade à qual ele pertence. A resposta contém groups e pagination.\n\n### Opções avançadas e compatibilidade\n- O default HTTP de noParticipants continua false para preservar integrações existentes. O exemplo recomendado usa true explicitamente.\n- Para participantes e perfis completos, consulte somente o grupo selecionado em POST /group/info.\n- force solicita atualização do WhatsApp. Normalmente basta deixar a API atualizar quando necessário; não use force em polling contínuo.\n\nUma atualização remota da lista ainda pode receber participantes do WhatsApp; noParticipants=true evita carregá-los na leitura da página e enviá-los na resposta.\n",
        "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,
                    "minimum": 1,
                    "maximum": 1000
                  },
                  "offset": {
                    "type": "integer",
                    "description": "Deslocamento base zero",
                    "default": 0
                  },
                  "search": {
                    "type": "string",
                    "description": "Busca por nome, tópico, JID ou nome da comunidade pai."
                  },
                  "force": {
                    "type": "boolean",
                    "default": false,
                    "description": "Avançado: solicita atualização remota. Não é necessário no fluxo normal; não use em polling contínuo."
                  },
                  "noParticipants": {
                    "type": "boolean",
                    "default": false,
                    "description": "Compatibilidade: true retorna resumos sem membros, como no exemplo recomendado. O default HTTP continua false."
                  }
                }
              },
              "examples": {
                "summaries": {
                  "summary": "Listagem leve para escolher um grupo",
                  "value": {
                    "search": "Suporte",
                    "limit": 50,
                    "offset": 0,
                    "noParticipants": true
                  }
                },
                "next_page": {
                  "summary": "Próxima página de resumos",
                  "value": {
                    "limit": 50,
                    "offset": 50,
                    "noParticipants": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Lista de grupos recuperada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "groups": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/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 retornado, limitado ao intervalo de zero até totalRecords."
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payload inválido.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "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"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "token": []
          }
        ]
      }
    },
    "/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. \nSomente administradores do grupo podem realizar esta ação.\n\nPrincipais características:\n- Invalida o link de convite antigo\n- Cria um novo link único\n- Retorna as informações atualizadas do grupo\n",
        "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": "#/components/schemas/Group"
                    },
                    "needs_refresh": {
                      "type": "boolean",
                      "description": "Indica se os detalhes do grupo precisam ser consultados novamente",
                      "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.\n\nQuando ativado (announce=true):\n- Apenas administradores podem enviar mensagens\n- Outros participantes podem apenas ler\n- Útil para anúncios importantes ou controle de spam\n\nQuando desativado (announce=false):\n- Todos os participantes podem enviar mensagens\n- Configuração padrão para grupos normais\n\nRequer que o usuário seja administrador do grupo para fazer alterações.\n",
        "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": "#/components/schemas/Group"
                    },
                    "needs_refresh": {
                      "type": "boolean",
                      "description": "Indica se os detalhes do grupo precisam ser consultados novamente",
                      "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/updateJoinApproval": {
      "post": {
        "operationId": "updateGroupJoinApproval",
        "tags": [
          "Grupos e Comunidades"
        ],
        "summary": "Configurar aprovação para entrada no grupo",
        "description": "Define se novos participantes precisam ser aprovados antes de entrar no grupo.\nNo objeto retornado em `group` e também em `/group/info`, esse estado aparece no campo `IsJoinApprovalRequired`.\n\nQuando ativado (`IsJoinApprovalRequired=true`):\n- Novas entradas passam por aprovação de administrador\n- Solicitações pendentes podem ser listadas em `/group/info`\n\nQuando desativado (`IsJoinApprovalRequired=false`):\n- Entradas por link/convite não exigem aprovação adicional\n\nRequer que o usuário seja administrador do grupo.\n",
        "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"
                  },
                  "IsJoinApprovalRequired": {
                    "type": "boolean",
                    "description": "Define se a entrada no grupo exige aprovação; reflete no campo `IsJoinApprovalRequired`",
                    "example": true
                  }
                },
                "required": [
                  "groupjid",
                  "IsJoinApprovalRequired"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuração atualizada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "response": {
                      "type": "string",
                      "example": "Group join approval enabled successfully"
                    },
                    "group": {
                      "$ref": "#/components/schemas/Group"
                    },
                    "needs_refresh": {
                      "type": "boolean",
                      "description": "Indica se os detalhes do grupo precisam ser consultados novamente",
                      "example": false
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Aprovação de entrada ativada",
                    "value": {
                      "response": "Group join approval enabled successfully",
                      "group": {
                        "JID": "120363339858396166@g.us",
                        "IsJoinApprovalRequired": true
                      },
                      "needs_refresh": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payload inválido ou campo IsJoinApprovalRequired ausente/inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "IsJoinApprovalRequired is required"
                    }
                  }
                }
              }
            }
          },
          "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/updateMemberAddMode": {
      "post": {
        "operationId": "updateGroupMemberAddMode",
        "tags": [
          "Grupos e Comunidades"
        ],
        "summary": "Configurar quem pode adicionar novos membros ao grupo",
        "description": "Define quem tem permissão para adicionar novos participantes diretamente ao grupo.\nNo objeto retornado em `group` e também em `/group/info`, esse estado aparece no campo `MemberAddMode`.\n\nValores aceitos em `MemberAddMode`:\n- `admin_add`: apenas administradores podem adicionar membros\n- `all_member_add`: qualquer participante pode adicionar membros\n\nRequer que o usuário seja administrador do grupo.\n",
        "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"
                  },
                  "MemberAddMode": {
                    "type": "string",
                    "enum": [
                      "admin_add",
                      "all_member_add"
                    ],
                    "description": "Define quem pode adicionar novos membros ao grupo; reflete no campo `MemberAddMode`",
                    "example": "admin_add"
                  }
                },
                "required": [
                  "groupjid",
                  "MemberAddMode"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuração atualizada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "response": {
                      "type": "string",
                      "example": "Group member add mode set to admin_add successfully"
                    },
                    "group": {
                      "$ref": "#/components/schemas/Group"
                    },
                    "needs_refresh": {
                      "type": "boolean",
                      "description": "Indica se os detalhes do grupo precisam ser consultados novamente",
                      "example": false
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Apenas admins podem adicionar membros",
                    "value": {
                      "response": "Group member add mode set to admin_add successfully",
                      "group": {
                        "JID": "120363339858396166@g.us",
                        "MemberAddMode": "admin_add"
                      },
                      "needs_refresh": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Valor inválido para MemberAddMode"
          },
          "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.\nRequer que o usuário seja administrador do grupo.\nA descrição aparece na tela de informações do grupo e pode ser visualizada por todos os participantes.\n",
        "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": "#/components/schemas/Group"
                    },
                    "needs_refresh": {
                      "type": "boolean",
                      "description": "Indica se os detalhes do grupo precisam ser consultados novamente",
                      "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/ephemeral": {
      "post": {
        "operationId": "updateGroupEphemeral",
        "summary": "Configurar mensagens temporárias em grupo",
        "description": "Define o temporizador de mensagens temporárias (disappearing messages) de um grupo.\n\nValores aceitos para a duração:\n- `0` ou `off` para desativar\n- `1d`\n- `7d`\n- `90d`\n\nObservações:\n- este endpoint é apenas para grupos\n- requer privilégios de administrador do grupo\n- se o identificador informado não for de grupo, a API retorna erro orientando usar `/chat/ephemeral`\n- após sucesso, a resposta devolve o chat e os dados atualizados do grupo\n",
        "tags": [
          "Grupos e Comunidades"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "groupjid",
                  "duration"
                ],
                "properties": {
                  "groupjid": {
                    "type": "string",
                    "description": "JID do grupo no formato xxxxx@g.us",
                    "example": "120363339858396166@g.us"
                  },
                  "duration": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "integer"
                      }
                    ],
                    "description": "Duração desejada para mensagens temporárias",
                    "example": "1d"
                  }
                }
              },
              "examples": {
                "ativar_1_dia": {
                  "summary": "Ativar por 1 dia",
                  "value": {
                    "groupjid": "120363339858396166@g.us",
                    "duration": "1d"
                  }
                },
                "desativar": {
                  "summary": "Desativar mensagens temporárias",
                  "value": {
                    "groupjid": "120363339858396166@g.us",
                    "duration": "off"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Temporizador atualizado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "response": {
                      "type": "string",
                      "example": "Ephemeral timer updated successfully"
                    },
                    "chat": {
                      "$ref": "#/components/schemas/Chat"
                    },
                    "ephemeral": {
                      "type": "object",
                      "properties": {
                        "enabled": {
                          "type": "boolean",
                          "example": true
                        },
                        "seconds": {
                          "type": "integer",
                          "format": "int64",
                          "example": 86400
                        },
                        "label": {
                          "type": "string",
                          "example": "1d"
                        }
                      }
                    },
                    "group": {
                      "$ref": "#/components/schemas/Group"
                    },
                    "needs_refresh": {
                      "type": "boolean",
                      "description": "Indica se os detalhes do grupo precisam ser consultados novamente",
                      "example": false
                    }
                  }
                },
                "examples": {
                  "sucesso": {
                    "summary": "Timer atualizado",
                    "value": {
                      "response": "Ephemeral timer updated successfully",
                      "chat": {
                        "wa_chatid": "120363339858396166@g.us",
                        "wa_ephemeralExpiration": 86400,
                        "wa_isGroup": true
                      },
                      "ephemeral": {
                        "enabled": true,
                        "seconds": 86400,
                        "label": "1d"
                      },
                      "group": {
                        "JID": "120363339858396166@g.us",
                        "IsEphemeral": true,
                        "DisappearingTimer": 86400
                      },
                      "needs_refresh": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payload inválido, grupo inválido ou duração não suportada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid duration. Allowed values: 0, off, 1d, 7d, 90d"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token inválido ou ausente"
          },
          "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"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro interno ao atualizar o temporizador",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Error updating chat ephemeral timer: connection closed"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/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.\n\nRequisitos da imagem:\n- Formato: JPEG\n- Resolução máxima: 640x640 pixels\n- Imagens maiores ou diferente de JPEG não são aceitas pelo WhatsApp\n\nPara remover a imagem atual, envie \"remove\" ou \"delete\" no campo image.\n",
        "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.\nA imagem deve estar em formato JPEG e ter resolução máxima de 640x640.\n",
                    "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": "#/components/schemas/Group"
                    },
                    "needs_refresh": {
                      "type": "boolean",
                      "description": "Indica se os detalhes do grupo precisam ser consultados novamente",
                      "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. \nQuando bloqueado (locked=true), apenas administradores podem alterar nome, descrição, \nimagem e outras configurações do grupo. Quando desbloqueado (locked=false), \nqualquer participante pode editar as informações.\n\nImportante:\n- Requer que o usuário seja administrador do grupo\n- Afeta edições de nome, descrição, imagem e outras informações do grupo\n- Não controla permissões de adição de membros\n",
        "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:\n- true = apenas admins podem editar infos do grupo\n- false = qualquer participante pode editar infos do grupo\n",
                    "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": "#/components/schemas/Group"
                    },
                    "needs_refresh": {
                      "type": "boolean",
                      "description": "Indica se os detalhes do grupo precisam ser consultados novamente",
                      "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.\nO nome do grupo deve seguir as diretrizes do WhatsApp e ter entre 1 e 25 caracteres.\n",
        "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": "#/components/schemas/Group"
                    },
                    "needs_refresh": {
                      "type": "boolean",
                      "description": "Indica se os detalhes do grupo precisam ser consultados novamente",
                      "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:\n- Adicionar ou remover participantes\n- Promover ou rebaixar administradores\n- Aprovar ou rejeitar solicitações pendentes\n\nRequer que o usuário seja administrador do grupo para executar as ações.\n",
        "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:\n- add: Adicionar participantes ao grupo\n- remove: Remover participantes do grupo\n- promote: Promover participantes a administradores\n- demote: Remover privilégios de administrador\n- approve: Aprovar solicitações pendentes de entrada\n- reject: Rejeitar solicitações pendentes de entrada\n",
                    "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.\nPara números de telefone, use formato internacional sem '+' ou espaços.\n",
                    "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": "#/components/schemas/Group",
                      "description": "Informações atualizadas do grupo"
                    },
                    "needs_refresh": {
                      "type": "boolean",
                      "description": "Indica se os detalhes do grupo precisam ser consultados novamente",
                      "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. \n\nA comunidade criada inicialmente terá apenas o grupo principal (announcements), e grupos adicionais podem ser vinculados posteriormente usando o endpoint `/community/updategroups`.\n\n**Observações importantes:**\n- O número que cria a comunidade torna-se automaticamente o administrador\n- A comunidade terá um grupo principal de anúncios criado automaticamente\n",
        "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": "#/components/schemas/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.\n\n## Funcionalidades\n- Adicionar múltiplos grupos simultaneamente a uma comunidade\n- Remover grupos de uma comunidade existente\n- Suporta operações em lote\n\n## Limitações\n- Os grupos devem existir previamente\n- A comunidade deve existir e o usuário deve ser administrador\n- Grupos já vinculados não podem ser adicionados novamente\n- Grupos não vinculados não podem ser removidos\n\n## Ações Disponíveis\n- `add`: Adiciona os grupos especificados à comunidade\n- `remove`: Remove os grupos especificados da comunidade\n",
        "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:\n* add - Adiciona grupos à comunidade\n* remove - Remove grupos da comunidade\n"
                  },
                  "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.\n\nObservações:\n- `name` é obrigatório\n- `picture` é opcional\n- `picture` aceita URL HTTP/HTTPS, base64 puro ou data URI\n- imagens acima de 1 MB são rejeitadas\n",
        "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",
                  "required": [
                    "response"
                  ],
                  "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": "Lista os canais seguidos pela conta conectada. Use para montar uma tela de\ncanais antes de consultar posts, silenciar notificações ou deixar de seguir.\n",
        "responses": {
          "200": {
            "description": "Lista de canais recuperada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "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": "Retorna nome, descrição, imagem e demais informações disponíveis de um canal\npelo `jid`. Use antes de exibir o canal ou executar ações administrativas.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "example": "120363123456789012@newsletter"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Informações do canal recuperadas com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "JID inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid newsletter jid"
                    }
                  }
                }
              }
            }
          },
          "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": "Resolve uma chave de convite e apresenta as informações do canal antes da\nentrada, sem exigir que a conta já siga esse canal.\n",
        "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",
                  "required": [
                    "response"
                  ],
                  "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.\n\nObservação:\n- esta rota retorna apenas a duração da assinatura temporária\n- isso não cria um novo evento de webhook\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "example": "120363123456789012@newsletter"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Assinatura criada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "type": "string",
                      "description": "Duração retornada pelo WhatsApp.",
                      "example": "5m0s"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "JID inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid newsletter jid"
                    }
                  }
                }
              }
            }
          },
          "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).\n\nEsta rota não depende de mensagens salvas localmente e é útil para:\n- carregar o histórico recente de posts de um canal\n- paginar mensagens anteriores usando `beforeid`\n- consumir conteúdo de newsletters sem persistência em banco\n\nIdentificação do canal:\n- envie `id` com o identificador numérico do canal; a API normaliza para `@newsletter`\n- ou envie `jid` completo no formato `1234567890@newsletter`\n\nObservações:\n- `count` controla quantos posts retornar\n- use preferencialmente `beforeid`\n- `beforeid` pagina para trás a partir de um `serverid`\n- o retorno vem no campo `response`\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "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.\nUse para paginação retroativa.\n",
                    "example": 12345
                  }
                }
              },
              "examples": {
                "basico": {
                  "summary": "Buscar últimos posts do canal",
                  "value": {
                    "jid": "120363123456789012@newsletter",
                    "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",
                  "required": [
                    "response"
                  ],
                  "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 JID do canal inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid newsletter jid"
                    }
                  }
                }
              }
            }
          },
          "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.\n\nEsta rota:\n- nao depende de mensagens salvas localmente\n- busca a mensagem recente diretamente no canal do WhatsApp\n- localiza o post por `messageid` ou `serverid`\n- edita apenas tipos suportados (`text`, `image`, `video`, `document`)\n\nObservações:\n- use `jid` para identificar o canal\n- envie ao menos um entre `messageid` e `serverid`\n- envie `text` ou `caption` com o novo conteúdo/legenda\n- para posts de mídia, `mediahandle` pode informar o handle já conhecido\n- `count` e `maxpages` controlam a janela de busca no canal\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "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"
                  },
                  "caption": {
                    "type": "string",
                    "description": "Alias de `text` para atualizar a legenda de posts de mídia.",
                    "example": "Nova legenda"
                  },
                  "mediahandle": {
                    "type": "string",
                    "description": "Handle de mídia já conhecido, usado quando a edição precisa preservar a mídia do post."
                  },
                  "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": {
                    "jid": "120363123456789012@newsletter",
                    "serverid": 12345,
                    "text": "Nova legenda do post"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mensagem do canal editada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "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 or caption 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.\n\nEsta rota:\n- nao depende de mensagens salvas localmente\n- revoga o post diretamente no canal do WhatsApp\n- aceita localizar o post por `messageid` ou `serverid`\n\nObservações:\n- use `jid` para identificar o canal\n- envie ao menos um entre `messageid` e `serverid`\n- `count` e `maxpages` controlam a janela de busca no canal\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "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": {
                    "jid": "120363123456789012@newsletter",
                    "serverid": 12345
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mensagem do canal deletada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "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.\n\nEsta rota é diferente de `/newsletter/messages`:\n- `/newsletter/messages` retorna o conteúdo dos posts\n- `/newsletter/updates` retorna mudanças posteriores nos posts, especialmente métricas\n\nEsta rota também não é um evento de webhook:\n- não existe webhook `newsletter_messages_update`\n- para views e reactions de canais, consulte `/newsletter/updates` sob demanda\n\nCasos de uso:\n- atualizar contadores de `views` de posts já carregados\n- atualizar `reactionCounts` de posts do canal\n- consultar sob demanda os mesmos tipos de métricas que chegam nos live updates internos do WhatsApp\n\nObservações:\n- use preferencialmente `afterid`\n- `afterid` filtra updates depois de um `serverid`\n- `since` filtra pelo momento do update\n- `since` aceita timestamp em segundos ou milissegundos\n- o retorno vem no campo `response`\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "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.\n- Se maior que `1000000000000`, é interpretado como milissegundos.\n- Caso contrário, é interpretado como segundos.\n",
                    "example": 1710000000
                  }
                }
              },
              "examples": {
                "por_after_id": {
                  "summary": "Buscar updates depois de um post conhecido",
                  "value": {
                    "jid": "120363123456789012@newsletter",
                    "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",
                  "required": [
                    "response"
                  ],
                  "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.\nEm muitos live updates esse campo pode vir ausente.\n",
                            "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 JID do canal inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid newsletter jid"
                    }
                  }
                }
              }
            }
          },
          "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`.\n\nObservações:\n- envie `serverids` com uma lista de posts\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid",
                  "serverids"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "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",
                  "required": [
                    "response"
                  ],
                  "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.\n\nObservações:\n- `serverid` identifica o post alvo\n- `reaction` define o emoji\n- envie `reaction` vazio para remover a reação\n- `reactionmessageid` é opcional; se omitido, o WhatsApp gera o ID da reação\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid",
                  "serverid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "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",
                  "required": [
                    "response"
                  ],
                  "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": "Faz a conta conectada seguir um canal, que então passa a aparecer na listagem e fica disponível para consulta de posts.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "example": "120363123456789012@newsletter"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Canal seguido com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "JID inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid newsletter jid"
                    }
                  }
                }
              }
            }
          },
          "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": "Remove o canal da lista seguida pela conta conectada sem apagar o canal nem seus posts.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "example": "120363123456789012@newsletter"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Canal removido dos seguidos com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "JID inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid newsletter jid"
                    }
                  }
                }
              }
            }
          },
          "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": "Silencia as notificações de um canal sem deixar de segui-lo; os posts continuam disponíveis para consulta.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "example": "120363123456789012@newsletter"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Canal silenciado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "JID inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid newsletter jid"
                    }
                  }
                }
              }
            }
          },
          "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": "Reativa as notificações de um canal anteriormente silenciado, mantendo a inscrição e o histórico disponíveis.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "example": "120363123456789012@newsletter"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mute removido com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "JID inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid newsletter jid"
                    }
                  }
                }
              }
            }
          },
          "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": "Exclui um canal administrado pela conta conectada. Para apenas parar de acompanhar um canal, use a operação de deixar de seguir.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "example": "120363123456789012@newsletter"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Canal deletado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "JID inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid newsletter jid"
                    }
                  }
                }
              }
            }
          },
          "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.\n\nObservações:\n- `picture` aceita URL HTTP/HTTPS, base64 puro ou data URI\n- imagens acima de 1 MB são rejeitadas\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid",
                  "picture"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "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",
                  "required": [
                    "response"
                  ],
                  "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": "Altera o nome público de um canal administrado pela conta conectada, facilitando sua identificação pelos participantes.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid",
                  "name"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "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",
                  "required": [
                    "response"
                  ],
                  "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 pública do canal para explicar o tema, a frequência e o conteúdo publicado.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "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",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payload inválido ou JID inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid newsletter jid"
                    }
                  }
                }
              }
            }
          },
          "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.\n\nAtualmente, esta rota controla `reactionCodes`.\n\nValores aceitos:\n- `all`\n- `basic`\n- `none`\n- `blocklist`\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid",
                  "reactionCodes"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "example": "120363123456789012@newsletter"
                  },
                  "reactionCodes": {
                    "type": "string",
                    "example": "basic"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configurações atualizadas com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "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.\n\nObservações:\n- use `after` para buscar a próxima página\n- `countryCodes` filtra por países\n- `view` e `searchText` são opcionais\n",
        "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",
                  "required": [
                    "response"
                  ],
                  "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": "Envia a um telefone um convite para administrar o canal. O acesso só muda depois que o destinatário aceitar.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid",
                  "phone"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "example": "120363123456789012@newsletter"
                  },
                  "phone": {
                    "type": "string",
                    "example": "5511999999999"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Convite enviado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "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 e torna a conta conectada administradora do canal informado.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "example": "120363123456789012@newsletter"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Convite aceito com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "JID inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid newsletter jid"
                    }
                  }
                }
              }
            }
          },
          "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 as permissões administrativas de um participante pelo telefone sem deixar de segui-lo automaticamente.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid",
                  "phone"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "example": "120363123456789012@newsletter"
                  },
                  "phone": {
                    "type": "string",
                    "example": "5511999999999"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Admin removido com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "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": "Cancela um convite de administrador que ainda não foi aceito; administradores ativos não são removidos por esta operação.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid",
                  "phone"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "example": "120363123456789012@newsletter"
                  },
                  "phone": {
                    "type": "string",
                    "example": "5511999999999"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Convite revogado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "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.\n\nObservações:\n- `phone` é obrigatório\n- `quitAdmin=true` remove o dono anterior da posição de admin após a transferência\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jid",
                  "phone"
                ],
                "properties": {
                  "jid": {
                    "type": "string",
                    "description": "JID do canal. Aceita o formato completo `120363123456789012@newsletter` ou apenas o identificador numérico.",
                    "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",
                  "required": [
                    "response"
                  ],
                  "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:\n- URL configurada\n- Eventos ativos\n- Filtros aplicados\n- Configurações adicionais\n\nExemplo de resposta:\n```json\n[\n  {\n    \"id\": \"123e4567-e89b-12d3-a456-426614174000\",\n    \"enabled\": true,\n    \"url\": \"https://example.com/webhook\",\n    \"events\": [\"messages\", \"messages_update\"],\n    \"excludeMessages\": [\"wasSentByApi\", \"isGroupNo\"],\n    \"addUrlEvents\": true,\n    \"addUrlTypesMessages\": true\n  },\n  {\n    \"id\": \"987fcdeb-51k3-09j8-x543-864297539100\",\n    \"enabled\": true,\n    \"url\": \"https://outro-endpoint.com/webhook\",\n    \"events\": [\"connection\", \"presence\"],\n    \"excludeMessages\": [],\n    \"addUrlEvents\": false,\n    \"addUrlTypesMessages\": false\n  }\n]\n```\n\nA resposta é sempre um array, mesmo quando há apenas um webhook configurado.\n",
        "responses": {
          "200": {
            "description": "Configuração do webhook retornada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/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.\nPermite gerenciar múltiplos webhooks por instância através do campo ID e action.\n\n### 🚀 Modo Simples (Recomendado)\n\n**Uso mais fácil - sem complexidade de IDs**:\n- Não inclua `action` nem `id` no payload\n- Gerencia automaticamente um único webhook por instância\n- Cria novo ou atualiza o existente automaticamente\n- **Recomendado**: Sempre use `\"excludeMessages\": [\"wasSentByApi\"]` para evitar loops\n- **Exemplo**: `{\"url\": \"https://meusite.com/webhook\", \"events\": [\"messages\"], \"excludeMessages\": [\"wasSentByApi\"]}`\n\n### 🧪 Sites para Testes (ordenados por qualidade)\n\n**Para testar webhooks durante desenvolvimento**:\n1. **https://webhook.cool/** - ⭐ Melhor opção (sem rate limit, interface limpa)\n2. **https://rbaskets.in/** - ⭐ Boa alternativa (confiável, baixo rate limit)\n3. **https://webhook.site/** - ⚠️ Evitar se possível (rate limit agressivo)\n\n### ⚙️ Modo Avançado (Para múltiplos webhooks)\n\n**Para usuários que precisam de múltiplos webhooks por instância**:\n\n💡 **Dica**: Mesmo precisando de múltiplos webhooks, considere usar `addUrlEvents` no modo simples.\nUm único webhook pode receber diferentes tipos de eventos em URLs específicas \n(ex: `/webhook/message`, `/webhook/connection`), eliminando a necessidade de múltiplos webhooks.\n\n1. **Criar Novo Webhook**:\n   - Use `action: \"add\"`\n   - Não inclua `id` no payload\n   - O sistema gera ID automaticamente\n\n2. **Atualizar Webhook Existente**:\n   - Use `action: \"update\"`\n   - Inclua o `id` do webhook no payload\n   - Todos os campos serão atualizados\n\n3. **Remover Webhook**:\n   - Use `action: \"delete\"`\n   - Inclua apenas o `id` do webhook\n   - Outros campos são ignorados\n\n\n\n### Eventos Disponíveis\n- `connection`: Alterações no estado da conexão\n- `history`: Recebimento de histórico de mensagens\n- `messages`: Novas mensagens recebidas\n- `messages_update`: Atualizações em mensagens existentes\n- `newsletter_messages`: Novos posts/mensagens de canais do WhatsApp\n  Para views e reactions de canais, use a rota `/newsletter/updates`.\n- `call`: Eventos de chamadas VoIP\n- `contacts`: Atualizações na agenda de contatos\n- `presence`: Alterações no status de presença\n- `groups`: Modificações em grupos\n- `labels`: Gerenciamento de etiquetas\n- `chats`: Eventos de conversas\n- `chat_labels`: Alterações em etiquetas de conversas\n- `sender`: Atualizações de campanhas, quando inicia, e quando completa\n\n**Remover mensagens com base nos filtros**:\n- `wasSentByApi`: Mensagens originadas pela API ⚠️ **IMPORTANTE:** Use sempre este filtro para evitar loops em automações\n- `wasNotSentByApi`: Mensagens não originadas pela API\n- `fromMeYes`: Mensagens enviadas pelo usuário\n- `fromMeNo`: Mensagens recebidas de terceiros\n- `isGroupYes`: Mensagens em grupos\n- `isGroupNo`: Mensagens em conversas individuais\n\n💡 **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.\n\n**Ações Suportadas**:\n- `add`: Registrar novo webhook\n- `delete`: Remover webhook existente\n\n**Parâmetros de URL**:\n- `addUrlEvents` (boolean): Quando ativo, adiciona o tipo do evento como path parameter na URL.\n  Exemplo: `https://api.example.com/webhook/{evento}`\n- `addUrlTypesMessages` (boolean): Quando ativo, adiciona o tipo da mensagem como path parameter na URL.\n  Exemplo: `https://api.example.com/webhook/{tipo_mensagem}`\n\n**Combinações de Parâmetros**:\n- Ambos ativos: `https://api.example.com/webhook/{evento}/{tipo_mensagem}`\n  Exemplo real: `https://api.example.com/webhook/message/conversation`\n- Apenas eventos: `https://api.example.com/webhook/message`\n- Apenas tipos: `https://api.example.com/webhook/conversation`\n\n**Notas Técnicas**:\n1. Os parâmetros são adicionados na ordem: evento → tipo mensagem\n2. A URL deve ser configurada para aceitar esses parâmetros dinâmicos\n3. Funciona com qualquer combinação de eventos/mensagens\n",
        "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",
                        "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.\n- `false` (padrão): URL normal\n- `true`: Adiciona evento na URL (ex: `/webhook/message`)\n",
                    "default": false
                  },
                  "addUrlTypesMessages": {
                    "type": "boolean",
                    "description": "Adiciona o tipo da mensagem como parâmetro na URL.\n- `false` (padrão): URL normal  \n- `true`: Adiciona tipo da mensagem (ex: `/webhook/conversation`)\n",
                    "default": false
                  },
                  "action": {
                    "type": "string",
                    "description": "Ação a ser executada:\n- add: criar novo webhook\n- update: atualizar webhook existente (requer id)\n- delete: remover webhook (requer apenas id)\nSe não informado, opera no modo simples (único webhook)\n",
                    "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": "#/components/schemas/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.\n\nCada item inclui data/hora (`created`), URL de destino, evento, tipo do webhook\n(`local`), payload tentado, número de tentativas, status HTTP final quando existir e a mensagem de erro.\n\nObservações:\n- O histórico fica apenas em memória e é perdido quando o processo reinicia.\n- O endpoint usa o mesmo `token` da instância.\n- Retorna apenas falhas dos webhooks locais da própria instância.\n- Falhas do webhook global ficam disponíveis separadamente em `/globalwebhook/errors` com `admintoken`.\n- O header `X-Webhook-Error-Capture-Started-At` informa desde quando a captura atual está valendo.\n\nExemplo de consulta:\n```bash\ncurl -X GET \"$BASE_URL/webhook/errors\" \\\n  -H \"token: SUA_INSTANCIA_TOKEN\"\n```\n",
        "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": [
          "Administração"
        ],
        "summary": "Ver Webhook Global",
        "security": [
          {
            "admintoken": []
          }
        ],
        "description": "Retorna a configuração atual do webhook global, incluindo:\n- URL configurada\n- Eventos ativos\n- Filtros aplicados\n- Configurações adicionais\n\nExemplo de resposta:\n```json\n{\n  \"enabled\": true,\n  \"url\": \"https://example.com/webhook\",\n  \"events\": [\"messages\", \"messages_update\"],\n  \"excludeMessages\": [\"wasSentByApi\", \"isGroupNo\"],\n  \"addUrlEvents\": true,\n  \"addUrlTypesMessages\": true\n}\n```\n",
        "responses": {
          "200": {
            "description": "Configuração atual do webhook global",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/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": [
          "Administração"
        ],
        "summary": "Configurar Webhook Global",
        "security": [
          {
            "admintoken": []
          }
        ],
        "description": "Configura um webhook global que receberá eventos de todas as instâncias.\n\n### 🚀 Configuração Simples (Recomendada)\n\n**Para a maioria dos casos de uso**:\n- Configure apenas URL e eventos desejados\n- Modo simples por padrão (sem complexidade)\n- **Recomendado**: Sempre use `\"excludeMessages\": [\"wasSentByApi\"]` para evitar loops\n- **Exemplo**: `{\"url\": \"https://webhook.cool/global\", \"events\": [\"messages\", \"connection\"], \"excludeMessages\": [\"wasSentByApi\"]}`\n\n### 🧪 Sites para Testes (ordenados por qualidade)\n\n**Para testar webhooks durante desenvolvimento**:\n1. **https://webhook.cool/** - ⭐ Melhor opção (sem rate limit, interface limpa)\n2. **https://rbaskets.in/** - ⭐ Boa alternativa (confiável, baixo rate limit)\n3. **https://webhook.site/** - ⚠️ Evitar se possível (rate limit agressivo)\n\n### Funcionalidades Principais:\n- Configuração de URL para recebimento de eventos\n- Seleção granular de tipos de eventos\n- Filtragem avançada de mensagens\n- Parâmetros adicionais na URL\n\n**Eventos Disponíveis**:\n- `connection`: Alterações no estado da conexão\n- `history`: Recebimento de histórico de mensagens\n- `messages`: Novas mensagens recebidas\n- `messages_update`: Atualizações em mensagens existentes\n- `call`: Eventos de chamadas VoIP\n- `contacts`: Atualizações na agenda de contatos\n- `presence`: Alterações no status de presença\n- `groups`: Modificações em grupos\n- `labels`: Gerenciamento de etiquetas\n- `chats`: Eventos de conversas\n- `chat_labels`: Alterações em etiquetas de conversas\n- `sender`: Atualizações de campanhas, quando inicia, e quando completa\n\n**Remover mensagens com base nos filtros**:\n- `wasSentByApi`: Mensagens originadas pela API ⚠️ **IMPORTANTE:** Use sempre este filtro para evitar loops em automações\n- `wasNotSentByApi`: Mensagens não originadas pela API\n- `fromMeYes`: Mensagens enviadas pelo usuário\n- `fromMeNo`: Mensagens recebidas de terceiros\n- `isGroupYes`: Mensagens em grupos\n- `isGroupNo`: Mensagens em conversas individuais\n\n💡 **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.\n\n**Parâmetros de URL**:\n- `addUrlEvents` (boolean): Quando ativo, adiciona o tipo do evento como path parameter na URL.\n  Exemplo: `https://api.example.com/webhook/{evento}`\n- `addUrlTypesMessages` (boolean): Quando ativo, adiciona o tipo da mensagem como path parameter na URL.\n  Exemplo: `https://api.example.com/webhook/{tipo_mensagem}`\n\n**Combinações de Parâmetros**:\n- Ambos ativos: `https://api.example.com/webhook/{evento}/{tipo_mensagem}`\n  Exemplo real: `https://api.example.com/webhook/message/conversation`\n- Apenas eventos: `https://api.example.com/webhook/message`\n- Apenas tipos: `https://api.example.com/webhook/conversation`\n\n**Notas Técnicas**:\n1. Os parâmetros são adicionados na ordem: evento → tipo mensagem\n2. A URL deve ser configurada para aceitar esses parâmetros dinâmicos\n3. Funciona com qualquer combinação de eventos/mensagens\n",
        "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",
                        "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.\n- `false` (padrão): URL normal\n- `true`: Adiciona evento na URL (ex: `/webhook/message`)\n",
                    "default": false
                  },
                  "addUrlTypesMessages": {
                    "type": "boolean",
                    "description": "Adiciona o tipo da mensagem como parâmetro na URL.\n- `false` (padrão): URL normal  \n- `true`: Adiciona tipo da mensagem (ex: `/webhook/conversation`)\n",
                    "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": "#/components/schemas/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": [
          "Administração"
        ],
        "summary": "Ver últimos erros do webhook global",
        "security": [
          {
            "admintoken": []
          }
        ],
        "description": "Retorna em memória os últimos 20 erros de entrega do webhook global.\n\nCada item inclui data/hora (`created`), URL de destino, evento, tipo do webhook\n(`global`), payload tentado, número de tentativas, status HTTP final quando existir e a mensagem de erro.\n\nObservações:\n- O histórico fica apenas em memória e é perdido quando o processo reinicia.\n- O endpoint exige `admintoken`.\n- Útil para diagnosticar falhas do webhook global sem expor esses dados aos tokens das instâncias.\n- O header `X-Webhook-Error-Capture-Started-At` informa desde quando a captura atual está valendo.\n\nExemplo de consulta:\n```bash\ncurl -X GET \"$BASE_URL/globalwebhook/errors\" \\\n  -H \"admintoken: SEU_ADMIN_TOKEN\"\n```\n",
        "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)\n\n### Funcionalidades principais:\n- conexão HTTP persistente em `text/event-stream`\n- seleção granular de tipos de eventos\n- filtragem de tipos de mensagens\n- autenticação por token na query, compatível com `EventSource`\n\n**Eventos Disponíveis**:\n- `connection`: Alterações no estado da conexão\n- `history`: Recebimento de histórico de mensagens\n- `messages`: Novas mensagens recebidas\n- `messages_update`: Atualizações em mensagens existentes\n- `call`: Eventos de chamadas VoIP\n- `contacts`: Atualizações na agenda de contatos\n- `presence`: Alterações no status de presença\n- `groups`: Modificações em grupos\n- `labels`: Gerenciamento de etiquetas\n- `chats`: Eventos de conversas\n- `chat_labels`: Alterações em etiquetas de conversas\n\n\nEstabelece uma conexão persistente para receber eventos em tempo real. Este\nendpoint:\n\n1. Requer autenticação via token\n\n2. Mantém uma conexão HTTP aberta com o cliente\n\n3. Envia eventos conforme ocorrem no servidor\n\n4. Suporta diferentes tipos de eventos\n\nExemplo de uso:\n\n```javascript\n\nconst eventSource = new\nEventSource('/sse?token=SEU_TOKEN&events=chats,messages');\n\n\neventSource.onmessage = function(event) {\n  const data = JSON.parse(event.data);\n  console.log('Novo evento:', data);\n};\n\n\neventSource.onerror = function(error) {\n  console.error('Erro na conexão SSE:', error);\n};\n\n```\n\n\nEstrutura de um evento:\n\n```json\n\n{\n  \"type\": \"message\",\n  \"data\": {\n    \"id\": \"3EB0538DA65A59F6D8A251\",\n    \"from\": \"5511999999999@s.whatsapp.net\",\n    \"to\": \"5511888888888@s.whatsapp.net\",\n    \"text\": \"Olá!\",\n    \"timestamp\": 1672531200000\n  }\n}\n\n```",
        "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:\n- Separados por vírgula: `?events=chats,messages`\n- Parâmetros repetidos: `?events=chats&events=messages`\n",
            "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:\n- Separados por vírgula: `?excludeMessages=poll,reaction`\n- Parâmetros repetidos: `?excludeMessages=poll&excludeMessages=reaction`\n",
            "example": "poll,reaction"
          }
        ],
        "responses": {
          "200": {
            "description": "Stream de eventos aberto",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "example": "no-cache"
              }
            },
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                },
                "example": "event: messages\ndata: {\"type\":\"message\",\"data\":{\"text\":\"Olá\"}}"
              }
            }
          },
          "400": {
            "description": "Lista de eventos ou parâmetros inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token inválido ou ausente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/sender/simple": {
      "post": {
        "operationId": "sendSimpleCampaign",
        "tags": [
          "Mensagem em massa"
        ],
        "summary": "Criar nova campanha (Simples)",
        "description": "Cria uma campanha para enviar a mesma mensagem a vários destinatários com intervalo controlado. Acompanhe a execução em `GET /sender/stats`.",
        "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\nmúltiplos destinatários e mensagens com delays personalizados.\n",
        "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:\n- text: Mensagem de texto\n- image: Imagem\n- document: Documento/arquivo\n- audio: Áudio\n- ptt: Mensagem de voz\n- myaudio: Áudio (opção alternativa)\n- sticker: Figurinha\n- video: Vídeo\n- videoplay: Vídeo com autoplay/loop no WhatsApp\n- contact: Contato\n- location: Localização\n- poll: Enquete\n- list: Lista de opções\n- button: Botões interativos\n- carousel: Carrossel de cartões com imagens e botões\n"
                        },
                        "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!\nConfira 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\nO 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\nO 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:\n\n## Ações Disponíveis:\n\n**🛑 stop** - Pausar campanha\n- Pausa uma campanha ativa ou agendada\n- Altera o status para \"paused\" \n- Use quando quiser interromper temporariamente o envio\n- Mensagens já enviadas não são afetadas\n\n**▶️ continue** - Continuar campanha  \n- Retoma uma campanha pausada\n- Altera o status para \"scheduled\"\n- Use para continuar o envio após pausar uma campanha\n- Não funciona em campanhas já concluídas (\"done\")\n\n**🗑️ delete** - Deletar campanha\n- Remove completamente a campanha\n- Deleta apenas mensagens NÃO ENVIADAS (status \"scheduled\")\n- Mensagens já enviadas são preservadas no histórico\n- Operação é executada de forma assíncrona\n\n## Status de Campanhas:\n- **scheduled**: Agendada para envio\n- **sending**: Enviando mensagens  \n- **paused**: Pausada pelo usuário\n- **done**: Concluída (não pode ser alterada)\n- **deleting**: Sendo deletada (operação em andamento)\n",
        "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:\n- **stop**: Pausa a campanha (muda para status \"paused\")\n- **continue**: Retoma campanha pausada (muda para status \"scheduled\") \n- **delete**: Remove campanha e mensagens não enviadas (assíncrono)\n",
                    "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.\nEsta é uma operação irreversível.\n",
        "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\npara as mais antigas.\n\nUse esta operação para montar o histórico de campanhas e escolher qual abrir\nem `POST /sender/listmessages`. Uma lista vazia indica que ainda não existem\ncampanhas disponíveis para a instância.\n",
        "parameters": [
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string",
              "enum": [
                "Active",
                "Archived"
              ]
            },
            "description": "Filtro reservado para compatibilidade. A resposta atual pode retornar\ntodas as campanhas independentemente desse valor.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de campanhas retornada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/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": "Lista as mensagens de uma campanha com filtro por status e paginação, permitindo acompanhar progresso e localizar falhas.",
        "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": "#/components/schemas/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"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/sender/stats": {
      "get": {
        "operationId": "getCampaignStats",
        "tags": [
          "Mensagem em massa"
        ],
        "summary": "Consultar estado e métricas das campanhas",
        "description": "Retorna uma fotografia do processador de campanhas da instância: estado\natual, campanha em execução, ritmo observado e próximo envio agendado.\n\nAs métricas representam a execução desde a última inicialização do serviço e\nnão substituem a consulta das campanhas e mensagens. `messages_processed`\nindica processamento pela fila, não entrega ou leitura pelo destinatário.\n",
        "security": [
          {
            "token": []
          }
        ],
        "responses": {
          "200": {
            "description": "Estado atual do processador de campanhas.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status",
                    "data"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "required": [
                        "status"
                      ],
                      "properties": {
                        "status": {
                          "type": "object",
                          "required": [
                            "current"
                          ],
                          "properties": {
                            "current": {
                              "type": "string",
                              "enum": [
                                "not_initialized",
                                "paused_for_direct_message",
                                "sending",
                                "paused",
                                "processing",
                                "idle"
                              ]
                            },
                            "direct_message_active": {
                              "type": "boolean"
                            },
                            "current_folder_id": {
                              "type": "string"
                            },
                            "delay_min": {
                              "type": "integer"
                            },
                            "delay_max": {
                              "type": "integer"
                            }
                          }
                        },
                        "statistics": {
                          "type": "object",
                          "properties": {
                            "messages_processed": {
                              "type": "integer"
                            },
                            "avg_processing_ms": {
                              "type": "integer"
                            },
                            "messages_per_minute": {
                              "type": "number"
                            }
                          }
                        },
                        "instance": {
                          "type": "object",
                          "properties": {
                            "groups_count": {
                              "type": "integer"
                            },
                            "is_business": {
                              "type": "boolean"
                            },
                            "platform": {
                              "type": "string"
                            },
                            "system_name": {
                              "type": "string"
                            },
                            "profile_name": {
                              "type": "string"
                            }
                          }
                        },
                        "scheduling": {
                          "type": "object",
                          "properties": {
                            "next_send_at": {
                              "type": "string",
                              "nullable": true,
                              "description": "Horário local formatado como YYYY-MM-DD HH:mm:ss."
                            },
                            "next_send_in_seconds": {
                              "type": "integer",
                              "nullable": true,
                              "description": "Presente quando o próximo envio ocorrer em menos de uma hora."
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "idle": {
                    "value": {
                      "status": "success",
                      "data": {
                        "status": {
                          "current": "idle",
                          "direct_message_active": false
                        },
                        "statistics": {
                          "messages_processed": 120,
                          "avg_processing_ms": 850,
                          "messages_per_minute": 12.5
                        },
                        "instance": {
                          "groups_count": 8,
                          "is_business": true,
                          "platform": "android",
                          "system_name": "Android",
                          "profile_name": "Atendimento"
                        },
                        "scheduling": {
                          "next_send_at": null,
                          "next_send_in_seconds": null
                        }
                      }
                    }
                  },
                  "not_initialized": {
                    "value": {
                      "status": "success",
                      "data": {
                        "status": {
                          "current": "not_initialized"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token da instância ausente ou inválido."
          },
          "500": {
            "description": "Processador de campanhas temporariamente indisponível."
          }
        }
      }
    },
    "/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 \npara a instância e a instância não pode enviar mensagens para eles.\n",
        "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.\nEsta lista é atualizada em tempo real conforme contatos são bloqueados/desbloqueados.\n",
        "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:\n\n1. **Definir todas as labels** (labelids): Define o conjunto completo de labels para o chat, substituindo labels existentes\n2. **Adicionar uma label** (add_labelid): Adiciona uma única label ao chat sem afetar as existentes\n3. **Remover uma label** (remove_labelid): Remove uma única label do chat sem afetar as outras\n\n**Importante**: Use apenas um dos três parâmetros por requisição. Labels inexistentes serão rejeitadas.\n\nAs labels devem ser fornecidas no formato id ou labelid encontradas na função get labels.\n",
        "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": "Remove uma conversa, suas mensagens locais ou ambas, conforme as opções enviadas.\nVocê pode escolher:\n- Deletar o chat do WhatsApp\n- Limpar a conversa no WhatsApp\n- Remover o chat do histórico da instância\n- Remover apenas as mensagens locais do chat\n- Qualquer combinação das opções acima\nObservação:\n- Se clearChatWhatsApp e deleteChatWhatsApp forem true, o clear tem prioridade.\n",
        "tags": [
          "Chats"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "number": {
                    "type": "string",
                    "description": "Número do chat no formato internacional.\nPara grupos use o ID completo do grupo.\n",
                    "example": "5511999999999"
                  },
                  "deleteChatDB": {
                    "type": "boolean",
                    "description": "Se true, remove o chat do histórico da instância",
                    "default": false,
                    "example": true
                  },
                  "deleteMessagesDB": {
                    "type": "boolean",
                    "description": "Se true, remove todas as mensagens locais do chat",
                    "default": false,
                    "example": true
                  },
                  "deleteChatWhatsApp": {
                    "type": "boolean",
                    "description": "Se true, deleta o chat do WhatsApp.\nPara grupos, esta operação não é permitida e o chat será apenas limpo.\n",
                    "default": false,
                    "example": true
                  },
                  "clearChatWhatsApp": {
                    "type": "boolean",
                    "description": "Se true, limpa a conversa do chat no WhatsApp (sem sair do chat).\nFunciona para grupos e conversas individuais.\n",
                    "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.\n- Quando arquivado, o chat é movido para a seção de arquivados no WhatsApp\n- A ação é sincronizada entre todos os dispositivos conectados\n- Não afeta as mensagens ou o conteúdo do chat\n",
        "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/ephemeral": {
      "post": {
        "operationId": "updateChatEphemeral",
        "summary": "Configurar mensagens temporárias em chat privado",
        "description": "Define o temporizador de mensagens temporárias (disappearing messages) de um chat privado.\n\nValores aceitos para a duração:\n- `0` ou `off` para desativar\n- `1d`\n- `7d`\n- `90d`\n\nObservações:\n- este endpoint é apenas para chats privados\n- se o identificador informado for de grupo, a API retorna erro orientando usar `/group/ephemeral`\n- a resposta inclui o chat com `wa_ephemeralExpiration` atualizado\n",
        "tags": [
          "Chats"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "number",
                  "duration"
                ],
                "properties": {
                  "number": {
                    "type": "string",
                    "description": "Identificador do chat privado",
                    "example": "5511999999999@s.whatsapp.net"
                  },
                  "duration": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "integer"
                      }
                    ],
                    "description": "Duração desejada para mensagens temporárias",
                    "example": "7d"
                  }
                }
              },
              "examples": {
                "ativar_7_dias": {
                  "summary": "Ativar por 7 dias",
                  "value": {
                    "number": "5511999999999@s.whatsapp.net",
                    "duration": "7d"
                  }
                },
                "desativar": {
                  "summary": "Desativar mensagens temporárias",
                  "value": {
                    "number": "5511999999999@s.whatsapp.net",
                    "duration": "off"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Temporizador atualizado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "response": {
                      "type": "string",
                      "example": "Ephemeral timer updated successfully"
                    },
                    "chat": {
                      "$ref": "#/components/schemas/Chat"
                    },
                    "ephemeral": {
                      "type": "object",
                      "properties": {
                        "enabled": {
                          "type": "boolean",
                          "example": true
                        },
                        "seconds": {
                          "type": "integer",
                          "format": "int64",
                          "example": 604800
                        },
                        "label": {
                          "type": "string",
                          "example": "7d"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "sucesso": {
                    "summary": "Timer atualizado",
                    "value": {
                      "response": "Ephemeral timer updated successfully",
                      "chat": {
                        "wa_chatid": "5511999999999@s.whatsapp.net",
                        "wa_ephemeralExpiration": 604800,
                        "wa_isGroup": false
                      },
                      "ephemeral": {
                        "enabled": true,
                        "seconds": 604800,
                        "label": "7d"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payload inválido, chat inválido ou duração não suportada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid duration. Allowed values: 0, off, 1d, 7d, 90d"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token inválido ou ausente"
          },
          "500": {
            "description": "Erro interno ao atualizar o temporizador",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Error updating chat ephemeral timer: connection closed"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/chat/read": {
      "post": {
        "operationId": "markChatRead",
        "summary": "Marcar chat como lido/não lido",
        "description": "Atualiza o status de leitura de um chat no WhatsApp.\n\nQuando um chat é marcado como lido:\n- O contador de mensagens não lidas é zerado\n- O indicador visual de mensagens não lidas é removido\n- O remetente recebe confirmação de leitura (se ativado)\n\nQuando marcado como não lido:\n- O chat aparece como pendente de leitura\n- Não afeta as confirmações de leitura já enviadas\n",
        "tags": [
          "Chats"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "number",
                  "read"
                ],
                "properties": {
                  "number": {
                    "type": "string",
                    "description": "Identificador do chat no formato:\n- Para usuários: [número]@s.whatsapp.net (ex: 5511999999999@s.whatsapp.net)\n- Para grupos: [id-grupo]@g.us (ex: 123456789-987654321@g.us)\n",
                    "example": "5511999999999@s.whatsapp.net"
                  },
                  "read": {
                    "type": "boolean",
                    "description": "- true: marca o chat como lido\n- false: marca o chat como não lido\n"
                  }
                }
              }
            }
          }
        },
        "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. \nAs opções de silenciamento são:\n* 0 - Remove o silenciamento\n* 8 - Silencia por 8 horas\n* 168 - Silencia por 1 semana (168 horas)\n* -1 - Silencia permanentemente\n",
        "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:\n* 0 = Remove silenciamento\n* 8 = Silencia por 8 horas\n* 168 = Silencia por 1 semana\n* -1 = Silencia permanentemente\n",
                    "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 \nno topo mesmo quando novas mensagens são recebidas em outros chats.\n",
        "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\") \nou ID do grupo (ex: \"123456789-123456@g.us\")\n",
                    "example": "5511999999999"
                  },
                  "pin": {
                    "type": "boolean",
                    "description": "Define se o chat deve ser fixado (true) ou desafixado (false)\n",
                    "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, \npaginação e ordenação customizada.\n\nOperadores de filtro:\n- `=` : igualdade exata\n- `~` : LIKE (contém)\n- `!~` : NOT LIKE (não contém)\n- `!=` : diferente\n- `>=` : maior ou igual\n- `>` : maior que\n- `<=` : menor ou igual\n- `<` : menor que\n- Sem operador: LIKE (contém)\n\nNa API 2.3.0, o formato completo preserva o contrato legado: padrão de 2000 registros e limit positivo explícito sem o novo teto de 500. Com compact=true, o padrão é 100 e o máximo é 200; nesse modo, limites maiores são reduzidos pelo servidor. Valores de limit omitidos, zero ou negativos usam o padrão do modo. Prefira o formato compacto e paginação explícita nas novas integrações.\n\nA projeção compacta usa os mesmos nomes JSON, omitindo campos de detalhes, notas, campos customizados e estado do chatbot. Filtros podem usar campos não incluídos na projeção. A resposta mantém chats, totalChatsStats e pagination. O atalho de busca por identificador pode retornar paginação { totalRecords: 1, limit: 1, offset: 0 }.\n",
        "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": "Formato completo: padrão 2000, preservando limit positivo explícito sem novo teto. Formato compacto: padrão 100, máximo 200. Omitido, zero ou negativo usa o padrão do modo."
                  },
                  "offset": {
                    "type": "integer",
                    "description": "Número de registros a pular (para paginação)",
                    "default": 0
                  },
                  "compact": {
                    "type": "boolean",
                    "default": false,
                    "description": "Retorna somente a projeção usada em listas/sidebar: identidade, nomes,\npreview, flags, unread, última mensagem, labels e campos essenciais do lead.\nNão retorna campos customizados, notas completas nem estado do chatbot.\n"
                  },
                  "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",
                    "description": "Use `=valor` para igualdade explícita."
                  },
                  "lead_tag": {
                    "type": "string",
                    "description": "Retorna chats que contenham exatamente esta tag em\n`lead_tags`, sem confundir nomes parcialmente iguais.\n"
                  }
                },
                "example": {
                  "operator": "AND",
                  "sort": "-wa_lastMsgTimestamp",
                  "limit": 50,
                  "offset": 0,
                  "wa_isGroup": true,
                  "lead_status": "~novo",
                  "lead_tag": "vip",
                  "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": "#/components/schemas/Chat"
                      },
                      "description": "Chats da página. No modo compacto, somente os campos da projeção de listagem são preenchidos."
                    },
                    "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 retornado, limitado ao intervalo de zero até totalRecords."
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/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.\n\nCasos de uso:\n- ler a anotação local já persistida no chat\n- consultar notas mesmo durante reconexão da sessão do WhatsApp\n\nRegras:\n- envie `number`\n- para recarregar do WhatsApp, use `/chat/notes/refresh`\n",
        "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": "#/components/schemas/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.\n\nUso recomendado:\n- tente primeiro com `force=false`\n- se isso não atualizar a nota corretamente, tente `force=true`\n- use `force=true` apenas como tentativa de correção, porque ele faz uma recarga mais pesada\n",
        "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`.\nUse `true` apenas quando a recarga padrão não funcionar bem,\npois esse modo faz uma nova leitura mais completa das notas.\n",
                    "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": "#/components/schemas/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.\n\nRegras:\n- envie `number`\n- envie `notes` como campo principal\n- envie string vazia para limpar a nota do chat\n",
        "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": "#/components/schemas/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/totalcount": {
      "get": {
        "operationId": "countChats",
        "tags": [
          "Chats"
        ],
        "summary": "Consultar contadores de chats",
        "description": "Retorna contadores totais e não lidos por estado, etiqueta e atendente.\nOs arrays são retornados vazios quando ainda não há etiquetas ou atendentes.\n",
        "security": [
          {
            "token": []
          }
        ],
        "responses": {
          "200": {
            "description": "Contadores atuais dos chats",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "total_chats",
                    "open_chats",
                    "archived_chats",
                    "group_chats",
                    "blocked_chats",
                    "label_counts",
                    "attendant_counts"
                  ],
                  "properties": {
                    "total_chats": {
                      "type": "object",
                      "required": [
                        "total",
                        "unread"
                      ],
                      "properties": {
                        "total": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "unread": {
                          "type": "integer",
                          "format": "int64"
                        }
                      }
                    },
                    "open_chats": {
                      "type": "object",
                      "required": [
                        "total",
                        "unread"
                      ],
                      "properties": {
                        "total": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "unread": {
                          "type": "integer",
                          "format": "int64"
                        }
                      }
                    },
                    "archived_chats": {
                      "type": "object",
                      "required": [
                        "total",
                        "unread"
                      ],
                      "properties": {
                        "total": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "unread": {
                          "type": "integer",
                          "format": "int64"
                        }
                      }
                    },
                    "group_chats": {
                      "type": "object",
                      "required": [
                        "total",
                        "unread"
                      ],
                      "properties": {
                        "total": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "unread": {
                          "type": "integer",
                          "format": "int64"
                        }
                      }
                    },
                    "blocked_chats": {
                      "type": "object",
                      "required": [
                        "total",
                        "unread"
                      ],
                      "properties": {
                        "total": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "unread": {
                          "type": "integer",
                          "format": "int64"
                        }
                      }
                    },
                    "label_counts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "labelid",
                          "name",
                          "total",
                          "unread"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "labelid": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "total": {
                            "type": "integer",
                            "format": "int64"
                          },
                          "unread": {
                            "type": "integer",
                            "format": "int64"
                          }
                        }
                      }
                    },
                    "attendant_counts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "total",
                          "unread"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "total": {
                            "type": "integer",
                            "format": "int64"
                          },
                          "unread": {
                            "type": "integer",
                            "format": "int64"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token inválido ou ausente"
          },
          "500": {
            "description": "Sessão indisponível"
          }
        }
      }
    },
    "/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, \natribuição de atendente, posição no kanban, tags e outros campos customizados.\n\nAs alterações ficam disponíveis imediatamente nas consultas e nos eventos webhook/SSE.\npara manter a aplicação sincronizada.\n",
        "tags": [
          "CRM"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Identificador do chat. Pode ser:\n- wa_chatid (ex: \"5511999999999@s.whatsapp.net\")\n- wa_fastid (ex: \"5511888888888:5511999999999\")\n",
                    "example": "5511999999999@s.whatsapp.net"
                  },
                  "chatbot_disableUntil": {
                    "type": "integer",
                    "format": "int64",
                    "description": "Timestamp UTC até quando o chatbot deve ficar desativado para este chat.\nUse 0 para reativar imediatamente.\n",
                    "example": 1735686000
                  },
                  "lead_isTicketOpen": {
                    "type": "boolean",
                    "description": "Status do ticket associado ao lead.\n- true: Ticket está aberto/em atendimento\n- false: Ticket está fechado/resolvido\n",
                    "example": true
                  },
                  "lead_assignedAttendant_id": {
                    "type": "string",
                    "description": "ID do atendente atribuído ao lead.\nUse string vazia (\"\") para remover a atribuição.\n",
                    "example": "att_123456"
                  },
                  "lead_kanbanOrder": {
                    "type": "integer",
                    "format": "int64",
                    "description": "Posição do card no quadro kanban.\nValores maiores aparecem primeiro.\n",
                    "example": 1000
                  },
                  "lead_tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Lista de tags associadas ao lead.\nTags inexistentes são criadas automaticamente.\nTags com `kanban=true` representam a coluna do cartão.\nEnvie array vazio ([]) para remover todas as tags.\n",
                    "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)\nApenas números ou formatado\n",
                    "example": "123.456.789-00"
                  },
                  "lead_status": {
                    "type": "string",
                    "description": "Status livre 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": "#/components/schemas/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"
          }
        }
      }
    },
    "/lead/tags": {
      "get": {
        "operationId": "listLeadTags",
        "tags": [
          "CRM"
        ],
        "summary": "Lista tags de lead",
        "description": "Retorna as tags pertencentes à instância autenticada. Registros com\n`kanban=true` representam as colunas ativas do Kanban.\n\nA resposta é ordenada com as colunas ativas primeiro, seguidas por\n`kanbanOrder` e nome. O endpoint usa somente dados locais e funciona mesmo\nquando a sessão do WhatsApp está desconectada.\n",
        "responses": {
          "200": {
            "description": "Tags retornadas com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LeadTag"
                  }
                },
                "example": [
                  {
                    "id": "r0123456789abcd",
                    "name": "Novo",
                    "kanban": true,
                    "kanbanOrder": 1000,
                    "owner": "5511999999999",
                    "created": "2026-09-03 12:00:00.000Z",
                    "updated": "2026-09-03 12:00:00.000Z"
                  }
                ]
              }
            }
          },
          "500": {
            "description": "Erro ao consultar as tags"
          }
        }
      }
    },
    "/lead/tags/edit": {
      "post": {
        "operationId": "editLeadTag",
        "tags": [
          "CRM"
        ],
        "summary": "Cria, edita ou apaga uma tag de lead",
        "description": "Cria uma tag quando `id` não é informado ou edita uma tag da instância\nautenticada quando `id` está presente.\n\nUse `kanban=true` para transformar a tag em uma coluna do quadro e\n`kanban=false` para retirá-la do Kanban sem apagar a tag. A alteração vale\nsomente para a instância autenticada.\n\nUse `delete=true` junto de `id` para apagar definitivamente a tag. Ao\napagar, a tag também é removida dos chats que a utilizam.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Omitir para criar; informar para editar"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Obrigatório na criação e opcional na edição"
                  },
                  "kanban": {
                    "type": "boolean",
                    "description": "Ativa ou desativa a tag como coluna do Kanban"
                  },
                  "kanbanOrder": {
                    "type": "integer",
                    "format": "int64",
                    "minimum": 0,
                    "description": "Ordem crescente da coluna"
                  },
                  "delete": {
                    "type": "boolean",
                    "description": "Apaga definitivamente a tag indicada por `id`"
                  }
                }
              },
              "examples": {
                "criar_coluna": {
                  "value": {
                    "name": "Em atendimento",
                    "kanban": true,
                    "kanbanOrder": 2000
                  }
                },
                "renomear_coluna": {
                  "value": {
                    "id": "r0123456789abcd",
                    "name": "Em conversa"
                  }
                },
                "apagar_tag": {
                  "value": {
                    "id": "r0123456789abcd",
                    "delete": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tag atualizada ou apagada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadTag"
                }
              }
            }
          },
          "201": {
            "description": "Tag criada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadTag"
                }
              }
            }
          },
          "400": {
            "description": "Payload inválido"
          },
          "404": {
            "description": "Tag não encontrada para a instância autenticada"
          },
          "409": {
            "description": "Já existe uma tag com o mesmo nome na instância"
          },
          "500": {
            "description": "Erro ao salvar a tag"
          },
          "503": {
            "description": "Recuperação de uma alteração anterior ainda em andamento"
          }
        }
      }
    },
    "/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`.\n\nO endpoint realiza:\n- Busca todos os contatos armazenados\n- Filtra para contatos da agenda, fora da agenda ou todos\n- Usa `address_book` como padrao quando `contactScope` nao for informado\n- Retorna dados formatados incluindo JID e informações de nome\n",
        "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"
                      },
                      "contact_name": {
                        "type": "string",
                        "description": "Nome completo do contato",
                        "example": "Contato Exemplo"
                      },
                      "contact_FirstName": {
                        "type": "string",
                        "description": "Primeiro nome do contato",
                        "example": "Contato"
                      }
                    },
                    "example": {
                      "jid": "5511999999999@s.whatsapp.net",
                      "contact_name": "Contato Exemplo",
                      "contact_FirstName": "Contato"
                    }
                  }
                }
              }
            }
          },
          "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.\nUse este endpoint (POST) para controlar `limit` e `offset` via corpo da requisicao.\nO campo `contactScope` permite escolher entre contatos da agenda, fora da agenda ou todos os contatos conhecidos.\nA rota GET `/contacts` continua disponivel para quem prefere a lista completa sem paginacao.\n",
        "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,
                    "minimum": 1,
                    "maximum": 1000
                  },
                  "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"
                  }
                }
              },
              "example": {
                "limit": 100,
                "offset": 0,
                "contactScope": "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.\n\nO endpoint realiza:\n- Adiciona o contato à agenda usando o WhatsApp\n- Usa o campo 'name' tanto para o nome completo quanto para o primeiro nome\n- Salva as informações do contato na agenda do WhatsApp\n- Retorna informações do contato adicionado\n",
        "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. \nPara Brasil, deve começar com 55. Aceita variações com/sem símbolo +, \ncom/sem parênteses, com/sem hífen e com/sem espaços. Também aceita formato \nJID do WhatsApp (@s.whatsapp.net). Não aceita contatos comerciais (@lid) \nnem grupos (@g.us).\n",
                    "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.\n\nO endpoint realiza:\n- Remove o contato da agenda usando o WhatsApp AppState\n- Atualiza a lista de contatos sincronizada\n- Retorna confirmação da remoção\n",
        "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. \nPara Brasil, deve começar com 55. Aceita variações com/sem símbolo +, \ncom/sem parênteses, com/sem hífen e com/sem espaços. Também aceita formato \nJID do WhatsApp (@s.whatsapp.net). Não aceita contatos comerciais (@lid) \nnem grupos (@g.us).\n",
                    "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": "Consultar detalhes de um chat",
        "description": "Retorna os dados disponíveis para apresentar ou editar uma conversa:\nidentificação, nomes conhecidos, telefone, foto, estado do chat, dados de\nlead e informações de grupo quando aplicáveis.\n\nUse depois de escolher um chat em `POST /chat/find`. Para obter somente a\nimagem, prefira `POST /chat/avatar`. O campo `preview` permite escolher uma\nimagem menor para interfaces de listagem ou a imagem completa.\n\nPara contatos individuais, `is_business` indica se há um nome comercial\nconhecido. `business_name` traz esse nome quando disponível.\n",
        "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:\n- `true`: Retorna imagem em tamanho preview (menor, otimizada para listagens)\n- `false` (padrão): Retorna imagem em tamanho full (resolução original, maior qualidade)\n",
                    "default": false
                  }
                },
                "required": [
                  "number"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Informações completas do chat retornadas com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Chat"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "is_business": {
                          "type": "boolean",
                          "description": "Há um nome comercial conhecido para este contato."
                        },
                        "business_name": {
                          "type": "string",
                          "description": "Nome comercial conhecido, ou string vazia."
                        },
                        "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",
                      "is_business": false,
                      "business_name": "",
                      "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.\n\n### Funcionalidades:\n- Verifica múltiplos números simultaneamente\n- Suporta números individuais e IDs de grupo\n- Retorna nome verificado quando disponível\n- Identifica grupos e comunidades\n- Verifica subgrupos de comunidades\n\n**Comportamento específico**:\n- Para números individuais:\n  - Verifica registro no WhatsApp\n  - Retorna nome verificado se disponível\n  - Normaliza formato do número\n- Para grupos:\n  - Verifica existência\n  - Retorna nome do grupo\n  - Retorna id do grupo de anúncios se buscado por id de comunidade\n",
        "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.\n\nRegras de uso:\n- Para editar uma etiqueta existente, envie o `labelid` real da etiqueta.\n- Para criar uma nova etiqueta, envie `labelid: \"new\"` com `delete: false`.\n  A API gera o próximo `labelid` numérico disponível para a instância.\n- Para deletar uma etiqueta existente, envie o `labelid` real com `delete: true`.\n\nObservações:\n- A resposta de sucesso retorna `\"Label created\"` para criação e `\"Label edited\"` para edição.\n- Para descobrir o `labelid` final criado, consulte `GET /labels` após a operação\n  ou consuma o webhook/evento de labels da instância.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "labelid": {
                    "type": "string",
                    "description": "ID da etiqueta.\n\nUse o ID real para editar/deletar uma etiqueta existente.\nUse `\"new\"` para criar uma nova etiqueta quando `delete` for `false`.\n",
                    "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\"`.\n",
                  "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": "Lista as etiquetas disponíveis para organizar conversas e filtros da\ninstância. Use os IDs retornados em `POST /chat/labels`.\n",
        "responses": {
          "200": {
            "description": "Lista de etiquetas retornada com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/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": "Iniciar recarga de etiquetas do WhatsApp",
        "description": "Inicia uma nova leitura das etiquetas no WhatsApp sem bloquear a requisição.\nA resposta confirma apenas que a recarga foi iniciada ou que já existe uma recarga em andamento.\nPara obter a lista atualizada, consulte `GET /labels` depois.\n\nA recarga também atualiza as associações entre etiquetas e chats. Quando\nhouver mudança, o webhook `chat_labels` pode informar os dados atualizados.\n\nUso recomendado:\n- tente primeiro com `force=false`\n- se isso não trouxer as etiquetas corretamente, tente `force=true`\n- use `force=true` apenas como tentativa de correção, porque ele faz uma recarga mais pesada\n",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "force": {
                    "type": "boolean",
                    "default": false,
                    "description": "Tente primeiro com `false`.\nUse `true` apenas quando a recarga padrão não funcionar bem,\npois esse modo faz uma nova leitura mais completa das etiquetas.\n",
                    "example": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Recarga de etiquetas aceita para processamento em background",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "status",
                    "message",
                    "force",
                    "fullSync"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "started",
                        "in_progress"
                      ],
                      "example": "started"
                    },
                    "message": {
                      "type": "string",
                      "example": "Label refresh started. Use GET /labels to fetch the refreshed list."
                    },
                    "force": {
                      "type": "boolean",
                      "example": false
                    },
                    "fullSync": {
                      "type": "boolean",
                      "example": false
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "A recarga não pôde ser executada porque a sincronização do histórico 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. Por padrão, cria respostas rápidas locais.\nPara criar/sincronizar uma resposta rápida no WhatsApp Business, envie `onWhatsApp: true`.\n\n- Para criar: não inclua o campo `id`\n- Para atualizar: inclua o `id` existente\n- Para excluir: defina `delete: true` e inclua o `id`\n\nObservação: respostas rápidas sincronizadas com o WhatsApp suportam apenas `type: text`.\nNão é possível converter uma resposta rápida local existente em resposta do WhatsApp; para criar no WhatsApp, envie `onWhatsApp: true` sem `id`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "examples": {
                "criar_apenas_api": {
                  "summary": "Criar apenas na API",
                  "value": {
                    "shortCut": "saudacao",
                    "type": "text",
                    "text": "Olá! Como posso ajudar?"
                  }
                },
                "criar_api_whatsapp": {
                  "summary": "Criar na API e no WhatsApp Business",
                  "value": {
                    "onWhatsApp": true,
                    "shortCut": "saudacao",
                    "type": "text",
                    "text": "Olá! Como posso ajudar?"
                  }
                },
                "editar_existente": {
                  "summary": "Editar resposta rápida existente",
                  "value": {
                    "id": "rb9da9c03637452",
                    "shortCut": "saudacao",
                    "type": "text",
                    "text": "Olá! Como posso ajudar hoje?"
                  }
                }
              },
              "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
                  },
                  "onWhatsApp": {
                    "type": "boolean",
                    "description": "Quando true, cria/sincroniza a resposta rápida no WhatsApp Business via app state. Disponível apenas para type=text.",
                    "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": "#/components/schemas/QuickReply"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Requisição inválida (erro de validação)"
          },
          "404": {
            "description": "Template não encontrado"
          },
          "500": {
            "description": "Erro no servidor ou falha ao sincronizar com WhatsApp"
          }
        }
      }
    },
    "/quickreply/showall": {
      "get": {
        "operationId": "listQuickReplies",
        "tags": [
          "Respostas Rápidas"
        ],
        "summary": "Listar todas as respostas rápidas",
        "description": "Lista os textos prontos cadastrados para agilizar o trabalho de atendentes em interfaces de suporte e vendas.",
        "responses": {
          "200": {
            "description": "Lista de respostas rápidas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/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:\n1. Iniciar chamadas de voz para contatos\n2. Funciona apenas com números válidos do WhatsApp\n3. O contato receberá uma chamada de voz\n\nSem `fileUrl`, o endpoint apenas faz o telefone do contato tocar e não\nestabelece uma comunicação de voz bidirecional.\n\nCom `fileUrl`, a API reproduz o arquivo quando a chamada é atendida e\nencerra a ligação ao final do áudio. São aceitos MP3, WAV e OGG/Opus por\nURL HTTP(S), data URI ou base64, com limite de 25 MB.\n\n**Opcional**: Use `call_duration` para definir por quantos segundos a chamada deve tocar.\nApós esse período a chamada é encerrada automaticamente, sem precisar chamar `/call/reject`.\nUse `0` para não limitar a reprodução do áudio por tempo.\n\nExemplo de requisição:\n```json\n{\n  \"number\": \"5511999999999\",\n  \"call_duration\": 0,\n  \"fileUrl\": \"https://exemplo.com/audio.mp3\"\n}\n```\n\nExemplo de resposta:\n```json\n{\n  \"response\": \"Call request accepted locally, awaiting WhatsApp confirmation\",\n  \"confirmed\": false,\n  \"audio\": {\n    \"requested\": true,\n    \"playback\": \"starts_when_call_is_ready\"\n  }\n}\n```\n\nErros comuns:\n- 401: Token inválido ou expirado\n- 400: Número inválido ou ausente\n- 500: Erro ao iniciar chamada\n",
        "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",
                    "minimum": 0,
                    "description": "Duração máxima da chamada em segundos. Use 0 ou omita para não limitar o áudio por tempo.",
                    "example": 15
                  },
                  "fileUrl": {
                    "type": "string",
                    "description": "Áudio MP3, WAV ou OGG/Opus por URL HTTP(S), data URI ou base64, com até 25 MB. A reprodução começa quando a chamada é atendida.",
                    "example": "https://exemplo.com/audio.mp3"
                  }
                },
                "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 request accepted locally, awaiting WhatsApp confirmation"
                    },
                    "confirmed": {
                      "type": "boolean",
                      "description": "Indica se a chamada já foi confirmada pelo WhatsApp na resposta inicial",
                      "example": false
                    },
                    "call": {
                      "type": "object",
                      "description": "Metadados da chamada criada",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "from": {
                          "type": "string"
                        },
                        "callCreator": {
                          "type": "string"
                        },
                        "callCreatorAlt": {
                          "type": "string"
                        },
                        "groupJid": {
                          "type": "string"
                        },
                        "fromMe": {
                          "type": "boolean"
                        },
                        "wasSentByAPI": {
                          "type": "boolean"
                        },
                        "source": {
                          "type": "string"
                        },
                        "primaryJid": {
                          "type": "string"
                        },
                        "alternateJid": {
                          "type": "string"
                        },
                        "timestamp": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "timestampISO": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "updatedAtISO": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "participants": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "audio": {
                      "type": "object",
                      "description": "Presente quando `fileUrl` foi informado",
                      "properties": {
                        "requested": {
                          "type": "boolean",
                          "example": true
                        },
                        "mode": {
                          "type": "string",
                          "example": "call"
                        },
                        "queued": {
                          "type": "boolean",
                          "example": true
                        },
                        "fileUrl": {
                          "type": "string",
                          "description": "Referência segura da origem do áudio"
                        },
                        "input": {
                          "type": "string",
                          "description": "Tipo da entrada recebida"
                        },
                        "source": {
                          "type": "string",
                          "description": "Decodificador usado para o áudio"
                        },
                        "playback": {
                          "type": "string",
                          "example": "starts_when_call_is_ready"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "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"
                    }
                  },
                  "invalid_audio": {
                    "summary": "Audio invalido ou não suportado",
                    "value": {
                      "error": "error making call with audio: unsupported call audio format: supported formats are mp3, wav and ogg/opus"
                    }
                  }
                }
              }
            }
          },
          "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.\n\nO body pode ser enviado vazio `{}`. Os campos `number` e `id` são opcionais e podem ser usados para especificar uma chamada específica.\n\nExemplo de requisição (recomendado):\n```json\n{}\n```\n\nExemplo de requisição com campos opcionais:\n```json\n{\n  \"number\": \"5511999999999\",\n  \"id\": \"ABEiGmo8oqkAcAKrBYQAAAAA_1\"\n}\n```\n\nExemplo de resposta:\n```json\n{\n  \"response\": \"Call rejected\"\n}\n```\n\nErros comuns:\n- 401: Token inválido ou expirado\n- 400: Número inválido\n- 500: Erro ao rejeitar chamada\n",
        "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.\n\n### Funcionalidades:\n- Retorna todas as configurações do Chatwoot incluindo credenciais\n- Mostra status de habilitação da integração\n- Útil para verificar configurações atuais antes de fazer alterações\n",
        "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.\n\n### Funcionalidades:\n- Configura todos os parâmetros da integração Chatwoot\n- Reinicializa automaticamente o cliente Chatwoot quando habilitado\n- Retorna URL do webhook para configurar no Chatwoot\n- Sincronização bidirecional de mensagens novas entre WhatsApp e Chatwoot\n- Sincronização automática de contatos (nome e telefone)\n- Atualização automática LID → PN (Local ID para Phone Number)\n- Sistema de nomes inteligentes com til (~)\n\n### Configuração no Chatwoot:\n1. Após configurar via API, use a URL retornada no webhook settings da inbox no Chatwoot\n2. Configure como webhook URL na sua inbox do Chatwoot\n3. A integração ficará ativa e sincronizará mensagens e contatos automaticamente\n\n### 🏷️ Sistema de Nomes Inteligentes:\n- **Nomes com til (~)**: São atualizados automaticamente quando o contato modifica seu nome no WhatsApp\n- **Nomes específicos**: Para definir um nome fixo, remova o til (~) do nome no Chatwoot\n- **Exemplo**: \"~João Silva\" será atualizado automaticamente, \"João Silva\" (sem til) permanecerá fixo\n- **Atualização LID→PN**: Contatos migram automaticamente de Local ID para Phone Number quando disponível\n- **Sem duplicação**: Durante a migração LID→PN, não haverá duplicação de conversas\n- **Respostas nativas**: Todas as respostas dos agentes aparecem nativamente no Chatwoot\n\n### 🚧 AVISO IMPORTANTE - INTEGRAÇÃO BETA:\n- **Fase Beta**: Esta integração está em fase de desenvolvimento e testes\n- **Uso por conta e risco**: O usuário assume total responsabilidade pelo uso\n- **Recomendação**: Teste em ambiente não-produtivo antes de usar em produção\n- **Suporte limitado**: Funcionalidades podem mudar sem aviso prévio\n\n### ⚠️ Limitações Conhecidas:\n- **Sincronização de histórico**: Não implementada - apenas mensagens novas são sincronizadas\n",
        "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": {
        "operationId": "postBusinessGetProfile",
        "tags": [
          "Business"
        ],
        "summary": "Obter o perfil comercial",
        "description": "Retorna os dados públicos do perfil comercial da conta conectada. Use para\nrevisar descrição, endereço, categoria e meios de contato antes de atualizar.\n",
        "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": {
        "operationId": "getBusinessGetCategories",
        "tags": [
          "Business"
        ],
        "summary": "Obter as categorias de negócios",
        "description": "Lista as categorias aceitas pelo perfil comercial. Use os identificadores\nretornados ao atualizar a categoria da empresa.\n",
        "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": {
        "operationId": "postBusinessUpdateProfile",
        "tags": [
          "Business"
        ],
        "summary": "Atualizar o perfil comercial",
        "description": "Atualiza os dados do perfil comercial da conta do WhatsApp Business atualmente conectada.\nTodos os campos são opcionais; apenas os enviados serão atualizados.\n",
        "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.\n\nObservações:\n- envie apenas `jid` para buscar a primeira página\n- a paginação pública usa o campo `after`\n- copie exatamente o valor retornado em `response.next` e envie na próxima chamada\n- o valor de `after` é um token opaco: não tente decodificar ou modificar\n- a integração atual retorna até 50 produtos por chamada\n- a resposta usa exclusivamente o formato atual documentado abaixo\n",
        "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.next`.",
                    "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",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "$ref": "#/components/schemas/BusinessCatalogPage"
                    }
                  }
                },
                "examples": {
                  "sucesso": {
                    "value": {
                      "response": {
                        "next": "Q1VSU09SX1BST1hJTUFfUEFHSU5B",
                        "products": [
                          {
                            "id": "1234567890",
                            "name": "Produto Exemplo",
                            "description": "Descrição do produto",
                            "price": "1990",
                            "currency": "BRL",
                            "retailer_id": "sku-123",
                            "is_hidden": false,
                            "is_sanctioned": false,
                            "product_availability": "in stock",
                            "media": {
                              "images": [
                                {
                                  "id": "img-1",
                                  "request_image_url": "https://mmg.whatsapp.net/v/t62.7118-24/...",
                                  "original_image_url": "https://lookaside.whatsapp.net/..."
                                }
                              ]
                            },
                            "status_info": {
                              "status": "APPROVED",
                              "can_appeal": false
                            }
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "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": {
        "operationId": "postBusinessCatalogInfo",
        "tags": [
          "Business"
        ],
        "summary": "Obter informações de um produto do catálogo",
        "description": "Retorna os detalhes disponíveis de um produto do catálogo. Use o ID obtido\nna listagem de produtos para abrir ou revisar um item.\n",
        "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",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "$ref": "#/components/schemas/BusinessProduct"
                    }
                  }
                }
              }
            }
          },
          "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": {
        "operationId": "postBusinessCatalogDelete",
        "tags": [
          "Business"
        ],
        "summary": "Deletar um produto do catálogo",
        "description": "Exclui um produto do catálogo comercial. Para retirá-lo da vitrine sem\napagar, prefira a operação de ocultar.\n",
        "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": {
        "operationId": "postBusinessCatalogShow",
        "tags": [
          "Business"
        ],
        "summary": "Mostrar um produto do catálogo",
        "description": "Torna um produto existente visível no catálogo comercial depois de revisar\nsuas informações e disponibilidade.\n",
        "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": {
        "operationId": "postBusinessCatalogHide",
        "tags": [
          "Business"
        ],
        "summary": "Ocultar um produto do catálogo",
        "description": "Retira temporariamente um produto da vitrine sem apagá-lo. O item pode ser\nexibido novamente pela operação correspondente.\n",
        "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": {
        "operationId": "postAdminRestart",
        "tags": [
          "Administraçã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.\n\nUse apenas em situações realmente necessárias, como instabilidades gerais.\nApós o restart, os números entram em reconexão automática e não ficam desconectados permanentemente.\n",
        "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"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/admin/token/rotate": {
      "post": {
        "operationId": "rotateAdminToken",
        "tags": [
          "Administração"
        ],
        "summary": "Rotacionar admin token",
        "security": [
          {
            "admintoken": []
          }
        ],
        "description": "Gera um novo `admintoken`. Use o token atual no header e guarde o token retornado.\n\nSó é permitida uma rotação a cada 24 horas.\n",
        "responses": {
          "200": {
            "description": "Admin token rotacionado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "message",
                    "admin_token",
                    "license_sync_triggered",
                    "license_synced",
                    "timestamp"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "Admin token rotated successfully"
                    },
                    "admin_token": {
                      "type": "string",
                      "minLength": 50,
                      "maxLength": 50,
                      "pattern": "^[A-Za-z0-9]{50}$",
                      "description": "Novo admin token.",
                      "example": "AbC123Def456GhI789JkL012MnO345PqR678StU901VwX234Yz"
                    },
                    "license_sync_triggered": {
                      "type": "boolean",
                      "example": true
                    },
                    "license_synced": {
                      "type": "boolean",
                      "example": true
                    },
                    "timestamp": {
                      "type": "integer",
                      "format": "int64",
                      "description": "Timestamp Unix em milissegundos.",
                      "example": 1776892800000
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "admintoken inválido ou ausente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Unauthorized"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Rotação bloqueada para container gratuito/demo",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Admin token rotation is disabled for free containers"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rotação bloqueada por cooldown de 24 horas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "last_rotated_at",
                    "next_rotation_at",
                    "retry_after_ms"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Admin token rotation cooldown active"
                    },
                    "last_rotated_at": {
                      "type": "integer",
                      "format": "int64",
                      "description": "Timestamp Unix em milissegundos da última rotação concluída.",
                      "example": 1776892800000
                    },
                    "next_rotation_at": {
                      "type": "integer",
                      "format": "int64",
                      "description": "Timestamp Unix em milissegundos de quando uma nova rotação será permitida.",
                      "example": 1776979200000
                    },
                    "retry_after_ms": {
                      "type": "integer",
                      "format": "int64",
                      "description": "Tempo restante em milissegundos para liberar nova rotação.",
                      "example": 86400000
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro interno ao rotacionar o token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Failed to persist admin token"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Falha ao confirmar a rotação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "error",
                    "license_synced",
                    "timestamp"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "string",
                      "example": "Failed to sync rotated admin token with license server"
                    },
                    "license_synced": {
                      "type": "boolean",
                      "example": false
                    },
                    "timestamp": {
                      "type": "integer",
                      "format": "int64",
                      "example": 1776892800000
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/chat/avatar": {
      "post": {
        "operationId": "getChatAvatar",
        "tags": [
          "Chats"
        ],
        "summary": "Consultar avatar de um chat",
        "description": "Retorna a URL temporária da imagem de uma conversa individual ou grupo.\nUse `preview=true` para solicitar a imagem reduzida ou `preview=false` para\nsolicitar a imagem completa.\n\nQuando não houver imagem disponível, a resposta continua válida e retorna\n`url` vazio. `force=true` solicita uma atualização antecipada, respeitando\num intervalo mínimo de 20 segundos por imagem e instância; não use essa\nopção em polling contínuo.\n",
        "security": [
          {
            "token": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "number"
                ],
                "properties": {
                  "number": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Identificador do chat. Aceita número com DDI, JID de usuário, LID conhecido pela instância ou JID de grupo.",
                    "example": "5511999999999"
                  },
                  "preview": {
                    "type": "boolean",
                    "default": false,
                    "description": "true solicita preview; false solicita a imagem completa."
                  },
                  "force": {
                    "type": "boolean",
                    "default": false,
                    "description": "Solicita uma atualização antecipada, respeitando o intervalo mínimo de 20 segundos por imagem e instância. Não use em polling contínuo."
                  }
                }
              },
              "example": {
                "number": "5511999999999",
                "preview": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "URL da foto ou string vazia quando não houver imagem disponível.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "url"
                  ],
                  "properties": {
                    "url": {
                      "type": "string",
                      "description": "URL temporária; string vazia é válida."
                    }
                  }
                },
                "examples": {
                  "found": {
                    "value": {
                      "url": "https://pps.whatsapp.net/example.jpg"
                    }
                  },
                  "absent": {
                    "value": {
                      "url": ""
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payload inválido, number ausente ou identificador inválido.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token ausente ou inválido.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Falha ao consultar a imagem ou ausência de sessão disponível.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/business/catalog/save": {
      "post": {
        "operationId": "postBusinessCatalogSave",
        "tags": [
          "Business"
        ],
        "summary": "Criar ou editar um produto do catálogo",
        "description": "Cria um produto quando `id` não é informado ou atualiza o produto indicado.\nOs preços são strings de inteiros em milésimos da moeda (por exemplo,\n`19990` = R$ 19,99). Envie `image_data` em base64 ou Data URL, ou uma\n`image_url` pública HTTPS para uma imagem nova. Para manter imagens já\ncadastradas, envie suas URLs em `image_urls`. Uma dessas três fontes\nde imagem é obrigatória.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Omitir para criar; informar para editar"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 256
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 4096
                  },
                  "currency": {
                    "type": "string",
                    "pattern": "^[A-Z]{3}$",
                    "example": "BRL"
                  },
                  "price": {
                    "type": "string",
                    "pattern": "^\\d{1,18}$",
                    "description": "Preço em milésimos da moeda",
                    "example": "19990"
                  },
                  "sale_price": {
                    "type": "string",
                    "pattern": "^\\d{1,18}$",
                    "description": "Preço promocional em milésimos da moeda"
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "retailer_id": {
                    "type": "string",
                    "maxLength": 256
                  },
                  "is_hidden": {
                    "type": "boolean",
                    "default": false
                  },
                  "image_urls": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 10,
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "description": "URLs HTTPS de mídia retornadas pelo WhatsApp/Meta; não aceita hosts arbitrários."
                  },
                  "video_urls": {
                    "type": "array",
                    "maxItems": 10,
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "description": "URLs de vídeos já associados ao produto"
                  },
                  "image_data": {
                    "type": "string",
                    "description": "Imagem JPEG ou PNG em base64 ou Data URL, com até 16 MB."
                  },
                  "image_url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048,
                    "description": "URL pública HTTPS de uma imagem JPEG ou PNG, com até 16 MB"
                  },
                  "compliance_category": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "compliance_info": {
                    "$ref": "#/components/schemas/BusinessComplianceInfo"
                  },
                  "width": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 1024
                  },
                  "height": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 1024
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Produto atualizado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "$ref": "#/components/schemas/BusinessProduct"
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Produto criado com sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "$ref": "#/components/schemas/BusinessProduct"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Produto inválido"
          },
          "401": {
            "description": "Token inválido"
          },
          "500": {
            "description": "Erro ao carregar a imagem ou salvar o produto"
          }
        }
      }
    },
    "/send/event": {
      "post": {
        "operationId": "sendEvent",
        "tags": [
          "Enviar Mensagem"
        ],
        "summary": "Enviar evento",
        "description": "Envia um convite de evento para um contato ou grupo. Informe `startTime`\nem segundos ou milissegundos Unix; `endTime` é opcional. Uma resposta do\nconvidado chega como mensagem do tipo `EventResponseMessage`, com a\nescolha em `vote`.\n\nAceita os campos comuns de envio: `replyid`, `mentions`, `delay`,\n`readchat`, `readmessages`, `async`, `track_source` e `track_id`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "number",
                  "name",
                  "startTime"
                ],
                "properties": {
                  "number": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "startTime": {
                    "type": "integer",
                    "format": "int64",
                    "description": "Início em segundos ou milissegundos Unix."
                  },
                  "endTime": {
                    "type": "integer",
                    "format": "int64",
                    "description": "Fim em segundos ou milissegundos Unix; não pode preceder o início."
                  },
                  "location": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "address": {
                        "type": "string"
                      },
                      "latitude": {
                        "type": "number",
                        "minimum": -90,
                        "maximum": 90
                      },
                      "longitude": {
                        "type": "number",
                        "minimum": -180,
                        "maximum": 180
                      }
                    }
                  },
                  "joinLink": {
                    "type": "string",
                    "format": "uri",
                    "description": "Link HTTPS obrigatório se `isScheduleCall=true`."
                  },
                  "extraGuestsAllowed": {
                    "type": "boolean"
                  },
                  "isScheduleCall": {
                    "type": "boolean"
                  },
                  "isCanceled": {
                    "type": "boolean"
                  },
                  "hasReminder": {
                    "type": "boolean"
                  },
                  "reminderOffsetSec": {
                    "type": "integer",
                    "format": "int64",
                    "minimum": 0
                  },
                  "replyid": {
                    "type": "string"
                  },
                  "mentions": {
                    "type": "string"
                  },
                  "delay": {
                    "type": "integer"
                  },
                  "readchat": {
                    "type": "boolean"
                  },
                  "readmessages": {
                    "type": "boolean"
                  },
                  "async": {
                    "type": "boolean"
                  },
                  "track_source": {
                    "type": "string"
                  },
                  "track_id": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "number": "5511999999999",
                "name": "Reunião de apresentação",
                "startTime": 1790186400,
                "endTime": 1790190000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Convite enviado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Message"
                }
              }
            }
          },
          "400": {
            "description": "Evento inválido"
          },
          "401": {
            "description": "Token inválido"
          },
          "500": {
            "description": "Falha no envio"
          }
        }
      }
    },
    "/business/catalog/collection/list": {
      "get": {
        "operationId": "listBusinessCatalogCollections",
        "tags": [
          "Business"
        ],
        "summary": "Listar coleções do catálogo",
        "description": "Lista as coleções do catálogo da instância autenticada. Para a primeira\npágina, não informe `after`. Se a resposta trouxer `response.next`,\ncopie o valor para `after` na próxima chamada. O cursor é opaco.\n",
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Cursor `response.next` da página anterior."
          }
        ],
        "responses": {
          "200": {
            "description": "Página de coleções",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "$ref": "#/components/schemas/BusinessCollectionPage"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token inválido"
          },
          "500": {
            "description": "Não foi possível consultar as coleções"
          }
        }
      }
    },
    "/business/catalog/collection/create": {
      "post": {
        "operationId": "createBusinessCatalogCollection",
        "tags": [
          "Business"
        ],
        "summary": "Criar coleção no catálogo",
        "description": "Cria uma coleção no catálogo da instância autenticada com produtos\nexistentes. Use os IDs retornados pela listagem de produtos.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "product_ids"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "product_ids": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "example": {
                "name": "Novidades",
                "product_ids": [
                  "1234567890"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Coleção criada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "$ref": "#/components/schemas/BusinessCollectionMutationResult"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Nome ou lista de produtos inválidos"
          },
          "401": {
            "description": "Token inválido"
          },
          "500": {
            "description": "Não foi possível criar a coleção"
          }
        }
      }
    },
    "/business/catalog/collection/{id}": {
      "patch": {
        "operationId": "updateBusinessCatalogCollection",
        "tags": [
          "Business"
        ],
        "summary": "Editar coleção do catálogo",
        "description": "Altera apenas os campos enviados da coleção indicada pelo `id` da URL.\nEnvie pelo menos uma alteração. `add_product_ids` adiciona produtos e\n`remove_product_ids` remove produtos da coleção sem apagá-los do catálogo.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID da coleção."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "add_product_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "remove_product_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "example": {
                "name": "Em destaque",
                "add_product_ids": [
                  "1234567890"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Coleção atualizada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "$ref": "#/components/schemas/BusinessCollectionMutationResult"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "ID ou alteração inválidos"
          },
          "401": {
            "description": "Token inválido"
          },
          "500": {
            "description": "Não foi possível editar a coleção"
          }
        }
      },
      "delete": {
        "operationId": "deleteBusinessCatalogCollection",
        "tags": [
          "Business"
        ],
        "summary": "Apagar coleção do catálogo",
        "description": "Apaga uma coleção da instância autenticada. Os produtos não são apagados\ndo catálogo.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID da coleção."
          }
        ],
        "responses": {
          "200": {
            "description": "Coleção apagada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "response"
                  ],
                  "properties": {
                    "response": {
                      "type": "string",
                      "example": "Deleted collection"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "ID inválido"
          },
          "401": {
            "description": "Token inválido"
          },
          "500": {
            "description": "Não foi possível apagar a coleção"
          }
        }
      }
    }
  },
  "webhooks": {
    "connection": {
      "post": {
        "summary": "Conexão da instância",
        "description": "Acompanhe mudanças do ciclo de conexão da instância. Use `instance.status` para atualizar a interface e decidir quando consultar `/instance/status`.\n\n## Quando é enviado\n\nConexão estabelecida e transições de desconexão notificadas pelo ciclo da sessão. Uma queda transitória de socket pode ser suprimida durante recuperação; não conte com um webhook para cada tentativa interna de reconexão.\n\n## Como interpretar\n\n- `event_id` identifica a notificação produzida pelo fluxo de conexão.\n- `instance.status` descreve o estado informado; `lastDisconnectReason` ajuda no diagnóstico.\n- `type`, quando presente, pode indicar a origem da transição, como `Disconnected` ou `TemporaryBan`.\n- Campos como `temporaryBan` só aparecem quando aplicáveis. Consulte o estado atual se eventos chegarem atrasados.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "connection",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "event_id": {
                        "type": "string",
                        "description": "Identificador da notificação de conexão; não é um campo universal dos outros eventos."
                      },
                      "instance": {
                        "type": "object",
                        "description": "Estado da instância.",
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "Nome da instância."
                          },
                          "status": {
                            "type": "string",
                            "description": "Estado da conexão informado pelo evento."
                          },
                          "lastDisconnectReason": {
                            "type": "string",
                            "description": "Motivo disponível da desconexão; pode ser unknown."
                          },
                          "lastDisconnect": {
                            "type": "string",
                            "description": "Data textual da última desconexão."
                          }
                        },
                        "additionalProperties": true
                      },
                      "type": {
                        "type": "string",
                        "description": "Origem/tipo da transição, quando disponível."
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "connected": {
                  "summary": "Conexão estabelecida",
                  "value": {
                    "EventType": "connection",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "event_id": "f51310de-8e2b-4ef5-8065-dcd67e764c65",
                    "instance": {
                      "name": "Atendimento",
                      "status": "connected"
                    }
                  }
                },
                "disconnected": {
                  "summary": "Desconexão notificada",
                  "value": {
                    "EventType": "connection",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "event_id": "4d42a099-7921-43ec-9774-da72901bbf13",
                    "type": "Disconnected",
                    "instance": {
                      "name": "Atendimento",
                      "status": "disconnected",
                      "lastDisconnectReason": "unknown",
                      "lastDisconnect": "2026-09-08 12:00:00.000Z"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    },
    "history": {
      "post": {
        "summary": "Sincronização de histórico",
        "description": "Receba lotes de dados processados durante sincronizações e recuperações de histórico.\n\n## Variações do payload\n\n`EventType` permanece `history`. O campo `event` identifica o conteúdo do lote: por exemplo `messages`, `chats`, `calls`, `labels` ou `chat_labels`. Leia o array correspondente; não suponha que todos os arrays existam no mesmo evento.\n\nSincronizações de etiquetas podem acrescentar `history_type`, `sync_id`, `full_sync`, `summary` e `chunk`. Esses metadados não são universais para todo histórico.\n\n## Como processar\n\nFaça upsert pelos IDs, aceite vários lotes e tolere sobreposição com eventos ao vivo. O recebimento de um lote não comprova que todo o histórico do WhatsApp foi sincronizado. Quando `chunk.has_more` existir, ele descreve aquela sequência de chunks.\n\n## Sequências e conclusão\n\nCada origem de lotes recebe um `batchChunkOrder`: o histórico inicial, cada parte que o WhatsApp envia depois dele e cada resposta de `POST /message/history-sync`. Chats, mensagens e ligações da mesma origem compartilham o número. Identifique uma sequência por `batchChunkOrder` + `event` e acompanhe seus lotes com `batchNumber` e `batchTotal`. Lotes de sequências diferentes podem chegar intercalados.\n\nLotes com dados chegam com `batchHistoryStatus: \"loading\"`. O fim é informado por um lote sem dados, com `event: \"status\"` e `batchHistoryStatus: \"complete\"`; seu `batchChunkOrder` é o da última sequência enviada. Ele sai quando o WhatsApp indica o fim da sincronização completa ou após cerca de 2 minutos sem novas partes do histórico. Se partes atrasadas chegarem depois, um novo `complete` é enviado: considere o de maior `batchChunkOrder`. A numeração recomeça em 1 a cada pareamento.\n\nUm novo pareamento pode reenviar mensagens já recebidas. Deduplique por `messageid` e faça upsert pelos IDs: lotes também podem se sobrepor a eventos recebidos ao vivo.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "history",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "event": {
                        "type": "string",
                        "description": "Conteúdo do lote: messages, chats, calls, labels, chat_labels ou status (conclusão do histórico)."
                      },
                      "messages": {
                        "type": [
                          "array",
                          "null"
                        ],
                        "description": "Lote de mensagens.",
                        "items": {
                          "type": "object",
                          "description": "Mensagem normalizada. Campos disponíveis variam conforme o tipo e a origem.",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "Identificador retornado pelo sistema; preserve como string."
                            },
                            "messageid": {
                              "type": "string",
                              "description": "ID da mensagem no WhatsApp."
                            },
                            "chatid": {
                              "type": "string",
                              "description": "JID do contato, grupo ou canal."
                            },
                            "sender": {
                              "type": "string",
                              "description": "JID do remetente."
                            },
                            "senderName": {
                              "type": "string",
                              "description": "Nome disponível do remetente."
                            },
                            "fromMe": {
                              "type": "boolean",
                              "description": "Mensagem enviada pela conta conectada."
                            },
                            "wasSentByApi": {
                              "type": "boolean",
                              "description": "Origem na API quando esse campo estiver presente na mensagem."
                            },
                            "isGroup": {
                              "type": "boolean",
                              "description": "Identifica conversa de grupo."
                            },
                            "messageType": {
                              "type": "string",
                              "description": "Tipo de mensagem normalizado."
                            },
                            "text": {
                              "type": "string",
                              "description": "Texto ou legenda disponível."
                            },
                            "messageTimestamp": {
                              "type": "integer",
                              "description": "Timestamp da mensagem em milissegundos Unix."
                            },
                            "content": {
                              "description": "Conteúdo específico do tipo de mensagem; não possui um formato único."
                            },
                            "status": {
                              "type": "string",
                              "description": "Estado disponível da mensagem; pode estar vazio."
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "chats": {
                        "type": [
                          "array",
                          "null"
                        ],
                        "description": "Lote de chats.",
                        "items": {
                          "type": "object",
                          "description": "Snapshot de chat. Atualize pelos campos recebidos; não trate o evento como lista completa.",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "ID local do chat."
                            },
                            "wa_chatid": {
                              "type": "string",
                              "description": "JID da conversa."
                            },
                            "name": {
                              "type": "string",
                              "description": "Nome disponível."
                            },
                            "wa_isGroup": {
                              "type": "boolean",
                              "description": "Conversa de grupo."
                            },
                            "wa_isBlocked": {
                              "type": "boolean",
                              "description": "Estado de bloqueio no snapshot."
                            },
                            "wa_archived": {
                              "type": "boolean",
                              "description": "Estado de arquivamento."
                            },
                            "wa_unreadCount": {
                              "type": "integer",
                              "description": "Quantidade de mensagens não lidas disponível."
                            },
                            "wa_label": {
                              "description": "Etiquetas associadas, conforme a projeção do chat. Pode ser texto JSON; normalize antes de usar."
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "labels": {
                        "type": [
                          "array",
                          "null"
                        ],
                        "description": "Lote de etiquetas.",
                        "items": {
                          "$ref": "#/components/schemas/Label"
                        }
                      },
                      "chat_labels": {
                        "type": [
                          "array",
                          "null"
                        ],
                        "description": "Associações atualizadas pela sincronização de etiquetas.",
                        "items": {
                          "type": "object",
                          "additionalProperties": true
                        }
                      },
                      "sync_id": {
                        "type": "string",
                        "description": "Correlação da sincronização de etiquetas, quando presente."
                      },
                      "history_type": {
                        "type": "string",
                        "description": "Origem adicional, como labels_refresh."
                      },
                      "full_sync": {
                        "type": "boolean",
                        "description": "Se a sincronização de etiquetas foi completa."
                      },
                      "chunk": {
                        "type": "object",
                        "description": "Metadados opcionais de fragmentação.",
                        "properties": {
                          "index": {
                            "type": "integer",
                            "description": "Índice do chunk."
                          },
                          "total": {
                            "type": "integer",
                            "description": "Total daquela sequência."
                          },
                          "size": {
                            "type": "integer",
                            "description": "Itens neste chunk."
                          },
                          "has_more": {
                            "type": "boolean",
                            "description": "Existem mais chunks naquela sequência."
                          }
                        },
                        "additionalProperties": true
                      },
                      "batchNumber": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "Número deste lote, começando em 1."
                      },
                      "batchTotal": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "Total de lotes desta sequência."
                      },
                      "batchChunkOrder": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "Sequência da origem deste lote, atribuída pela API. Não é a ordem do chunk no WhatsApp e recomeça em 1 a cada pareamento."
                      },
                      "batchHistoryStatus": {
                        "type": "string",
                        "enum": [
                          "loading",
                          "complete"
                        ],
                        "description": "`loading` em lotes com dados; `complete` no lote `status` que encerra o histórico."
                      },
                      "calls": {
                        "type": [
                          "array",
                          "null"
                        ],
                        "description": "Registros de chamadas do histórico quando event=calls.",
                        "items": {
                          "type": "object",
                          "additionalProperties": true
                        }
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "messages": {
                  "summary": "Lote de mensagens",
                  "value": {
                    "EventType": "history",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "event": "messages",
                    "messages": [
                      {
                        "id": "5511999999999:MSG_HISTORICO",
                        "messageid": "MSG_HISTORICO",
                        "chatid": "5511888888888@s.whatsapp.net",
                        "text": "Mensagem do histórico",
                        "messageTimestamp": 1788868800000
                      }
                    ],
                    "batchNumber": 1,
                    "batchTotal": 1,
                    "batchChunkOrder": 1,
                    "batchHistoryStatus": "loading"
                  }
                },
                "chats": {
                  "summary": "Lote de chats",
                  "value": {
                    "EventType": "history",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "event": "chats",
                    "chats": [
                      {
                        "id": "r0123456789abcd",
                        "wa_chatid": "5511888888888@s.whatsapp.net",
                        "name": "Contato de exemplo"
                      }
                    ],
                    "batchNumber": 1,
                    "batchTotal": 1,
                    "batchChunkOrder": 1,
                    "batchHistoryStatus": "loading"
                  }
                },
                "status": {
                  "summary": "Conclusão do histórico",
                  "value": {
                    "EventType": "history",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "event": "status",
                    "batchNumber": 1,
                    "batchTotal": 1,
                    "batchChunkOrder": 3,
                    "batchHistoryStatus": "complete"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    },
    "messages": {
      "post": {
        "summary": "Mensagens",
        "description": "Receba mensagens novas e projeções de mensagens enviadas pela instância. Use o objeto `message` como ponto de partida para identificar conversa, remetente, conteúdo e ID.\n\n## Quando é enviado\n\nO fluxo de mensagens pode produzir eventos recebidos e enviados. O payload depende do tipo de mensagem e da origem; texto, mídia, reações e atualizações relacionadas não têm conteúdo idêntico.\n\n## Como processar\n\n1. Identifique a instância autorizada e a conversa em `message.chatid`.\n2. Preserve `message.id` e `message.messageid`; não converta os IDs em números.\n3. Aplique deduplicação adequada ao seu processamento. Não responda automaticamente a toda mensagem sem verificar sua origem.\n4. Para acompanhar entrega/leitura, use também `messages_update`.\n\nO objeto `chat` pode acompanhar a mensagem. `chatSource` indica a origem do snapshot quando disponível.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "messages",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "message": {
                        "type": "object",
                        "description": "Mensagem normalizada. Campos disponíveis variam conforme o tipo e a origem.",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Identificador retornado pelo sistema; preserve como string."
                          },
                          "messageid": {
                            "type": "string",
                            "description": "ID da mensagem no WhatsApp."
                          },
                          "chatid": {
                            "type": "string",
                            "description": "JID do contato, grupo ou canal."
                          },
                          "sender": {
                            "type": "string",
                            "description": "JID do remetente."
                          },
                          "senderName": {
                            "type": "string",
                            "description": "Nome disponível do remetente."
                          },
                          "fromMe": {
                            "type": "boolean",
                            "description": "Mensagem enviada pela conta conectada."
                          },
                          "wasSentByApi": {
                            "type": "boolean",
                            "description": "Origem na API quando esse campo estiver presente na mensagem."
                          },
                          "isGroup": {
                            "type": "boolean",
                            "description": "Identifica conversa de grupo."
                          },
                          "messageType": {
                            "type": "string",
                            "description": "Tipo de mensagem normalizado."
                          },
                          "text": {
                            "type": "string",
                            "description": "Texto ou legenda disponível."
                          },
                          "messageTimestamp": {
                            "type": "integer",
                            "description": "Timestamp da mensagem em milissegundos Unix."
                          },
                          "content": {
                            "description": "Conteúdo específico do tipo de mensagem; não possui um formato único."
                          },
                          "status": {
                            "type": "string",
                            "description": "Estado disponível da mensagem; pode estar vazio."
                          }
                        },
                        "additionalProperties": true
                      },
                      "chat": {
                        "type": "object",
                        "description": "Snapshot de chat. Atualize pelos campos recebidos; não trate o evento como lista completa.",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID local do chat."
                          },
                          "wa_chatid": {
                            "type": "string",
                            "description": "JID da conversa."
                          },
                          "name": {
                            "type": "string",
                            "description": "Nome disponível."
                          },
                          "wa_isGroup": {
                            "type": "boolean",
                            "description": "Conversa de grupo."
                          },
                          "wa_isBlocked": {
                            "type": "boolean",
                            "description": "Estado de bloqueio no snapshot."
                          },
                          "wa_archived": {
                            "type": "boolean",
                            "description": "Estado de arquivamento."
                          },
                          "wa_unreadCount": {
                            "type": "integer",
                            "description": "Quantidade de mensagens não lidas disponível."
                          },
                          "wa_label": {
                            "description": "Etiquetas associadas, conforme a projeção do chat. Pode ser texto JSON; normalize antes de usar."
                          }
                        },
                        "additionalProperties": true
                      },
                      "chatSource": {
                        "type": "string",
                        "description": "Origem do snapshot de chat quando presente, por exemplo updated."
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "text": {
                  "summary": "Mensagem de texto recebida",
                  "value": {
                    "EventType": "messages",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "message": {
                      "id": "5511999999999:MSG_EXEMPLO",
                      "messageid": "MSG_EXEMPLO",
                      "chatid": "5511888888888@s.whatsapp.net",
                      "sender": "5511888888888@s.whatsapp.net",
                      "senderName": "Contato de exemplo",
                      "fromMe": false,
                      "isGroup": false,
                      "messageType": "Conversation",
                      "text": "Olá, preciso de ajuda.",
                      "messageTimestamp": 1788868800000
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    },
    "messages_update": {
      "post": {
        "summary": "Entrega e leitura",
        "description": "Acompanhe atualizações de estado de mensagens, como recibos de entrega e leitura.\n\n## Como correlacionar\n\n`event.MessageIDs` pode conter vários IDs. Aplique o estado recebido a cada mensagem correspondente da mesma instância/conversa. Não trate o evento como uma mensagem nova.\n\nA grafia dos campos é relevante: `MessageIDs`, `Timestamp`, `Type`, `IsFromMe` e `IsGroup` usam maiúsculas. Os campos normalizados `chatid`, `sender_pn` e `sender_lid` usam minúsculas.\n\n`event.Timestamp` do fluxo de recibos usa segundos Unix. Isso é diferente de `message.messageTimestamp`, que usa milissegundos. Eventos podem chegar fora da ordem esperada; preserve sua regra de progressão de estado.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "messages_update",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "type": {
                        "type": "string",
                        "description": "Origem do evento; o fluxo de recibos usa ReadReceipt."
                      },
                      "state": {
                        "type": "string",
                        "description": "Estado normalizado aplicado às mensagens."
                      },
                      "event": {
                        "type": "object",
                        "description": "Recibo e mensagens afetadas.",
                        "properties": {
                          "chatid": {
                            "type": "string",
                            "description": "JID da conversa, quando resolvido."
                          },
                          "chatlid": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "LID da conversa; pode ser ausente ou null."
                          },
                          "sender_pn": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "JID por telefone, quando conhecido."
                          },
                          "sender_lid": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Identificador LID, quando conhecido."
                          },
                          "Chat": {
                            "type": "string",
                            "description": "JID da conversa."
                          },
                          "Sender": {
                            "type": "string",
                            "description": "JID do emissor do recibo."
                          },
                          "MessageIDs": {
                            "type": [
                              "array",
                              "null"
                            ],
                            "description": "Mensagens afetadas.",
                            "items": {
                              "type": "string"
                            }
                          },
                          "Timestamp": {
                            "type": "integer",
                            "description": "Segundos Unix no fluxo de recibos."
                          },
                          "Type": {
                            "type": "string",
                            "description": "Estado do recibo."
                          },
                          "IsFromMe": {
                            "type": "boolean",
                            "description": "Origem da mensagem."
                          },
                          "IsGroup": {
                            "type": "boolean",
                            "description": "Conversa de grupo."
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "read": {
                  "summary": "Recibo de leitura",
                  "value": {
                    "EventType": "messages_update",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "type": "ReadReceipt",
                    "state": "Read",
                    "event": {
                      "Chat": "5511888888888@s.whatsapp.net",
                      "chatid": "5511888888888@s.whatsapp.net",
                      "chatlid": null,
                      "Sender": "5511888888888@s.whatsapp.net",
                      "sender_pn": "5511888888888@s.whatsapp.net",
                      "sender_lid": null,
                      "MessageIDs": [
                        "MSG_EXEMPLO"
                      ],
                      "Timestamp": 1788868800,
                      "Type": "Read",
                      "IsFromMe": true,
                      "IsGroup": false
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    },
    "newsletter_messages": {
      "post": {
        "summary": "Mensagens de canais",
        "description": "Receba mensagens de canais/newsletters disponíveis para a sessão.\n\n## Diferenças em relação a messages\n\nO payload inclui `newsletter` e `message`. Preserve o JID terminado em `@newsletter`. O ID normalizado da mensagem combina informações do ID e do identificador de servidor; não reconstrua esse valor por conta própria.\n\nUse `message.isNewsletter`, `newsletterServerId` e os identificadores retornados para reconhecer esse fluxo. A API não transforma toda alteração de canal em mensagem: stanzas de protocolo/reações podem ser ignoradas pelo emissor; consulte as rotas específicas de newsletter para atualizar o estado.\n\nO evento não garante histórico completo nem substitui a consulta de mensagens recentes do canal.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "newsletter_messages",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "newsletter": {
                        "type": "object",
                        "description": "Identificação do canal.",
                        "properties": {
                          "jid": {
                            "type": "string",
                            "description": "JID do canal, quando incluído na projeção."
                          },
                          "id": {
                            "type": "string",
                            "description": "Parte de usuário do JID do canal."
                          },
                          "chatid": {
                            "type": "string",
                            "description": "JID completo do canal."
                          },
                          "server": {
                            "type": "string",
                            "description": "Domínio do identificador, newsletter."
                          }
                        },
                        "additionalProperties": true
                      },
                      "message": {
                        "type": "object",
                        "description": "Mensagem normalizada. Campos disponíveis variam conforme o tipo e a origem.",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Identificador retornado pelo sistema; preserve como string."
                          },
                          "messageid": {
                            "type": "string",
                            "description": "ID da mensagem no WhatsApp."
                          },
                          "chatid": {
                            "type": "string",
                            "description": "JID do contato, grupo ou canal."
                          },
                          "sender": {
                            "type": "string",
                            "description": "JID do remetente."
                          },
                          "senderName": {
                            "type": "string",
                            "description": "Nome disponível do remetente."
                          },
                          "fromMe": {
                            "type": "boolean",
                            "description": "Mensagem enviada pela conta conectada."
                          },
                          "wasSentByApi": {
                            "type": "boolean",
                            "description": "Origem na API quando esse campo estiver presente na mensagem."
                          },
                          "isGroup": {
                            "type": "boolean",
                            "description": "Identifica conversa de grupo."
                          },
                          "messageType": {
                            "type": "string",
                            "description": "Tipo de mensagem normalizado."
                          },
                          "text": {
                            "type": "string",
                            "description": "Texto ou legenda disponível."
                          },
                          "messageTimestamp": {
                            "type": "integer",
                            "description": "Timestamp da mensagem em milissegundos Unix."
                          },
                          "content": {
                            "description": "Conteúdo específico do tipo de mensagem; não possui um formato único."
                          },
                          "status": {
                            "type": "string",
                            "description": "Estado disponível da mensagem; pode estar vazio."
                          },
                          "isNewsletter": {
                            "type": "boolean",
                            "description": "Indica mensagem de canal."
                          },
                          "newsletterServerId": {
                            "type": "integer",
                            "description": "ID de servidor da mensagem de canal."
                          },
                          "newsletterMeta": {
                            "description": "Metadados específicos do canal, quando disponíveis."
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "message": {
                  "summary": "Mensagem de canal",
                  "value": {
                    "EventType": "newsletter_messages",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "newsletter": {
                      "jid": "120363000000000001@newsletter",
                      "id": "120363000000000001",
                      "chatid": "120363000000000001@newsletter",
                      "server": "newsletter"
                    },
                    "message": {
                      "id": "MSG_CANAL:42",
                      "messageid": "MSG_CANAL",
                      "chatid": "120363000000000001@newsletter",
                      "isNewsletter": true,
                      "isGroup": false,
                      "fromMe": false,
                      "messageType": "Conversation",
                      "text": "Atualização do canal",
                      "messageTimestamp": 1788868800000,
                      "newsletterServerId": 42
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    },
    "call": {
      "post": {
        "summary": "Chamadas",
        "description": "Acompanhe sinalização de chamadas e registros de chamadas de saída concluídas.\n\n## Duas formas de evento\n\n| `type` | O que representa | Onde correlacionar |\n|---|---|---|\n| `Call` | Sinalização ao vivo: oferta, aceite, encerramento, rejeição ou aviso | `event.CallID` e, quando disponível, `event.Data.Tag` |\n| `CallLog` | Registro de chamada de saída concluída, recebido pelo fluxo de sincronização | `event.callID` e `event.callResult` |\n\nOs subtipos incluem oferta, aceite, encerramento, rejeição, avisos de chamada e sinalização de latência, conforme os dados recebidos. Avisos de latência podem ser suprimidos quando já houve notificação para a chamada. Não espere uma sequência fixa nem um evento para cada transição interna.\n\n## Como interpretar\n\n- `EventType` é sempre `call`; `type` diferencia `Call` e `CallLog`.\n- No fluxo ao vivo, o subtipo pode estar em `event.Data.Tag`. O campo `Reason` aparece em encerramentos quando fornecido.\n- `fromMe` descreve a origem. `wasSentByAPI` aparece no fluxo ao vivo quando a API consegue classificar essa origem.\n- Identidades PN/LID podem ser acrescentadas quando resolvidas. Em chamadas de grupo, também pode haver `chatid`/`chatlid` na raiz.\n\n## Como processar\n\nCorrelacione a chamada pelo ID dentro da instância, mas não deduplique apenas pelo ID: oferta e encerramento da mesma chamada são eventos diferentes. Não interprete `CallLog` como uma nova chamada recebida. Estes eventos não contêm o áudio da ligação.\n\nOs exemplos abaixo incluem sinalização ao vivo e um registro concluído. Campos remotos opcionais variam entre clientes e situações.\n\n## Resultados em CallLog\n\nO registro usa códigos numéricos: `0` conectado, `1` rejeitado, `2` cancelado, `3` aceito em outro dispositivo, `4` perdido, `5` inválido, `6` indisponível, `8` falha e `9` abandonado. Registros ainda em andamento ou futuros não são emitidos por esse fluxo de conclusão.\n\n\nQuando disponível, `callState` informa offered, accepted, terminated ou rejected para o evento ao vivo.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "call",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "type": {
                        "type": "string",
                        "enum": [
                          "Call",
                          "CallLog"
                        ],
                        "description": "Call para sinalização ao vivo; CallLog para registro de chamada de saída concluída."
                      },
                      "fromMe": {
                        "type": "boolean",
                        "description": "Chamada originada pela conta conectada."
                      },
                      "wasSentByAPI": {
                        "type": "boolean",
                        "description": "Indica início pela API quando informado no fluxo ao vivo."
                      },
                      "isGroup": {
                        "type": "boolean",
                        "description": "Presente em CallLog; no fluxo ao vivo também consulte event.GroupJID."
                      },
                      "chatid": {
                        "type": "string",
                        "description": "JID da conversa, quando resolvido."
                      },
                      "chatlid": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "LID da conversa; pode ser ausente ou null."
                      },
                      "sender_pn": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "JID por telefone, quando conhecido."
                      },
                      "sender_lid": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "Identificador LID, quando conhecido."
                      },
                      "event": {
                        "type": "object",
                        "description": "Dados da sinalização ou do registro. O formato depende de type.",
                        "properties": {
                          "CallID": {
                            "type": "string",
                            "description": "Identificador da chamada ao vivo. Use com o subtipo; uma chamada gera várias notificações."
                          },
                          "From": {
                            "type": "string",
                            "description": "JID de quem enviou a sinalização."
                          },
                          "CallCreator": {
                            "type": "string",
                            "description": "JID de quem criou a chamada."
                          },
                          "CallCreatorAlt": {
                            "type": "string",
                            "description": "Identidade alternativa, quando disponível."
                          },
                          "GroupJID": {
                            "type": "string",
                            "description": "JID do grupo quando aplicável; pode estar vazio."
                          },
                          "Timestamp": {
                            "type": "string",
                            "description": "Data/hora da sinalização ao vivo em formato textual."
                          },
                          "RemotePlatform": {
                            "type": "string",
                            "description": "Plataforma remota, quando disponível."
                          },
                          "RemoteVersion": {
                            "type": "string",
                            "description": "Versão do cliente remoto, quando disponível."
                          },
                          "Reason": {
                            "type": "string",
                            "description": "Motivo informado no encerramento, quando presente."
                          },
                          "Data": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Nó de sinalização; pode não estar presente em todas as variantes.",
                            "properties": {
                              "Tag": {
                                "type": "string",
                                "description": "Subtipo recebido, como offer, accept, terminate ou reject."
                              },
                              "Attrs": {
                                "description": "Atributos do nó; formato variável."
                              },
                              "Content": {
                                "description": "Conteúdo adicional do nó; formato variável."
                              }
                            },
                            "additionalProperties": true
                          },
                          "callID": {
                            "type": "string",
                            "description": "ID no registro CallLog (grafia diferente de CallID)."
                          },
                          "callResult": {
                            "type": "integer",
                            "description": "Resultado numérico do registro CallLog. Não confundir com um status HTTP."
                          },
                          "Media": {
                            "type": "string",
                            "description": "Áudio ou vídeo em avisos de chamada, quando informado."
                          },
                          "Type": {
                            "type": "string",
                            "description": "Pode indicar group em avisos de chamada de grupo; é diferente do type da raiz."
                          },
                          "isIncoming": {
                            "type": "boolean",
                            "description": "Direção no registro CallLog; o fluxo documentado emite registros de saída."
                          },
                          "isVideo": {
                            "type": "boolean",
                            "description": "Indica vídeo no registro CallLog, quando presente."
                          },
                          "callCreatorJID": {
                            "type": "string",
                            "description": "Criador no registro CallLog."
                          },
                          "groupJID": {
                            "type": "string",
                            "description": "Grupo no registro CallLog, quando aplicável."
                          }
                        },
                        "additionalProperties": true
                      },
                      "callState": {
                        "type": "string",
                        "enum": [
                          "offered",
                          "accepted",
                          "terminated",
                          "rejected"
                        ],
                        "description": "Estado da chamada em um evento ao vivo, quando disponível."
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "offer": {
                  "summary": "Oferta de chamada recebida",
                  "value": {
                    "EventType": "call",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "type": "Call",
                    "fromMe": false,
                    "wasSentByAPI": false,
                    "sender_pn": "5511888888888@s.whatsapp.net",
                    "event": {
                      "From": "5511888888888@s.whatsapp.net",
                      "Timestamp": "2026-09-08T12:00:00Z",
                      "CallCreator": "5511888888888@s.whatsapp.net",
                      "CallID": "CALL_EXEMPLO",
                      "GroupJID": "",
                      "RemotePlatform": "android",
                      "RemoteVersion": "versão-do-cliente",
                      "Data": {
                        "Tag": "offer"
                      }
                    },
                    "callState": "offered"
                  }
                },
                "terminate": {
                  "summary": "Encerramento da mesma chamada",
                  "value": {
                    "EventType": "call",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "type": "Call",
                    "fromMe": false,
                    "wasSentByAPI": false,
                    "event": {
                      "From": "5511888888888@s.whatsapp.net",
                      "Timestamp": "2026-09-08T12:01:00Z",
                      "CallCreator": "5511888888888@s.whatsapp.net",
                      "CallID": "CALL_EXEMPLO",
                      "GroupJID": "",
                      "Data": {
                        "Tag": "terminate"
                      }
                    },
                    "callState": "terminated"
                  }
                },
                "calllog": {
                  "summary": "Registro de chamada de saída concluída",
                  "value": {
                    "EventType": "call",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "type": "CallLog",
                    "fromMe": true,
                    "isGroup": false,
                    "event": {
                      "callID": "CALL_EXEMPLO",
                      "callResult": 0,
                      "isIncoming": false
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    },
    "contacts": {
      "post": {
        "summary": "Contatos",
        "description": "Acompanhe alterações de contatos recebidas pela sessão.\n\n## Como interpretar\n\n`event.JID` identifica o contato e `event.Action` contém a atualização recebida, como nomes da agenda. O evento não significa que uma nova conversa foi criada.\n\nAlterações provenientes do full sync podem ser absorvidas pelo processamento de histórico, sem uma notificação individual de contato. Para uma visão inicial, consulte a listagem de contatos e processe os eventos posteriores como atualizações.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "contacts",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "type": {
                        "type": "string",
                        "description": "O fluxo de contato usa Contact."
                      },
                      "event": {
                        "type": "object",
                        "description": "Atualização de contato.",
                        "properties": {
                          "JID": {
                            "type": "string",
                            "description": "JID do contato."
                          },
                          "Timestamp": {
                            "type": "string",
                            "description": "Data/hora informada no evento."
                          },
                          "FromFullSync": {
                            "type": "boolean",
                            "description": "Origem em sincronização completa, quando presente."
                          },
                          "Action": {
                            "type": "object",
                            "description": "Dados alterados do contato.",
                            "properties": {
                              "fullName": {
                                "type": "string",
                                "description": "Nome completo disponível."
                              },
                              "firstName": {
                                "type": "string",
                                "description": "Primeiro nome disponível."
                              },
                              "lidJID": {
                                "type": "string",
                                "description": "Identificador LID, quando disponível."
                              },
                              "saveOnPrimaryAddressbook": {
                                "type": "boolean",
                                "description": "Informação de salvamento na agenda principal, quando presente."
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "contact": {
                  "summary": "Alteração de nome",
                  "value": {
                    "EventType": "contacts",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "type": "Contact",
                    "event": {
                      "JID": "5511888888888@s.whatsapp.net",
                      "Timestamp": "2026-09-08T12:00:00Z",
                      "FromFullSync": false,
                      "Action": {
                        "fullName": "Contato de exemplo",
                        "firstName": "Contato"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    },
    "presence": {
      "post": {
        "summary": "Digitação e gravação",
        "description": "Acompanhe presença dentro de uma conversa, como digitação e gravação de áudio.\n\n## Como interpretar\n\n`event.State` informa o estado de atividade (`composing` ou `paused`); `event.Media` pode indicar áudio. Preserve `Chat`/`chatid` e as identidades de remetente disponíveis.\n\nNão use este evento como confirmação de que o usuário está online ou offline. A API não envia notificações de conectividade (`Presence`); o fluxo de atividade da conversa (`ChatPresence`) é o que produz estes eventos.\n\nEstados de atividade são transitórios e não representam envio, entrega ou leitura de mensagens.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "presence",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "type": {
                        "type": "string",
                        "description": "O fluxo de ChatPresence usa presence."
                      },
                      "event": {
                        "type": "object",
                        "description": "Atividade na conversa.",
                        "properties": {
                          "chatid": {
                            "type": "string",
                            "description": "JID da conversa, quando resolvido."
                          },
                          "chatlid": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "LID da conversa; pode ser ausente ou null."
                          },
                          "sender_pn": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "JID por telefone, quando conhecido."
                          },
                          "sender_lid": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Identificador LID, quando conhecido."
                          },
                          "Chat": {
                            "type": "string",
                            "description": "JID da conversa."
                          },
                          "Sender": {
                            "type": "string",
                            "description": "JID do participante."
                          },
                          "State": {
                            "type": "string",
                            "enum": [
                              "composing",
                              "paused"
                            ],
                            "description": "Atividade recebida."
                          },
                          "Media": {
                            "type": "string",
                            "description": "Tipo de atividade, por exemplo audio; pode estar vazio."
                          },
                          "IsFromMe": {
                            "type": "boolean",
                            "description": "Origem na conta conectada."
                          },
                          "IsGroup": {
                            "type": "boolean",
                            "description": "Conversa de grupo."
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "typing": {
                  "summary": "Contato digitando",
                  "value": {
                    "EventType": "presence",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "type": "presence",
                    "event": {
                      "Chat": "5511888888888@s.whatsapp.net",
                      "Sender": "5511888888888@s.whatsapp.net",
                      "chatid": "5511888888888@s.whatsapp.net",
                      "State": "composing",
                      "Media": "",
                      "IsFromMe": false,
                      "IsGroup": false
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    },
    "groups": {
      "post": {
        "summary": "Alterações de grupos",
        "description": "Acompanhe alterações de metadados e participantes de grupos.\n\n## Variações\n\nO fluxo pode usar `type: Group` para alterações de informações e `type: JoinedGroup` para entrada em grupo. O conteúdo de `event` varia com a alteração. `Join`, `Leave`, `Promote` e `Demote` descrevem participantes afetados; campos ausentes ou nulos não significam, por si só, que todos foram removidos.\n\nUse `event.JID` ou o identificador normalizado disponível na raiz para correlacionar o grupo. Os arrays podem incluir projeções PN/LID. Consulte `/group/info` quando precisar do estado atual completo, em vez de reconstruí-lo a partir de um único evento parcial.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "groups",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "type": {
                        "type": "string",
                        "description": "Group ou JoinedGroup, conforme a origem."
                      },
                      "chatid": {
                        "type": "string",
                        "description": "JID da conversa, quando resolvido."
                      },
                      "chatlid": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "LID da conversa; pode ser ausente ou null."
                      },
                      "sender_pn": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "JID por telefone, quando conhecido."
                      },
                      "sender_lid": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "Identificador LID, quando conhecido."
                      },
                      "event": {
                        "type": "object",
                        "description": "Mudança de grupo.",
                        "properties": {
                          "JID": {
                            "type": "string",
                            "description": "JID do grupo."
                          },
                          "Sender": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Participante associado à alteração, quando disponível."
                          },
                          "Timestamp": {
                            "type": "string",
                            "description": "Data/hora da alteração."
                          },
                          "Name": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Alteração de nome.",
                            "properties": {
                              "Name": {
                                "type": "string",
                                "description": "Nome informado."
                              }
                            },
                            "additionalProperties": true
                          },
                          "Topic": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Alteração de descrição.",
                            "properties": {
                              "Topic": {
                                "type": "string",
                                "description": "Descrição informada."
                              }
                            },
                            "additionalProperties": true
                          },
                          "Join": {
                            "type": [
                              "array",
                              "null"
                            ],
                            "description": "Participantes afetados por esta alteração.",
                            "items": {
                              "type": "string"
                            }
                          },
                          "Leave": {
                            "type": [
                              "array",
                              "null"
                            ],
                            "description": "Participantes afetados por esta alteração.",
                            "items": {
                              "type": "string"
                            }
                          },
                          "Promote": {
                            "type": [
                              "array",
                              "null"
                            ],
                            "description": "Participantes afetados por esta alteração.",
                            "items": {
                              "type": "string"
                            }
                          },
                          "Demote": {
                            "type": [
                              "array",
                              "null"
                            ],
                            "description": "Participantes afetados por esta alteração.",
                            "items": {
                              "type": "string"
                            }
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "name": {
                  "summary": "Alteração do nome do grupo",
                  "value": {
                    "EventType": "groups",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "type": "Group",
                    "event": {
                      "JID": "120363000000000001@g.us",
                      "Sender": "5511888888888@s.whatsapp.net",
                      "Timestamp": "2026-09-08T12:00:00Z",
                      "Name": {
                        "Name": "Equipe de atendimento"
                      },
                      "Join": [],
                      "Leave": [],
                      "Promote": [],
                      "Demote": []
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    },
    "labels": {
      "post": {
        "summary": "Definição de etiquetas",
        "description": "Acompanhe criação, renomeação, cor e exclusão de etiquetas.\n\n## Etiqueta versus associação\n\n`labels` descreve a definição da etiqueta. Para saber quais etiquetas estão associadas a um chat, use `chat_labels`. Sincronizações completas de etiquetas também podem chegar em lotes de `history`.\n\nUse `event.LabelID` para correlacionar a etiqueta. Em `event.Action`, `deleted` indica exclusão quando fornecido; nome e cor podem variar conforme a ação recebida.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "labels",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "type": {
                        "type": "string",
                        "description": "O evento de edição usa LabelEdit."
                      },
                      "event": {
                        "type": "object",
                        "description": "Atualização da etiqueta.",
                        "properties": {
                          "LabelID": {
                            "type": "string",
                            "description": "ID da etiqueta."
                          },
                          "Timestamp": {
                            "type": "string",
                            "description": "Data/hora da atualização."
                          },
                          "FromFullSync": {
                            "type": "boolean",
                            "description": "Origem de full sync quando presente."
                          },
                          "Action": {
                            "type": "object",
                            "description": "Alterações recebidas.",
                            "properties": {
                              "name": {
                                "type": "string",
                                "description": "Nome da etiqueta."
                              },
                              "color": {
                                "type": "integer",
                                "description": "Código de cor."
                              },
                              "deleted": {
                                "type": "boolean",
                                "description": "Indica exclusão da etiqueta."
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "label": {
                  "summary": "Etiqueta criada ou renomeada",
                  "value": {
                    "EventType": "labels",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "type": "LabelEdit",
                    "event": {
                      "LabelID": "31",
                      "Timestamp": "2026-09-08T12:00:00Z",
                      "FromFullSync": false,
                      "Action": {
                        "name": "Suporte",
                        "color": 1,
                        "deleted": false
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    },
    "chats": {
      "post": {
        "summary": "Atualizações de chats",
        "description": "Acompanhe mudanças no snapshot de uma conversa: nome disponível, contadores, arquivamento, bloqueio e outros campos atualizados.\n\n## Como processar\n\nCorrelacione por `chat.wa_chatid` ou pelo ID local disponível e aplique os campos recebidos. O evento traz um chat, não uma listagem completa. Não recrie uma mensagem apenas porque a prévia do chat mudou.\n\nSnapshots podem refletir processamento posterior de uma mensagem ou atualização de metadados. Para inicialização e reconciliação, use `/chat/find`.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "chats",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "chat": {
                        "type": "object",
                        "description": "Snapshot de chat. Atualize pelos campos recebidos; não trate o evento como lista completa.",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID local do chat."
                          },
                          "wa_chatid": {
                            "type": "string",
                            "description": "JID da conversa."
                          },
                          "name": {
                            "type": "string",
                            "description": "Nome disponível."
                          },
                          "wa_isGroup": {
                            "type": "boolean",
                            "description": "Conversa de grupo."
                          },
                          "wa_isBlocked": {
                            "type": "boolean",
                            "description": "Estado de bloqueio no snapshot."
                          },
                          "wa_archived": {
                            "type": "boolean",
                            "description": "Estado de arquivamento."
                          },
                          "wa_unreadCount": {
                            "type": "integer",
                            "description": "Quantidade de mensagens não lidas disponível."
                          },
                          "wa_label": {
                            "description": "Etiquetas associadas, conforme a projeção do chat. Pode ser texto JSON; normalize antes de usar."
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "chat": {
                  "summary": "Snapshot atualizado",
                  "value": {
                    "EventType": "chats",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "chat": {
                      "id": "r0123456789abcd",
                      "wa_chatid": "5511888888888@s.whatsapp.net",
                      "name": "Contato de exemplo",
                      "wa_isGroup": false,
                      "wa_isBlocked": false,
                      "wa_archived": false,
                      "wa_unreadCount": 2
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    },
    "chat_labels": {
      "post": {
        "summary": "Etiquetas de um chat",
        "description": "Acompanhe alterações nas etiquetas associadas a uma conversa.\n\n## Como processar\n\nA atualização chega no objeto `chat`. O campo `chat.wa_label` representa a associação resultante; normalize a representação recebida antes de aplicar. Uma lista vazia significa que as etiquetas foram removidas.\n\nNão confunda este evento com `labels`, que altera a definição da etiqueta. Em sincronizações, associações também podem chegar em `history` com `event: chat_labels` e metadados de chunks.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "chat_labels",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "chat": {
                        "type": "object",
                        "description": "Snapshot de chat. Atualize pelos campos recebidos; não trate o evento como lista completa.",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID local do chat."
                          },
                          "wa_chatid": {
                            "type": "string",
                            "description": "JID da conversa."
                          },
                          "name": {
                            "type": "string",
                            "description": "Nome disponível."
                          },
                          "wa_isGroup": {
                            "type": "boolean",
                            "description": "Conversa de grupo."
                          },
                          "wa_isBlocked": {
                            "type": "boolean",
                            "description": "Estado de bloqueio no snapshot."
                          },
                          "wa_archived": {
                            "type": "boolean",
                            "description": "Estado de arquivamento."
                          },
                          "wa_unreadCount": {
                            "type": "integer",
                            "description": "Quantidade de mensagens não lidas disponível."
                          },
                          "wa_label": {
                            "description": "Etiquetas associadas, conforme a projeção do chat. Pode ser texto JSON; normalize antes de usar."
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "removed": {
                  "summary": "Todas as etiquetas removidas do chat",
                  "value": {
                    "EventType": "chat_labels",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "chat": {
                      "id": "r0123456789abcd",
                      "wa_chatid": "5511888888888@s.whatsapp.net",
                      "wa_label": "[]"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    },
    "sender": {
      "post": {
        "summary": "Processamento de campanhas",
        "description": "Acompanhe início e conclusão do processamento de uma pasta de campanha.\n\n## Estados e contadores\n\n| `status` | Conteúdo principal |\n|---|---|\n| `sending` | `folderID`, `folderInfo`, `messageCount`, `scheduledFor`, `startedAt` |\n| `done` | `folderID`, `folderInfo`, `successCount`, `failedCount`, `completedAt` |\n\nCorrelacione pelo `folderID` dentro da instância. Os timestamps de início/conclusão usam milissegundos Unix. O término do processamento e os contadores da campanha não equivalem à leitura de todas as mensagens pelos destinatários; para isso, acompanhe os eventos de mensagens correspondentes.\n\nA notificação de início ocorre na transição de scheduled para sending; não espere um novo evento de início a cada retomada interna.",
        "x-status": "active",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "EventType": {
                        "type": "string",
                        "const": "sender",
                        "description": "Nome exato para inscrição e identificação deste evento."
                      },
                      "folderID": {
                        "type": "string",
                        "description": "ID da pasta de campanha."
                      },
                      "folderInfo": {
                        "type": "string",
                        "description": "Informação descritiva da pasta."
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "sending",
                          "done"
                        ],
                        "description": "Fase notificada do processamento."
                      },
                      "messageCount": {
                        "type": "integer",
                        "description": "Quantidade no início do processamento."
                      },
                      "scheduledFor": {
                        "type": "integer",
                        "description": "Agendamento informado pela pasta."
                      },
                      "startedAt": {
                        "type": "integer",
                        "description": "Início em milissegundos Unix."
                      },
                      "successCount": {
                        "type": "integer",
                        "description": "Contagem de sucesso registrada pelo processamento."
                      },
                      "failedCount": {
                        "type": "integer",
                        "description": "Contagem de falhas registrada pelo processamento."
                      },
                      "completedAt": {
                        "type": "integer",
                        "description": "Conclusão em milissegundos Unix."
                      }
                    },
                    "additionalProperties": true
                  }
                ]
              },
              "examples": {
                "sending": {
                  "summary": "Início de processamento",
                  "value": {
                    "EventType": "sender",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "folderID": "r0123456789abcd",
                    "folderInfo": "Campanha de exemplo",
                    "status": "sending",
                    "messageCount": 20,
                    "scheduledFor": 1788868800000,
                    "startedAt": 1788868800000
                  }
                },
                "done": {
                  "summary": "Processamento concluído",
                  "value": {
                    "EventType": "sender",
                    "owner": "5511999999999",
                    "token": "INSTANCE_TOKEN",
                    "BaseUrl": "https://seu-servidor.example",
                    "instanceName": "Atendimento",
                    "folderID": "r0123456789abcd",
                    "folderInfo": "Campanha de exemplo",
                    "status": "done",
                    "successCount": 19,
                    "failedCount": 1,
                    "completedAt": 1788868860000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seu receptor aceitou o evento. A resposta deve ser rápida; processe trabalho demorado depois de persistir o recebimento."
          }
        }
      }
    }
  }
}
