Migration

Migrate from Evolution API to ZapZap: a step-by-step guide

Migrating from Evolution API to ZapZap swaps a system you host for a managed service. You stop running the server, database and updates, and pay R$15 per active number per month. The code change is small: send URL and headers and the webhook reader. The facts about Evolution come from the official repository and documentation, read on 10/27/2026.

Published on · 4 min read

This article is also available in: Português · Español

What changes when you leave self-hosting

Evolution API is open source: the official repository states Apache 2.0 with additional conditions on logo preservation and usage notification, Node.js 20 or later, PostgreSQL or MySQL, and Redis recommended. The project's own description says the Baileys connection relies on WhatsApp Web and may have limitations compared with official APIs. You choose the server, the version and when to update.

On ZapZap, the server, updates and monitoring are on us, and billing is per active number. In return, you do not control the infrastructure or the code. Both are unofficial, so the ban risk to the number is of the same kind.

What keeping Evolution costs: the open calculation

Free software is not zero cost. Build the calculation with your own numbers: the server (VPS or cloud) running Node, database and Redis; backup; monitoring; and the hours of whoever updates it and investigates when a session drops. Add the monthly server cost to the owner's hourly rate times hours per month and divide by the number of instances.

Compare with R$15 per active number per month. If you run many instances and already have DevOps, the math may favor Evolution. With few instances and nobody dedicated, it usually favors managed. The post on hosted Evolution and WAHA vs a managed API has the full formula.

Endpoint mapping: Evolution API to ZapZap

The Evolution column comes from the official documentation (docs.evolutionfoundation.com.br, 10/27/2026). Different Evolution versions use different formats, so check yours.

ActionEvolution APIZapZap
Authenticationapikey header (global or instance key)x-api-key and x-api-secret
Send textPOST /message/sendText/{instanceName}, with number and textMessage.textPOST /api/v1/{instanceId}/send/text, with number and text
Send filemedia endpoints per typePOST /api/v1/{instanceId}/send/media with type, file, text and docName
Check numbercheck Evolution's documentationPOST /api/v1/{instanceId}/chat/check with numbers
EventsMESSAGES_UPSERT, MESSAGES_UPDATE, CONNECTION_UPDATE and others, per instancemessages, messages_update, connection and others, in PUT /api/v1/instances/{id}/webhook
ConnectQR code or pairing code on the instanceQR code in instance QR or pairing code in connect

How to change sending and the webhook

Sending changes in URL, headers and body shape: on Evolution the text sits inside a textMessage object; on ZapZap it is the text field at the top. Keep a single send function and change only its inside.

On the webhook, Evolution sends the event name in capitals (for example MESSAGES_UPSERT); ZapZap sends event in lowercase (messages) inside an envelope with data.message. Write an adapter and turn on only the messages event on ZapZap, plus messages_update if you use delivery status.

Node.js: envio e adaptador

// ANTES: Evolution API
// POST {EVOLUTION_URL}/message/sendText/{instancia}  header: apikey
// body: { number: "5511999999999", textMessage: { text: "Olá!" } }

// DEPOIS: ZapZap
export async function enviarWhatsApp(numero, texto) {
  const r = await fetch(
    "https://api.zapzapapi.com/api/v1/" + process.env.ZAPZAP_INSTANCE_ID + "/send/text",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-api-key": process.env.ZAPZAP_API_KEY,
        "x-api-secret": process.env.ZAPZAP_API_SECRET,
      },
      body: JSON.stringify({ number: numero, text: texto }),
      signal: AbortSignal.timeout(15000),
    }
  );
  if (!r.ok) throw new Error("ZapZap " + r.status + " " + (await r.text()));
  return r.json();
}

export function deZapZap(evento) {
  const m = evento?.data?.message;
  if (evento?.event !== "messages" || !m || m.fromMe) return null;
  return { telefone: String(m.chatid || "").replace(/\D/g, ""), texto: m.text || "" };
}

How to move the number and a cutover checklist

Create the instance on ZapZap (Create Instance) and connect the number by QR code. Messages and contacts stored in your Evolution database remain yours: export them before shutting the server down. Do not keep the same number connected on both at once.

Checklist: 1) create the account and test with a number of your own; 2) swap the send function; 3) point the webhook at the adapter and validate the signature (guide); 4) export whatever you want to keep from Evolution; 5) cut over at a calm hour; 6) shut the old server down only after a few stable days.

When to stay on Evolution

Stay on Evolution if you have DevOps and want the code and the data inside your environment, if you run many instances and the server math works in your favor, or if you depend on an integration specific to it. See also the Evolution API vs ZapZap comparison. If you need a channel sanctioned by Meta, the option is the official API.

Quick summary

  • The code change is small: send URL and headers and a webhook adapter.
  • Free software has server, update and time costs: do the math with your own numbers.
  • Both are unofficial; the risk to the number is of the same kind.
  • Export the data you want to keep before shutting the Evolution server down.

Also read

Frequently asked questions

Does my Evolution data move to ZapZap?

Not automatically. Evolution keeps data in your database; export what you need. ZapZap starts with an empty instance connected by QR code.

Does ZapZap use Baileys like Evolution?

We do not publish implementation details as a selection criterion. From the user's side, the connection is by QR code, like WhatsApp Web, and the risk of an unofficial solution exists on both.

Can I migrate gradually?

Yes: migrate one instance at a time, starting with a lower-risk one, and keep the send function configurable per instance during the transition.

Does ZapZap guarantee the number will not be banned?

No. No unofficial API can guarantee that. Automatic delay and typing reduce the risk, but opt-in, pace and a clean list remain on you.

Compare in practice

Create the account, connect a test number and run the endpoint mapping. R$15 per active number per month, no per-message fee.