Migrar do Z-API para a API oficial do WhatsApp

Em resumo: para levar um bot ou uma automação do produto de QR code do Z-API para a API Cloud oficial da Meta, conecte o número ao ZapClaw pela Coexistência, envie pela API REST do ZapClaw em vez de /send-text e leia o webhook do ZapClaw em vez de ReceivedCallback. O número continua funcionando no app WhatsApp Business no seu celular. Abaixo: os passos, os campos de envio de texto e de mídia e os principais campos de webhook lado a lado, e o que não tem equivalente na API oficial.

O ZapClaw conecta o seu número à API Cloud da Meta pela Coexistência, sem sessão de QR code e sem app próprio na Meta.

Plano Business: R$ 99 por mês, com números ilimitados

Comece grátis Ver o mapeamento dos campos

Por que migrar para a API oficial

As políticas da Meta continuam valendo na API oficial: a Meta pode restringir ou desativar uma conta que as descumpre, e a API do ZapClaw passa a responder 403 com o motivo (erros, em inglês).

O que você precisa para conectar

Não precisa de CNPJ nem de empresa verificada para conectar. A lista completa.

A migração, passo a passo

  1. Mapeie o código primeiro. Troque as chamadas de envio e o tratamento do webhook com as tabelas abaixo, ou coloque o shim na frente do seu fluxo para ele manter as chamadas do Z-API enquanto você reescreve.
  2. Faça backup das conversas no app WhatsApp Business e confira os requisitos acima.
  3. Conecte o número. Crie a sua conta no ZapClaw e conecte o número na janela da Meta, pelo painel. A Meta então desconecta todos os dispositivos vinculados à conta, inclusive a sessão do Z-API. Desconecte a instância no Z-API depois, para ninguém ler o QR code dela de novo e dois sistemas responderem ao mesmo cliente.
  4. Configure o webhook. No painel, em Webhook, cole a sua URL HTTPS pública, escolha os eventos e copie a chave de assinatura. Marque Mensagens enviadas pelo app WhatsApp Business se o seu fluxo lia callbacks com fromMe: true.
  5. Crie uma chave de API e envie com ela no cabeçalho X-API-Key para https://api.zapclaw.app. O campo from indica o número, então uma chave envia por todos os números da conta, sem id de instância nem token no caminho.
  6. Crie os seus templates. Fora da janela de 24 horas, e para escrever primeiro, a Meta só aceita um template aprovado. Crie pelo painel ou com POST /api/v1/send/templates, e passe language ao enviar um: o padrão da API é pt_BR.
  7. Teste. Clique em Enviar evento de teste na página Webhook do painel, depois escreva para o seu número de outro celular e confira se o seu fluxo recebe a mensagem e responde.

Envio: as chamadas do Z-API e o equivalente no ZapClaw

Os caminhos do Z-API começam com https://api.z-api.io/instances/{instanceId}/token/{token}, abreviado abaixo como …. Os do ZapClaw começam com https://api.zapclaw.app.

Z-API ZapClaw
Enviar texto POST …/send-text POST /api/v1/send/text
Enviar mídia …/send-image, …/send-video, …/send-audio, …/send-sticker, …/send-document/{extension} POST /api/v1/send/media
Autenticação Id da instância e token no caminho, mais um cabeçalho Client-Token opcional Cabeçalho X-API-Key
O seu número A instância, no caminho from, no corpo
Destinatário phone: um número ou um id de grupo to: um número, só dígitos
Texto message text, até 4.096 caracteres
Arquivo de mídia image, video, audio, sticker ou document: um link ou base64 type, mais link (uma URL https pública) ou mediaId de POST /api/v1/media
Nome do documento A extensão no caminho, fileName no corpo filename, com a extensão
Legenda caption caption (imagem, vídeo, documento)
Responder a uma mensagem messageId, nos envios de texto e de mídia replyTo: o wamid da mensagem
Atrasos delayMessage, delayTyping Sem equivalente. POST /api/v1/send/typing mostra o indicador de digitação numa mensagem que você recebeu.
Visualização única viewOnce Não suportado num número em Coexistência
Editar uma mensagem enviada editMessageId Sem equivalente
Resposta zaapId, messageId, id 201 com message.id e message.wamid

Localização, cartões de contato e reações vão por POST /api/v1/send/location, /send/contacts e /send/reaction (referência da API, em inglês). O shim mais abaixo ainda não converte essas chamadas: envie direto ao ZapClaw.

Recebimento: o ReceivedCallback e o equivalente no ZapClaw

O Z-API envia cada mensagem como um objeto plano com type: "ReceivedCallback". O ZapClaw envia event, timestamp, data e account para uma URL só, para todos os seus números.

