Pular para o conteúdo principal
Quase certamente você está usando o store em memória, que perde as credenciais quando o processo encerra. Use um backend durável (SQLite, Postgres, …) para o domínio auth e mantenha um sessionId estável entre execuções — trocá-lo órfã as credenciais anteriores. Veja Stores.
É proposital — o zapo não reconecta sozinho. Escute o evento connection com status: 'close' e chame connect() de novo (pule quando isLogout for true). Veja o padrão de reconexão.
A mídia faz upload mesmo sem o @zapo-js/media-utils — mas sem ele não há processor para gerar thumbnails/previews, dimensões de imagem-vídeo ou waveforms de áudio, então ela pode aparecer como anexo simples ou sem preview. Para mídia adequada, instale (npm i @zapo-js/media-utils, mais ffmpeg/ffprobe) e configure um processor via opção media. Veja Mídia.
Passe um caminho de arquivo (string) ou um Readable para media, não um Buffer — o zapo faz streaming dos bytes pelo pipeline, então a memória fica constante mesmo com arquivos grandes. No download, prefira downloadToFile/download em vez de downloadBytes.
A perna proxy.ws precisa do pacote ws (o WebSocket nativo do runtime não aceita um Agent HTTP). As pernas de mídia/link-preview usam um dispatcher do undici. Veja os exemplos de proxy para SOCKS/HTTP/HTTPS e IPv4/IPv6.
Sempre responda para o event.key.remoteJid (o JID do grupo), nunca para o JID de um participante. Quando você tiver o LID de um contato, prefira o LID — é a identidade preservadora de privacidade e compatível com o futuro. Veja Identidades (PN vs LID).
Isso é a sincronização multi-dispositivo — seus próprios envios voltam no evento message marcados com key.fromMe === true. Filtre-os se você só quer tráfego de entrada. Veja Recebendo mensagens.
Importe o tipo do evento da raiz do pacote — todos os tipos de coordinator e de evento são exportados:
Não. As conexões mobile são estáveis, mas o zapo intencionalmente não fornece API de registro — registrar um número é complexo e exige um celular físico. Você conecta com credenciais já registradas. Veja Conexões mobile.
Os dois funcionam. O QR é o padrão (evento auth_qr). Para um código de 8 caracteres, chame client.auth.requestPairingCode(phone) após o evento auth_pairing_required. Veja Autenticação.
disconnect() fecha o socket mas mantém as credenciais para você retomar depois. logout() desvincula o dispositivo no servidor e limpa o estado armazenado (conforme logoutStoreClear). Veja Autenticação.
O WhatsApp rejeitou a versão embarcada do WA Web. Atualize o zapo quando possível. Como paliativo, ative recoverFromClientTooOld: true para buscar a versão atual e reconectar, ou passe um resolver version que retorne uma string fresca por conexão. Veja Versão do WhatsApp Web.
Algumas operações são restritas: editBusinessProfile, operações de foto de capa e broadcast lists são somente business; vincular email é somente mobile; várias operações de comunidade/newsletter exigem um transporte MEX ativo. A referência de coordinators sinaliza cada uma.

Ainda travado?

Arquitetura em detalhes

Entenda as camadas para depurar no nível do protocolo.

API low-level

Inspecione stanzas cruas com os eventos de debug e o lowlevel.
Última modificação em 29 de maio de 2026