• Home
  • Blog
  • Evolution API: The Open-Source WhatsApp Gateway, Explained
Guides
10 min read May 24, 2026

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.

Key takeaways
  • 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:

YAML
# 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:

BASH
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.

BASH
# 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.

BASH
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:

JAVASCRIPT
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.

ConsiderationEvolution APIRaw Baileys
InterfaceREST + webhooks, language-agnosticNode.js library, you write the code
Multi-instanceBuilt in, isolated per numberBuild it yourself
InfrastructureNeeds PostgreSQL/MySQL + RedisMinimal; bring your own storage
IntegrationsChatwoot, Typebot, queues, S3 out of the boxDIY
Protocol controlAbstracted awayFull, fine-grained access to events
UIEvolution Manager availableNone
Best forTeams, SaaS, multi-tenant opsEmbedded/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

Need read-only WhatsApp data without the ban risk?

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

Sources & further reading

Related

More from the blog

Written by
Eduardo Airaudo

Developer and founder of the WhatsApp Profile API. Building WhatsApp tooling and APIs since 2022.

What Our Users Say

Real reviews from our satisfied customers

4.5/5 (170 reviews)