Migrar de Z-API a la API oficial de WhatsApp

En resumen: para llevar un bot o una automatización del producto de código QR de Z-API a la Cloud API oficial de Meta, conecta el número a ZapClaw con la Coexistencia, envía por la API REST de ZapClaw en lugar de /send-text y lee el webhook de ZapClaw en lugar de ReceivedCallback. El número sigue funcionando en la app de WhatsApp Business en tu celular. Abajo: los pasos, los campos de envío de texto y multimedia y los principales campos de webhook lado a lado, y lo que no tiene equivalente en la API oficial.

ZapClaw conecta tu número a la Cloud API de Meta con la Coexistencia, sin sesión de código QR y sin app propia en Meta.

Plan Business: US$ 29 al mes, con números ilimitados

Empieza gratis Ver el mapeo de campos

Por qué pasar a la API oficial

Las políticas de Meta siguen aplicando en la API oficial: Meta puede restringir o desactivar una cuenta que las incumple, y la API de ZapClaw responde entonces 403 con el motivo (errores, en inglés).

Lo que necesitas para conectar

No necesitas una empresa registrada ni un negocio verificado para conectar. La lista completa.

La migración, paso a paso

  1. Primero, mapea tu código. Cambia tus llamadas de envío y tu manejador de webhook con las tablas de abajo, o pon el shim delante de tu flujo para que conserve sus llamadas de Z-API mientras lo reescribes.
  2. Haz una copia de seguridad de tus chats en la app de WhatsApp Business y revisa los requisitos de arriba.
  3. Conecta el número. Crea tu cuenta en ZapClaw y conecta el número en la ventana de Meta, desde el panel. Meta desvincula entonces todos los dispositivos vinculados a la cuenta, incluida la sesión de Z-API. Desconecta la instancia en Z-API después, para que nadie vuelva a leer su código QR y dos sistemas respondan al mismo cliente.
  4. Configura el webhook. En el panel, en Webhook, pega tu URL HTTPS pública, elige los eventos y copia la clave de firma. Marca Mensajes enviados desde la app WhatsApp Business si tu flujo leía callbacks con fromMe: true.
  5. Crea una clave de API y envía con ella en el encabezado X-API-Key a https://api.zapclaw.app. El campo from indica el número, así que una clave envía desde todos los números de la cuenta, sin id de instancia ni token en la ruta.
  6. Crea tus plantillas. Fuera de la ventana de 24 horas, y para escribir primero, Meta solo acepta una plantilla aprobada. Créalas en el panel o con POST /api/v1/send/templates, y pasa language al enviar una: el valor por defecto de la API es pt_BR.
  7. Prueba. Haz clic en Enviar evento de prueba en la página Webhook del panel, luego escribe a tu número desde otro celular y comprueba que tu flujo recibe el mensaje y responde.

Envío: las llamadas de Z-API y su equivalente en ZapClaw

Las rutas de Z-API empiezan con https://api.z-api.io/instances/{instanceId}/token/{token}, abreviado abajo como …. Las de ZapClaw empiezan con https://api.zapclaw.app.

Z-API ZapClaw
Enviar texto POST …/send-text POST /api/v1/send/text
Enviar multimedia …/send-image, …/send-video, …/send-audio, …/send-sticker, …/send-document/{extension} POST /api/v1/send/media
Autenticación Id de la instancia y token en la ruta, más un encabezado Client-Token opcional Encabezado X-API-Key
Tu número La instancia, en la ruta from, en el cuerpo
Destinatario phone: un número o un id de grupo to: un número, solo dígitos
Texto message text, hasta 4,096 caracteres
Archivo multimedia image, video, audio, sticker o document: un enlace o base64 type, más link (una URL https pública) o mediaId de POST /api/v1/media
Nombre del documento La extensión en la ruta, fileName en el cuerpo filename, con su extensión
Leyenda caption caption (imagen, video, documento)
Responder a un mensaje messageId, en los envíos de texto y multimedia replyTo: el wamid del mensaje
Retrasos delayMessage, delayTyping Sin equivalente. POST /api/v1/send/typing muestra el indicador de escritura en un mensaje que recibiste.
Visualización única viewOnce No se admite en un número con Coexistencia
Editar un mensaje enviado editMessageId Sin equivalente
Respuesta zaapId, messageId, id 201 con message.id y message.wamid

La ubicación, las tarjetas de contacto y las reacciones van por POST /api/v1/send/location, /send/contacts y /send/reaction (referencia de la API, en inglés). El shim de más abajo aún no convierte esas llamadas: envíalas directo a ZapClaw.

Recepción: ReceivedCallback y su equivalente en ZapClaw