Z-API ZapClaw
Evento type: "ReceivedCallback" event: "message.received", também no cabeçalho X-ZapClaw-Event
Qual dos seus números instanceId, connectedPhone account.phone_number_id, account.display_phone_number
Remetente phone data.from, e data.user_id, o id permanente do contato
Enviada por você fromMe: true Um evento separado, message.echo, com data.to, para mensagens enviadas pelo app WhatsApp Business ou pelo WhatsApp Web (opcional)
Id da mensagem messageId data.message_id, um wamid
Nome do contato senderName, chatName data.contact_name
Horário momment: milissegundos nos exemplos da documentação data.timestamp: segundos, como string
Texto text.message data.text.body
Imagem image.imageUrl, image.mimeType, image.caption data.image.media_url, data.image.mime_type, data.image.caption
Áudio audio.audioUrl, audio.ptt data.audio.media_url, data.audio.voice
Vídeo video.videoUrl, video.caption data.video.media_url, data.video.caption
Documento document.documentUrl, document.fileName data.document.media_url, data.document.filename
Figurinha sticker.stickerUrl data.sticker.media_url
Localização location.latitude, location.longitude data.location.latitude, data.location.longitude
Resposta de botão buttonsResponseMessage.buttonId data.interactive.button_reply.id; a resposta rápida de um template chega como data.button.payload
Resposta de lista listResponseMessage.selectedRowId data.interactive.list_reply.id
Mensagem citada referenceMessageId data.context.id
Grupos isGroup, participantPhone Sempre uma conversa individual
Status de entrega MessageStatusCallback, com SENT, RECEIVED, READ, READ_BY_ME ou PLAYED message.status, com data.status igual a sent, delivered, read ou failed
Resultado do envio DeliveryCallback, com error quando o envio falhou message.status com failed, e o motivo da Meta em data.errors
Armazenamento de mídia O Z-API guarda os arquivos por 30 dias A Meta guarda a mídia recebida por cerca de 30 dias; baixe com a sua X-API-Key
Autenticação da requisição Nenhuma descrita na documentação de webhooks X-ZapClaw-Signature: um HMAC-SHA256 do corpo bruto, feito com a sua chave de assinatura (como verificar, em inglês)

O Z-API avisa um envio que falhou no webhook DeliveryCallback, no campo error; o MessageStatusCallback dele não tem status de falha. No ZapClaw, um message.status com failed traz o motivo da Meta em data.errors: leve para lá o tratamento de erro do seu DeliveryCallback. As entregas podem chegar fora de ordem: quando a ordem importa, ordene pelo sequence do nível superior.

O que não tem equivalente, e o que fazer no lugar

Continue usando o app WhatsApp Business no celular: a Meta desconecta um número em Coexistência cujo app fica cerca de 14 dias sem uso, e o ZapClaw avisa o seu webhook com um evento account.account_update (detalhes, em inglês).

Um adaptador curto

Duas funções para Node.js 18 ou mais novo, sem dependências: a primeira envia onde o seu código chamava send-text, a segunda transforma um message.received do ZapClaw nos campos do ReceivedCallback que o seu fluxo já lê. Confira o cabeçalho X-ZapClaw-Signature antes de confiar num corpo.

// Sending: what was POST .../instances/{instanceId}/token/{token}/send-text
const sendText = async ({ phone, message }) => {
  const res = await fetch('https://api.zapclaw.app/api/v1/send/text', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': process.env.ZAPCLAW_API_KEY,
    },
    body: JSON.stringify({ from: process.env.ZAPCLAW_FROM, to: phone, text: message }),
  });
  if (!res.ok) throw new Error(`ZapClaw answered ${res.status}`);
  const sent = (await res.json()).message;
  return { zaapId: sent.id, messageId: sent.wamid, id: sent.wamid };
};

// Receiving: the ReceivedCallback fields, taken from a message.received body
const fromZapClaw = (body) => ({
  phone: body.data.from,
  messageId: body.data.message_id,
  senderName: body.data.contact_name,
  momment: Number(body.data.timestamp) * 1000,
  text: body.data.text ? { message: body.data.text.body } : undefined,
});

A versão completa está no GitHub: zapclaw/migrate-to-whatsapp-official-api converte texto, mídia, status de entrega e webhooks, e traz um pequeno shim. Uma chamada que não é convertida, como uma localização ou um cartão de contato, é recusada com um código de erro claro: envie essas chamadas direto pela API do ZapClaw. Aponte para o shim a URL base do Z-API que o seu fluxo usa: ele repassa ao ZapClaw as chamadas que converte e transforma os webhooks assinados do ZapClaw de volta em ReceivedCallback, MessageStatusCallback e, para um envio que falhou, DeliveryCallback, para você migrar primeiro e reescrever depois. Licença MIT.

Se o seu cenário é diferente

Quanto custa

A Meta cobra as tarifas de mensagem do WhatsApp direto de você, sem margem do ZapClaw. Todos os planos e preços.

Veja também

Fontes

Conferido em 15 de outubro de 2026. O Z-API muda a API com o tempo, então confira a documentação dele antes de migrar.

Leve os seus fluxos do Z-API para a API oficial

Comece no plano grátis: um número, sem cartão. Passe para o plano Business quando precisar de mais números ou de mais mensagens.

Comece grátis Ler a documentação do webhook