Evolution API: The Open-Source WhatsApp Gateway, Explained
Evolution API wraps Baileys (and the official Cloud API) in a multi-instance REST gateway with webhooks and integrations. Here's the architecture, Docker setup, and when to use it.
- Evolution API is an open-source TypeScript REST gateway (maintained by the Evolution Foundation) that wraps Baileys and the official WhatsApp Cloud API behind one HTTP interface with webhooks and multi-instance support.
- Run it with Docker (image evoapicloud/evolution-api), backed by PostgreSQL (MySQL is also supported) and Redis; the default port is 8080 and a global API key secures admin operations.
- Send a message with one POST to /message/sendText/{instance} using an apikey header — no socket code required.
- Baileys mode is unofficial and violates WhatsApp's Terms of Service; numbers can be banned without warning. For production volume or compliance, use the official Cloud API connection.
- Choose Evolution API when you want managed multi-instance, integrations, and a UI; choose raw Baileys when you need a minimal footprint and fine-grained protocol control.
What Evolution API actually is
Evolution API is an open-source REST API that turns WhatsApp — and several other messaging channels — into something you can drive over plain HTTP. Instead of writing socket-handling code against a low-level library, you POST JSON to an Evolution API endpoint and a message goes out; events come back to you as webhooks. It is maintained by the Evolution Foundation, written almost entirely in TypeScript (~98%), and runs on Node.js 20+ with Express.
The project began as a WhatsApp controller derived from CodeChat, which itself implemented Baileys (the reverse-engineered WhatsApp Web library). Today it has grown into a multi-tenant gateway with a sizeable community — several thousand GitHub stars (roughly 8.7k as of late 2025) — and an active release cadence. The canonical repository now lives under the evolution-foundation organization; the older EvolutionAPI org URL still resolves and redirects to the same project, so both handles appear in the wild.
Architecture: how the layers fit
Evolution API is best understood as a layered, multi-tenant gateway. Each request passes through clearly separated responsibilities, which is what makes it possible to run dozens of WhatsApp numbers from a single deployment without their configs colliding.
- HTTP layer — Express routes with API-key authentication; this is the REST surface you call.
- Service layer — orchestration and business logic that coordinates instances, messages, and integrations.
- Channel layer — polymorphic connection implementations, so a Baileys connection and a Cloud API connection expose the same interface upstream.
- Integration layer — adapters for Chatwoot, Typebot, Dify, OpenAI, message queues, and webhooks.
- Data layer — persistence (PostgreSQL or MySQL via Prisma), caching (Redis), and media storage (local or S3/MinIO).
The key concept is the instance. An instance is one WhatsApp connection (one number) with its own configuration, chatbots, webhooks, proxy settings, and integrations — fully isolated from every other instance. This multi-instance model is the headline feature: one gateway, many independent numbers, each addressable by name in the URL.
Evolution exposes two connection types behind that channel layer. The first is Baileys — free and unofficial, riding on the WhatsApp Web protocol via the WhiskeySockets/Baileys library. The second is the official WhatsApp Cloud API from Meta, intended for higher volume, Meta-managed reliability and infrastructure, and compliance-sensitive workloads. (Note that the Cloud API is not end-to-end encrypted to your business: Meta terminates the Signal-protocol encryption at its servers and decrypts messages there to route them to you, so it offers encryption in transit and Meta-managed compliance rather than an E2E guarantee.) You pick per instance, which means you can prototype on Baileys and graduate specific numbers to the Cloud API without changing your application code much.
Docker setup (the official method)
Docker is the supported deployment path. Evolution needs a relational database — PostgreSQL is recommended, and MySQL is also supported via Prisma — plus Redis for caching; the container listens on port 8080 by default. The single most important environment variable is AUTHENTICATION_API_KEY — the global admin key that lets you create and delete instances. A companion management UI ships as evoapicloud/evolution-manager.
A minimal docker-compose that brings up the API, Postgres, and Redis together looks like this:
# docker-compose.yml
services:
evolution-api:
image: evoapicloud/evolution-api:latest
restart: always
ports:
- "8080:8080"
environment:
AUTHENTICATION_API_KEY: "change-me-to-a-long-random-secret"
DATABASE_ENABLED: "true"
DATABASE_PROVIDER: "postgresql"
DATABASE_CONNECTION_URI: "postgresql://evo:evo@postgres:5432/evolution"
CACHE_REDIS_ENABLED: "true"
CACHE_REDIS_URI: "redis://redis:6379"
CACHE_REDIS_PREFIX_KEY: "evolution"
depends_on:
- postgres
- redis
volumes:
- evolution_instances:/evolution/instances
postgres:
image: postgres:16-alpine
restart: always
environment:
POSTGRES_USER: evo
POSTGRES_PASSWORD: evo
POSTGRES_DB: evolution
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
restart: always
volumes:
- redis_data:/data
volumes:
evolution_instances:
postgres_data:
redis_data:Bring it up, then confirm the API is alive:
docker compose up -d
# health / version check
curl http://localhost:8080/Creating an instance and connecting a number
Before you can send anything, you create an instance and link a WhatsApp account to it. Creating an instance is an admin operation, so it uses the global API key. The response includes a per-instance API key (the hash) that you use for all subsequent messaging on that instance — a clean separation of admin power from day-to-day sending.
# Create an instance (uses the GLOBAL apikey)
curl -X POST http://localhost:8080/instance/create \
-H "Content-Type: application/json" \
-H "apikey: change-me-to-a-long-random-secret" \
-d '{
"instanceName": "sales-bot",
"integration": "WHATSAPP-BAILEYS",
"qrcode": true
}'For a Baileys instance, the response contains a QR code you scan from the target phone's WhatsApp (Linked Devices). After it connects, the instance is ready. To switch to Meta's official channel instead, set integration to WHATSAPP-BUSINESS and supply your Cloud API credentials rather than scanning a QR — the rest of your request shapes stay the same.
Sending a message via REST
This is where the gateway pays off. Sending a text is a single POST to /message/sendText/{instance}, authenticated with the apikey header. No event loop, no reconnection logic, no protocol details — just JSON in, message out.
curl -X POST http://localhost:8080/message/sendText/sales-bot \
-H "Content-Type: application/json" \
-H "apikey: <instance-or-global-api-key>" \
-d '{
"number": "5511999999999",
"text": "Hello from Evolution API!",
"delay": 1200,
"linkPreview": true
}'The number is in international format without a plus sign. Optional fields include delay (a typing-style pause in milliseconds), linkPreview, mentioned, quoted, and mentionsEveryOne. A successful call returns HTTP 201 with the message key — remoteJid, fromMe, and id — plus a timestamp and status, which you can persist to track delivery.
The equivalent in Node.js with fetch:
const res = await fetch(
"http://localhost:8080/message/sendText/sales-bot",
{
method: "POST",
headers: {
"Content-Type": "application/json",
apikey: process.env.EVOLUTION_API_KEY,
},
body: JSON.stringify({
number: "5511999999999",
text: "Hello from Evolution API!",
delay: 1200,
}),
}
);
const data = await res.json();
console.log(res.status, data.key); // 201 { remoteJid, fromMe, id }Webhooks and integrations
Outbound sending is only half the story; the other half is receiving. Evolution delivers events in real time over webhooks. You can configure a webhook per instance — useful when each number belongs to a different tenant — or a single global webhook that receives events from every instance, which is simpler for a centralized worker.
On top of raw webhooks, Evolution ships first-class integrations so you often don't need to build the plumbing yourself:
- Conversation/helpdesk: Chatwoot, Typebot, Dify, OpenAI for AI-assisted replies.
- Message queues and streaming: RabbitMQ, Apache Kafka, Amazon SQS.
- Realtime and storage: Socket.io for live events, Amazon S3 / MinIO for media.
- Automation platforms via webhooks: tools like n8n, Make, and Zapier slot in naturally on top of the event stream.
If you are building a chatbot or a CRM sync, this integration layer is the reason teams reach for Evolution over wiring a library by hand. For a deeper look at the event model itself, see our WhatsApp webhooks guide.
License: open source, but not trademark-free
Evolution API is released under the Apache License 2.0 — but with added brand-protection conditions. The source code is genuinely Apache-2.0 (you can read, modify, and redistribute it), while the Evolution name, logo, and visual identity are trademarks of the Evolution Foundation. Two distinct documents govern the extras: TRADEMARKS.md covers the logo and wordmark and requires that any fork rebrand under a distinct name, while the LICENSE note adds a LOGO/copyright-preservation rule and a usage-notification/activation requirement for the console components.
What this means concretely: Apache-2.0 lets a fork remove the activation requirement, and that is legally permitted. But a fork that does so loses the right to use the Evolution / Evolution API name, logo, and branding (the conditions set out in TRADEMARKS.md). So describe the license honestly — it is Apache-2.0 with brand/trademark-protection conditions, not plain vanilla Apache-2.0. For most users self-hosting the official image, none of this is a blocker; it matters mainly if you intend to rebrand and redistribute.
The Terms of Service reality check
This is the part that no honest guide can skip. Evolution's Baileys connection is unofficial: it automates a WhatsApp account through the WhatsApp Web protocol, which violates WhatsApp's and Meta's Terms of Service. Numbers running in Baileys mode can be banned — unpredictably, with no reliable pattern, and reports of bans increased through 2025. Meta can also change the underlying protocol at any time, breaking connectivity until Baileys is updated upstream.
The Baileys maintainers themselves do not condone ToS-violating use. The sober guidance:
- For production or compliance-sensitive messaging, use Evolution's official WhatsApp Cloud API connection (or Meta's API directly).
- Reserve Baileys mode for prototyping, internal tooling, or genuine accept-the-risk scenarios.
- If you do run Baileys, warm up new numbers gradually, keep healthy reply ratios, avoid robotic timing, and never blast cold contacts.
Evolution API vs. raw Baileys
Both sit on the same protocol, so the choice is about how much you want managed for you versus how much control and minimalism you need.
| Consideration | Evolution API | Raw Baileys |
|---|---|---|
| Interface | REST + webhooks, language-agnostic | Node.js library, you write the code |
| Multi-instance | Built in, isolated per number | Build it yourself |
| Infrastructure | Needs PostgreSQL/MySQL + Redis | Minimal; bring your own storage |
| Integrations | Chatwoot, Typebot, queues, S3 out of the box | DIY |
| Protocol control | Abstracted away | Full, fine-grained access to events |
| UI | Evolution Manager available | None |
| Best for | Teams, SaaS, multi-tenant ops | Embedded/library use, custom bots, lean footprint |
Choose Evolution API when you want multi-instance management, a REST surface, ready integrations, media handling, persistence, and a UI without writing socket code — ideal for teams and SaaS products. Choose raw Baileys when you need protocol-level control, a minimal footprint, custom event handling, or you simply want to avoid the extra database/Redis infra and the brand/activation layer. If you're weighing the wider field, our roundup of open-source WhatsApp libraries and the Baileys deep-dive both add useful context.
Bottom line
Evolution API is one of the most capable open-source WhatsApp gateways available: a clean layered architecture, true multi-instance support, a REST + webhook surface, a strong integration roster, and an active release line (v2.3.x as of late 2025, with v2.3.7 shipping in December 2025). It earns its place when you want managed messaging infrastructure rather than a library to babysit.
Just go in clear-eyed: the free Baileys mode is unofficial and carries real, unpredictable ban risk, the license is Apache-2.0 with trademark conditions, and anything production-grade should lean on the official Cloud API. Match the connection type to your risk tolerance, and Evolution becomes a genuinely productive foundation.
Frequently asked questions
Check if a number is on WhatsApp, fetch public profile pictures and names, and detect business accounts via a hosted API — no linked account, no socket code.
Explore the WhatsApp Profile API