Evolution API is an open-source REST server for WhatsApp that you run yourself. It is one of the most searched names in this space for good reason: it is free to run, it speaks both a linked-device connection and the official Cloud API, and it plugs into a long list of chat and automation tools. This page is for the team that has it running, or is about to, and wants to know what a hosted API changes.
- Advantage: A residential proxy per number is included, sticky in the country and city you pick.
- Advantage: No servers, upgrades or on-call for the connection on your side.
- Advantage: Webhooks signed with HMAC-SHA256 and retried at 30s, 2m, 10m, 1h and 6h.
- Advantage:
Idempotency-Keyon sends, a TypeScript SDK and a hosted MCP server.
- Disadvantage: Hosted: messages pass through our infrastructure, not only your network.
- Disadvantage: Linked devices only: no official Cloud API, templates or verified badge.
- Disadvantage: Proxy traffic past the included 0.5 GB a month per number costs $0.99 per GB.
- Disadvantage: Chatwoot, Typebot and similar tools are yours to connect through webhooks.
- Advantage: Open source and free to run on your own servers.
- Advantage: Messages, media and session keys stay on machines you control.
- Advantage: A linked device and the official Cloud API behind one API.
- Advantage: Chatwoot, Typebot, n8n and queue connectors are built in.
- Disadvantage: You buy, place and replace the residential proxies yourself.
- Disadvantage: Pacing, reconnect alerts and upgrades are yours to build and run.
- Disadvantage: The license adds a logo and usage-notice condition to Apache 2.0.
- Disadvantage: Webhook signing is not described on its webhooks docs page.
#What Evolution API is
Evolution API is a Node.js and TypeScript server, maintained by the Evolution Foundation, that exposes WhatsApp over HTTP. It started as a fork of CodeChat, and its linked-device connection is built on Baileys, the open-source library that speaks the WhatsApp Web protocol.
A few facts worth knowing before you compare anything:
- Two connection modes. An instance can be a linked device (
WHATSAPP-BAILEYS) or a number on the official Cloud API (WHATSAPP-BUSINESS), chosen when you create it. - Many integrations. Typebot, Chatwoot, OpenAI, Dify, Flowise, n8n and others connect to an instance, and events can go out by webhook, WebSocket, RabbitMQ, SQS, Kafka, NATS or Pusher.
- The license. The code is Apache 2.0 with added conditions in the LICENSE file: keep the logo and copyright in its console, and show a notice in your system that it uses Evolution API, or buy a commercial license. Read the file yourself if you ship it inside a product.
- Activation. The docs say that from version 2.4.0 a free license activation runs on first access, and the server then sends periodic heartbeats with its version, aggregate counts and IP. The latest stable release when we checked was 2.3.7, with 2.4.0 in release candidates.
#Who should keep running it
If you already operate servers, Evolution API is a reasonable choice, and several situations favour it over any hosted service.
- Your data cannot leave your network. Messages, media and session keys stay on machines you control. No hosted provider can match that.
- You need the integrations. Chatwoot, Typebot and the queue connectors are built in. wuapi has webhooks and a REST API, so a Chatwoot inbox is something you would wire up yourself.
- You want both connection modes behind one API. wuapi is linked-device only. If part of your traffic must go through the official Cloud API, Evolution API covers both.
- Your volume is large and your ops team is cheap. At hundreds of numbers, a flat server bill beats any per-number price, as long as someone owns the proxies and the on-call.
If one of those is you, keep it. The rest of this page is for the team whose real cost is the running, not the license.
#What running it actually takes
The server is the easy part. The repository's docker-compose file brings up four containers: the API, its web manager, PostgreSQL and Redis. That gets you a working instance in an afternoon. What takes longer is everything that decides whether the numbers stay connected.
A proxy for every number. Evolution API lets you set a proxy per instance with POST /proxy/set/{instance}, over HTTP, HTTPS or SOCKS. It does not supply one. You choose a provider, buy residential IPs in the right countries, keep each number on the same exit, and notice when an exit dies. A number that reconnects from a datacenter address, or from a new country every day, is a number that draws attention. Why WhatsApp bans numbers goes through the signals.
Pacing. A linked device sends as fast as you call it. If your product ever writes first to people, you need a per-number rate, a lower one for contacts who never wrote to you, and ideally a typing indicator before each message. That is a queue you build and tune.
Upgrades. Breaking changes arrive with WhatsApp protocol changes, and you schedule the upgrade, the migration and the rollback. Sessions live in your database and on the instance volume, so both need backups.
Reconnects and alerts. Linked sessions drop and come back all day. You decide which drops are noise and which one means a phone logged out, and you page someone for the second kind.
#Where wuapi is different
wuapi is a hosted API for the same linked-device model: each number is a device linked by QR or pairing code, the way WhatsApp Web links. The difference is what comes attached to each number.
- A residential exit per number, included. You pass
proxyLocationwhen you create the account, pick from 134 countries on the proxy locations page, and the number keeps a sticky exit there. If the proxy is down, the account waits offline. It never falls back to a datacenter IP. - Pacing you can turn on per number.
messagesPerMinute,firstContactPerMinuteand a typing indicator, set withPATCH /v1/accounts/{accountId}. They are off by default, so replies go out at once; we recommend12a minute,5to new contacts and typing on for any sending that starts with you. Keep your number healthy explains when. - Webhooks signed and retried. Every delivery carries
Wuapi-Signature: t=<unix>,v1=<hex>, an HMAC-SHA256 over the timestamp and the raw body, and a failed one is retried at 30s, 2m, 10m, 1h and 6h, six attempts in total. - Idempotent sends. An
Idempotency-Keyon anyPOSTis remembered for24h, so a retry from your queue never sends twice. - A typed contract. An OpenAPI 3.1 file, the
@wuapidev/sdkTypeScript package, and an MCP server for Claude, Cursor and other agents. - Projects. One organization holds many projects, each with its own accounts, keys, webhooks and usage, so an agency can keep customers apart.
Nothing here makes a number safe from WhatsApp's own decisions. A proxy removes a network signal. What you send, and how people react to it, is still yours.
#What ten numbers cost each way
Take ten linked numbers in one country, a mix of support and order updates.
On Evolution API, the software is free and the bill has three lines. A server, which is small. A residential proxy per number, which is the line that grows: providers sell by the gigabyte or by the IP, and a number that also sends and receives media uses more than a text-only one. And the time of whoever upgrades the server, watches the numbers and answers the page when one drops at night. The third line is the one teams leave out of the spreadsheet.
On wuapi, ten numbers cost $46.50 a month: $6 for the first and $4.50 for each of the other nine. The proxies are part of that price, with 5 GB of traffic a month pooled across the ten, and anything past it is billed at $0.99 per GB. There is no server line and no on-call line for the connection itself. You still own your webhook endpoint and what your product does with the messages.
Which one is cheaper depends almost entirely on the third line. If someone on your team already runs servers at night, self-hosting wins. If not, count the hours.
#Side by side
| Evolution API | wuapi | |
|---|---|---|
| what it is | open-source server you run | hosted API |
| price | free to run; your servers and proxies | $6 first number, $4.50 each to 50, $3.50 after |
| free plan | free to self-host | 1 number, 2,000 messages, 0.5 GB proxy a month |
| hosting | Docker, PostgreSQL or MySQL, Redis | none on your side |
| connection modes | linked device and official Cloud API | linked device only |
| residential proxy per number | bring your own, set per instance | included, sticky, 0.5 GB a month per number |
| proxy traffic past the allowance | your provider's price | $0.99 per GB |
| pacing and typing | build it yourself | per number, opt-in, 12 a minute recommended |
| signed webhooks | optional JWT header in the code | HMAC-SHA256 over timestamp and raw body |
| webhook retries | exponential, configured by env vars | 30s, 2m, 10m, 1h, 6h |
| idempotent sends | not documented | Idempotency-Key, 24 hours |
| typed SDK and OpenAPI | OpenAPI files, a Python client | OpenAPI 3.1, TypeScript SDK |
| MCP server | none published by the team | local and hosted |
| multi-tenant | instances on one server | projects with their own keys and usage |
| chat and bot integrations | Chatwoot, Typebot, n8n and more built in | webhooks and REST |
#Moving from Evolution API
The concepts line up closely, so a move is mostly renaming.
| Evolution API | wuapi |
|---|---|
| instance | account |
apikey header | Authorization: Bearer wu_live_... |
POST /instance/create | POST /v1/accounts with proxyLocation |
GET /instance/connect/{instance} | GET /v1/accounts/{accountId}, read qrCodeUrl |
POST /message/sendText/{instance} | POST /v1/messages with accountId, to, text |
POST /webhook/set/{instance} | POST /v1/webhook-endpoints with url, events |
POST /proxy/set/{instance} | nothing to do; the exit comes with the account |
MESSAGES_UPSERT | message.received |
CONNECTION_UPDATE | account.connected, account.disconnected |
QRCODE_UPDATED | account.qr_code_issued |
A send, before and after:
// Evolution API
await fetch(`${EVOLUTION_URL}/message/sendText/support-line`, {
method: "POST",
headers: { apikey: EVOLUTION_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ number: "5511999999999", text: "Your order has shipped." }),
})
// wuapi
import { Wuapi } from "@wuapidev/sdk"
const wuapi = new Wuapi({ apiKey: process.env.WUAPI_API_KEY })
await wuapi.messages.send({ accountId, to: "+5511999999999", text: "Your order has shipped." })Three things to plan for:
- Every number links again. A session cannot be exported from one server to another, so each phone scans a new QR code or types a pairing code. Tell the number's owner before you start.
- Webhook verification changes. Replace whatever check you had with the signature check in the docs, and handle events idempotently by
id, because a delivery can arrive twice. - History does not come across. Messages you stored in your own database stay yours. After linking, WhatsApp sends the new device the amount of history it decides.
The Free plan lets you move one number and run it next to your server before you move the rest.
#Questions people ask
Is there a hosted version of Evolution API?
The Evolution Foundation lists hosted cloud and support as its commercial offer but publishes no prices, and its docs point to a partner VPS with Evolution API preinstalled. wuapi is a separate hosted API for linked numbers, with its own prices on the pricing page.
Is Evolution API free for commercial use?
The code is Apache 2.0 with added conditions: keep the logo and copyright in its console, and show a notice that your system uses Evolution API, or buy a commercial license. Read the LICENSE file in the repository before you ship it in a product.
Does wuapi support the official Cloud API like Evolution API does?
No. wuapi links numbers as devices only. If you need approved templates or the official Cloud API for part of your traffic, keep a Cloud API provider for that part and use wuapi for the linked numbers.
Do I need my own proxies with wuapi?
No. Every account gets a residential proxy with a sticky exit in the country and city you choose, and 0.5 GB of traffic a month per paid number is included. Past that, traffic costs $0.99 per GB.
Can I move my Evolution API numbers without scanning again?
No. A linked session cannot be exported between servers, so each number links again with a QR code or a pairing code. Plan it as a short, announced step for each phone owner.