Model or dataset
evolution-foundation/evolution-api avatar
evolution-foundation/evolution-api

Evolution API: a self-hosted WhatsApp REST API with Baileys and Cloud API behind one interface

Evolution API is an open-source WhatsApp integration API

9,744 stars7,320 forksTypeScriptNOASSERTION

At a glance

What is it?
Evolution API is an open-source TypeScript server that exposes WhatsApp over HTTP, speaking either the Baileys web protocol or Meta's official Cloud API, with pluggable queues, storage and chatbot integrations. It is a good fit when you need to own the messaging layer; it is the wrong tool when you want Meta to own the compliance burden for you.
Who is it for?
Adopt Evolution API if you need a self-hosted HTTP layer over WhatsApp and are prepared to run PostgreSQL, Redis and the API yourself, or to use the official Docker image. Do not adopt it if you need Meta to carry the compliance and deliverability burden for you, or if you cannot tolerate a Baileys connection that depends on the WhatsApp Web protocol.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 79 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Evolution API solves for teams that need WhatsApp in their own stack

Sending and receiving WhatsApp messages from your own application means dealing with a protocol that was never designed to be driven by third-party servers. There are two ways in: the unofficial WhatsApp Web route, which the Baileys library implements, and Meta's official Cloud API. They have different authentication, different message shapes and different failure modes. Evolution API's pitch is that you write against one REST surface and choose the channel underneath.

The audience is fairly specific. It is backend and integration engineers building service bots, multi-service chat desks or CRM connectors who want the messaging transport to live on their own infrastructure. The README names the use cases: multi-service chats, service bots and WhatsApp-integrated systems for the Baileys path, and higher-volume business messaging for the Cloud API path. It is not a hosted product you sign up for. The README documents a Docker image and an npm-based install, and the repository ships docker-compose.yaml, a Dockerfile and local_install.sh.

The project began as a WhatsApp controller API based on CodeChat, which itself implemented Baileys. The README states this lineage directly and credits CodeChat. That history explains the shape of the codebase: a single Express service with a large set of optional integrations bolted onto the side rather than a set of small composable packages.

How the request path and the integration layers fit together

The README gives an architecture diagram worth reading literally. A client or CRM calls Evolution API. From there the server fans out into four kinds of integration: channel integrations (Baileys or Cloud API), chatbot integrations (Typebot, Chatwoot, OpenAI, Dify, Flowise, N8N), event integrations (WebSocket, RabbitMQ, SQS, NATS, Pusher) and storage integrations (S3, MinIO).

That is the whole design. There is no separate broker process you must run, and no sidecar. The API process holds the WhatsApp connection, writes to PostgreSQL or MySQL through Prisma, and publishes events to whichever transport you configured. Media is either stored locally or pushed to S3 or MinIO, and the README notes that media is downloaded from WhatsApp automatically, with optional audio transcription through OpenAI.

Authentication has three distinct layers, and conflating them is a common source of confusion. There is API key authentication via an apikey header for calls into the REST API. There are instance-specific tokens for the WhatsApp connection itself. And there is webhook signature validation for traffic coming back from external integrations. A deployment that only sets the first will still have instances that cannot connect.

Multi-tenancy is handled through instances, and the event layer is configurable per instance. The .env.example exposes EVENT_EMITTER_MAX_LISTENERS with a default of 50, which is a hint about the intended scale per process: this is a Node event emitter underneath, not a distributed bus. The DEL_INSTANCE setting controls how long an instance stays in memory after losing its connection, defaulting to five minutes, and can be set to false to disable expiry entirely.

Installing Evolution API with Docker or from source

The README lists Node.js 20+, PostgreSQL or MySQL, and Redis (recommended for caching) as prerequisites. Docker is the shorter path. The README gives a single-container example that pulls the published image and passes your environment file:

bash
docker pull evoapicloud/evolution-api:latest
docker run -p 8080:8080 --env-file .env evoapicloud/evolution-api:latest

The container listens on 8080, which is also the default SERVER_PORT in .env.example. For anything beyond a smoke test, the repository's docker-compose.yaml is the better starting point because it also defines Redis, PostgreSQL 15 and a separate frontend container. Note that the compose file binds the API to 127.0.0.1:8080 rather than exposing it on all interfaces, and it references an external dokploy-network, which will fail to start unless that network already exists.

bash
docker compose up -d

If you install from source instead, the README walks through cloning, installing dependencies and copying the environment template:

bash
git clone [email protected]:evolution-foundation/evolution-api.git
cd evolution-api
npm install
cp .env.example .env

Database setup is provider-driven. You set DATABASE_PROVIDER and then run the Prisma scripts, which use runWithProvider.js to swap in the right schema and migrations:

bash
export DATABASE_PROVIDER=postgresql
npm run db:generate
npm run db:deploy

After that, npm run dev:server starts the server with hot reload, and the production path is npm run build followed by npm run start:prod. Before any of this, open .env and set DATABASE_CONNECTION_URI, the Redis settings and your API key. The README does not document a rollback procedure for npm run db:deploy, and the script itself removes and replaces the prisma/migrations directory, so treat the first deploy against a real database as a one-way step until you have your own backup in place.

The Baileys channel is the part that will wake you up at night

The README is unusually candid about this: the Baileys connection relies on the web version of WhatsApp and, in its own words, may have limitations compared to official APIs. That sentence is doing a lot of work. Baileys is a reverse-engineered client for WhatsApp Web, so your instance's stability is coupled to a protocol Meta controls and can change without notice. The README does not document a reconnection policy, a ban-risk model or a migration path from Baileys to Cloud API for an existing instance.

