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
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.
| Action | Evolution API | ZapZap |
|---|---|---|
| Authentication | apikey header (global or instance key) | x-api-key and x-api-secret |
| Send text | POST /message/sendText/{instanceName}, with number and textMessage.text | POST /api/v1/{instanceId}/send/text, with number and text |
| Send file | media endpoints per type | POST /api/v1/{instanceId}/send/media with type, file, text and docName |
| Check number | check Evolution's documentation | POST /api/v1/{instanceId}/chat/check with numbers |
| Events | MESSAGES_UPSERT, MESSAGES_UPDATE, CONNECTION_UPDATE and others, per instance | messages, messages_update, connection and others, in PUT /api/v1/instances/{id}/webhook |
| Connect | QR code or pairing code on the instance | QR 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.
Keep reading
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.