Z-API envía cada mensaje como un objeto plano con type: "ReceivedCallback". ZapClaw envía event, timestamp, data y account a una sola URL para todos tus números.

Z-API ZapClaw
Evento type: "ReceivedCallback" event: "message.received", también en el encabezado X-ZapClaw-Event
Cuál de tus números instanceId, connectedPhone account.phone_number_id, account.display_phone_number
Remitente phone data.from, y data.user_id, el id permanente del contacto
Enviado por ti fromMe: true Un evento aparte, message.echo, con data.to, para mensajes enviados desde la app de WhatsApp Business o WhatsApp Web (opcional)
Id del mensaje messageId data.message_id, un wamid
Nombre del contacto senderName, chatName data.contact_name
Hora momment: milisegundos en los ejemplos de la documentación data.timestamp: segundos, como cadena
Texto text.message data.text.body
Imagen image.imageUrl, image.mimeType, image.caption data.image.media_url, data.image.mime_type, data.image.caption
Audio audio.audioUrl, audio.ptt data.audio.media_url, data.audio.voice
Video video.videoUrl, video.caption data.video.media_url, data.video.caption
Documento document.documentUrl, document.fileName data.document.media_url, data.document.filename
Sticker sticker.stickerUrl data.sticker.media_url
Ubicación location.latitude, location.longitude data.location.latitude, data.location.longitude
Respuesta de botón buttonsResponseMessage.buttonId data.interactive.button_reply.id; la respuesta rápida de una plantilla llega como data.button.payload
Respuesta de lista listResponseMessage.selectedRowId data.interactive.list_reply.id
Mensaje citado referenceMessageId data.context.id
Grupos isGroup, participantPhone Siempre un chat individual
Estado de entrega MessageStatusCallback, con SENT, RECEIVED, READ, READ_BY_ME o PLAYED message.status, con data.status igual a sent, delivered, read o failed
Resultado del envío DeliveryCallback, con error cuando el envío falló message.status con failed, y el motivo de Meta en data.errors
Almacenamiento de archivos Z-API guarda los archivos 30 días Meta guarda los archivos recibidos unos 30 días; descárgalos con tu X-API-Key
Autenticación de la solicitud Ninguna descrita en la documentación de webhooks X-ZapClaw-Signature: un HMAC-SHA256 del cuerpo sin procesar, hecho con tu clave de firma (cómo verificarla, en inglés)

Z-API avisa de un envío fallido en su webhook DeliveryCallback, en el campo error; su MessageStatusCallback no tiene un estado de fallo. En ZapClaw, un message.status con failed trae el motivo de Meta en data.errors: lleva ahí el manejo de errores de tu DeliveryCallback. Las entregas pueden llegar fuera de orden: cuando el orden importa, ordena por el sequence del nivel superior.

Lo que no tiene equivalente, y qué hacer en su lugar

Sigue usando la app de WhatsApp Business en el celular: Meta desconecta un número con Coexistencia cuya app pasa unos 14 días sin uso, y ZapClaw avisa a tu webhook con un evento account.account_update (detalles, en inglés).

Un adaptador corto

Dos funciones para Node.js 18 o más reciente, sin dependencias: la primera envía donde tu código llamaba a send-text, la segunda convierte un message.received de ZapClaw en los campos de ReceivedCallback que tu flujo ya lee. Comprueba el encabezado X-ZapClaw-Signature antes de confiar en un cuerpo.

// 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,
});

La versión completa está en GitHub: zapclaw/migrate-to-whatsapp-official-api convierte texto, multimedia, estados de entrega y webhooks, e incluye un pequeño shim. Una llamada que no se convierte, como una ubicación o una tarjeta de contacto, se rechaza con un código de error claro: envía esas llamadas directo por la API de ZapClaw. Apunta al shim la URL base de Z-API que usa tu flujo: reenvía a ZapClaw las llamadas que convierte y transforma los webhooks firmados de ZapClaw de nuevo en ReceivedCallback, MessageStatusCallback y, para un envío fallido, DeliveryCallback, para que migres primero y reescribas después. Licencia MIT.

Si tu caso es distinto

Cuánto cuesta

Meta te cobra directamente las tarifas de mensajes de WhatsApp, sin margen de ZapClaw. Todos los planes y precios.

Ver también

Fuentes

Revisado el 15 de octubre de 2026. Z-API cambia su API con el tiempo, así que revisa su documentación antes de migrar.

Lleva tus flujos de Z-API a la API oficial

Empieza en el plan gratuito: un número, sin tarjeta. Pasa al plan Business cuando necesites más números o más mensajes.

Empieza gratis Leer la documentación del webhook