The Cloud API path is the sanctioned alternative, but it is not a drop-in swap. The README states it requires compliance with Meta's policies and may incur per-message costs. So the choice is not free versus paid. It is a trade between operational risk on the Baileys side and policy plus billing exposure on the Cloud API side, and the README does not pretend otherwise.

There is a second boundary worth naming: the licence. The repository's LICENSE file is not a standard identifier. The metadata reports NOASSERTION, while the README badge points at Apache 2.0. The repository also ships a separate TRADEMARKS.md. If you are embedding this in a commercial product, read both files rather than trusting the badge.

Telemetry is on by default. .env.example sets TELEMETRY_ENABLED=true, and the README describes the payload as anonymous data covering routes used, most accessed routes and API version, with no sensitive or personal data collected. You can turn it off with that variable. Prometheus metrics are a separate switch, PROMETHEUS_METRICS, defaulting to false, and when enabled they are protected by METRICS_USER, METRICS_PASSWORD and METRICS_ALLOWED_IPS.

Evolution API against the official Cloud API SDK route

The most direct alternative is to skip the intermediary and call Meta's Cloud API from your application, either directly over HTTP or through an SDK. The difference is architectural, not cosmetic. With the official route, Meta terminates the WhatsApp session, handles the protocol, and enforces its own policy layer; you write against a stable, documented contract and pay per message. With Evolution API on Baileys, you own the session, the reconnect logic, the media download and the storage, and you pay for the server.

Evolution API's value is concentrated in what sits above the channel: the instance model, the webhook and event fan-out, the Chatwoot and Typebot integrations, and the fact that you can switch channels without rewriting your callers. If you do not need those, the abstraction is a layer of operational surface you are maintaining for no reason. A small team sending transactional messages through the official Cloud API will find less to run and less to break.

If you do need the integration surface, the honest comparison is against assembling it yourself: Baileys plus your own Express routes plus your own queue publisher plus your own media store. That is essentially what this project is, and the repository layout reflects it. The trade you are making is accepting the project's opinions about instances, environment variables and Prisma schemas in exchange for not writing them.

Maintenance status, release cadence and what upgrading actually costs

The repository is not archived, and the last push was on 2026-07-14. The most recent releases listed are 2.4.0-rc2 on 2026-05-17 and 2.4.0-rc1 on 2026-05-06, both release candidates, with the last stable release being 2.3.7 on 2025-12-05. The package.json in the repository still declares version 2.3.7. If you need a stable tag rather than a candidate, 2.3.7 is what the repository shows.

Upgrade cost is dominated by the database layer. The db:deploy script deletes prisma/migrations and copies the provider-specific migrations directory in its place before running prisma migrate deploy. That means the migration history in your working tree is regenerated from the repository each time rather than being an append-only local record. The Dockerfile runs the same deploy script on container start, so a new image tag can migrate your database as part of boot. The README does not document a rollback path for either case.

There is also a Windows-specific variant, db:deploy:win, which uses xcopy instead of cp. If your team is mixed-platform, the two scripts can diverge in behaviour and only one of them is likely to be exercised in CI.

On licensing: the README badge says Apache 2.0, the repository metadata says NOASSERTION, and TRADEMARKS.md exists alongside LICENSE and NOTICE. Those three signals do not agree, and the difference matters most for trademark use and for redistribution, not for running the server internally. Read the files in the repository before you rely on any summary, including this one.

Editorial conclusion

Adopt Evolution API if you need a self-hosted HTTP layer over WhatsApp and are prepared to run PostgreSQL, Redis and the API yourself, or to use the official Docker image. Do not adopt it if you need Meta to carry the compliance and deliverability burden for you, or if you cannot tolerate a Baileys connection that depends on the WhatsApp Web protocol. Before committing, verify three things in the repository itself: the terms in LICENSE and TRADEMARKS.md, the exact DATABASE_PROVIDER value your deployment will use, and whether TELEMETRY_ENABLED should be set to false in your .env.

Frequently asked questions

Is Evolution API free?

The software itself is open source and the README describes the Baileys-based connection as a free API. The Cloud API path is different: the README states it requires compliance with Meta's policies and may incur per-message costs, so the channel you choose determines whether you pay per message.

Is Evolution API self-hosted?

Yes. The README documents installing from source with Node.js 20+, PostgreSQL or MySQL and Redis, and it also publishes a Docker image at evoapicloud/evolution-api. The repository ships docker-compose.yaml and a Dockerfile, so the API runs on infrastructure you control.

Is Evolution API open source?

The README carries an Apache 2.0 badge and the repository ships LICENSE, NOTICE and TRADEMARKS.md files. The repository metadata reports the licence as NOASSERTION, so read the licence files themselves rather than relying on the badge.

How to install Evolution API with Docker?

The README gives docker pull evoapicloud/evolution-api:latest followed by docker run -p 8080:8080 --env-file .env. For a full stack, the repository's docker-compose.yaml also defines Redis, PostgreSQL 15 and a frontend container, and it binds the API to 127.0.0.1:8080.

What is the latest version of Evolution API?

The most recent releases listed are 2.4.0-rc2 on 2026-05-17 and 2.4.0-rc1 on 2026-05-06, both release candidates. The last stable release shown is 2.3.7 on 2025-12-05, which is also the version declared in the repository's package.json.

Is Evolution API safe?

The README states the Baileys connection relies on the web version of WhatsApp and may have limitations compared to official APIs, while the Cloud API path requires compliance with Meta's policies. The project also collects anonymous telemetry by default, which .env.example lets you disable with TELEMETRY_ENABLED=false. The repository does not document a security audit.

Official sources

  1. evolution-foundation/evolution-api on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/evolution-foundation-evolution-api.svg)](https://hysenlabs.com/projects/evolution-foundation-evolution-api)