evolution-go: a self-hosted WhatsApp API with licence activation and a manager UI
Evolution API / Evolution Go is an open-source WhatsApp integration API
At a glance
- What is it?
- Evolution Go is a WhatsApp integration API written in Go that pairs devices by QR code, exposes REST and Swagger endpoints and pushes events over WebSocket, webhooks, AMQP and NATS. Running it is straightforward with Docker, but the service refuses API traffic until a licence is activated and it sends anonymous telemetry by default.
- Who is it for?
- Adopt evolution-go if you want to run the WhatsApp connection, the API and the event pipeline on infrastructure you control, and if you are comfortable satisfying the licence registration and heartbeat flow. Do not choose it for a small script that only needs to send a message, and treat the custom licence and the automatic telemetry as things to review before deployment rather than after.
- 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 22 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A WhatsApp server you run yourself, built on whatsmeow
evolution-go is a WhatsApp integration API written in Go and published by Evolution Foundation as one of the messaging engines in its ecosystem. The mechanism underneath is worth stating plainly: it does not wrap a hosted platform, it holds the WhatsApp session itself through the whatsmeow library and exposes that session over HTTP. Around that core sit the parts a product team actually needs, namely REST endpoints with Swagger documentation, a set of event channels, media handling, optional message persistence, a QR pairing flow, a manager interface, and a Docker configuration. The service is also used as a WhatsApp provider by the Evo CRM Community project and by other software in the same ecosystem, so it is written to be embedded rather than only to be browsed. The tech stack is Gin for HTTP, PostgreSQL with GORM for persistence, MinIO or S3 for object storage, and RabbitMQ or NATS for queuing.
The API answers 503 until a licence is activated
The first thing to understand is that evolution-go is not open source in the free-to-run sense. It requires a licence to operate, and the activation flow is enforced by the server rather than by a prompt. On first run, API endpoints return 503 until activation is complete. You open the Manager at http://localhost:8080/manager/login, enter your API URL and your GLOBAL_API_KEY, and complete the license registration flow. After that the API is fully operational. Status is kept in the database in the runtime_configs table, and the service sends heartbeats periodically to maintain activation. The configuration file also documents a headless path: setting EVOLUTION_OPERATOR_EMAIL to the address used in a first manual registration makes the service call /v1/register/auto on startup and skip the browser flow, falling back to manual registration if the email is not registered yet. That is a meaningful detail for container deployments, where a manager UI click is not always practical.
Starting the service with make docker-build and make docker-run
The Docker route is the one the project recommends. You clone the repository, enter the directory and build and run the image with the Makefile targets:
git clone https://github.com/evolution-foundation/evolution-go.git
cd evolution-go
make docker-build
make docker-runThe container build compiles the Go binary from cmd/evolution-go with CGO enabled, because the media stack includes libjpeg-turbo and libwebp, and the final image adds ffmpeg and poppler-utils, the latter providing pdftoppm to rasterise the first page of a PDF for document thumbnails in the media endpoint. A prebuilt image is also published on Docker Hub as evoapicloud/evolution-go. For local development the project expects a Go toolchain and a database, and the sequence is:
git clone https://github.com/evolution-foundation/evolution-go.git
cd evolution-go
# Setup, configure and run
make setup
cp .env.example .env
make devmake dev runs the application in development mode, and the project points at make help and COMMANDS.md for the full list of targets, which include build, test, swagger, migrate-up, migrate-down and logs.
Two databases, one API key, and the variables that matter
Configuration is a .env file, and the example in the documentation is a good map of the surface:
# Server
SERVER_PORT=8080
CLIENT_NAME=evolution
# Security
GLOBAL_API_KEY=your-secure-api-key-here
# Database
POSTGRES_AUTH_DB=postgresql://postgres:password@localhost:5432/evogo_auth?sslmode=disable
POSTGRES_USERS_DB=postgresql://postgres:password@localhost:5432/evogo_users?sslmode=disable
DATABASE_SAVE_MESSAGES=false
# Logging
WADEBUG=DEBUG
LOGTYPE=consoleTwo PostgreSQL connections are required, one named evogo_auth and one named evogo_users, and GLOBAL_API_KEY has no default, so a container that starts without it comes up with no usable API. DATABASE_SAVE_MESSAGES defaults to false, which turns off message persistence entirely. The example file also carries WADEBUG and LOGTYPE, CONNECT_ON_STARTUP, an AMQP URL with a global enable flag, WEBHOOK_URL, proxy settings where PROXY_PROTOCOL can be http, https or socks5, and MinIO settings, along with a comment block explaining that PASSKEY_PUBLIC_URL must be a base URL reachable by the browser where WhatsApp Web opens, so localhost will not do when the browser runs on another machine.
Instances, QR pairing and the endpoints a client touches
The public surface is small enough to read in one screen. Instances are created with POST /instance/create, paired by fetching GET /instance/{name}/qrcode, and their state read through GET /instance/{name}/status. Messages go out through POST /message/sendText and POST /message/sendMedia, and an instance is removed with DELETE /instance/{name}. Swagger UI is served at http://localhost:8080/swagger/index.html, which is the fastest way to see the full route set rather than only the headline endpoints. Pairing is QR based and built in, and the repository carries a passkey-helper directory plus documentation on WebAuthn pairing for accounts that ask for a passkey when linking a device. Internally the code is organised in pkg/ with separate packages for core, instance, message, sendMessage, routes, middleware, config, events and storage, which keeps licensing and middleware concerns out of the message path.
One event pipeline with four delivery styles
Events are handled by the pkg/events package, described as event producers covering AMQP, NATS, webhook and WebSocket. That design choice matters more than it first appears, because a WhatsApp integration usually has to feed several consumers at once: a bot runtime, a CRM, a database writer and a dashboard. The AMQP variables in the example configuration include AMQP_URL and a separate AMQP_GLOBAL_ENABLED flag, so a deployment can turn the global queue on or off independently of per-instance routing. Webhooks are configured with WEBHOOK_URL, and the example file additionally sets WEBHOOK_FILES=true. The WebSocket path uses gorilla/websocket from go.mod, and the swagger tooling is the swaggo stack. Storage for media is handled by pkg/storage against MinIO or S3, with the client library minio-go in the dependency list, and the repository also depends on lib/pq, gorm.io/driver/postgres and modernc.org/sqlite for data access.
The trade-offs, the licence and the release gap
Several things deserve a plain assessment. The licence is the first constraint: evolution-go will not serve API traffic without activation and periodic heartbeats, which means an external service is part of your runtime dependency, and the licence field on the repository reports a custom licence that GitHub cannot classify, while the README displays an Apache 2.0 badge. Read the LICENSE file before deploying, since the two are not obviously the same thing, and treat this as a compliance question for your own counsel rather than a settled detail. Second, the project collects anonymous telemetry, described as routes used and API version, and states that no sensitive or personal data is collected, but it is on by default and the README does not describe a switch for it. Third, the release history is thin: the newest tagged release is v0.7.2 on 2026-07-03, preceded by v0.7.1 the same day and v0.7.0 on 2026-04-17, while the last push was on 2026-10-01, so the repository has moved well past the last tag. A deployment pinned to a tag is not running the current code, and the CHANGELOG.md is where the differences live.
Running it yourself versus hosting the same binary elsewhere
The alternative the project itself points at is hosted infrastructure rather than a different engine: it offers an Evolution Go VPS through a HostGator partnership, where the container, the PostgreSQL instances and the MinIO storage are somebody else's problem. The difference in approach is straightforward. Running the image on your own host means you choose the machine, the disk and the network path, and you own the upgrade path, the two database migrations and the licence activation. A hosted VPS keeps the same software and the same API surface but moves the operational load, and it adds a vendor between you and the running service, including a vendor who must still be able to complete the licence registration. Whichever route you take, the endpoints, the environment variables and the activation flow are the same, so the decision is about who carries the operational work, not about what the API does.
Editorial conclusion
Adopt evolution-go if you want to run the WhatsApp connection, the API and the event pipeline on infrastructure you control, and if you are comfortable satisfying the licence registration and heartbeat flow. Do not choose it for a small script that only needs to send a message, and treat the custom licence and the automatic telemetry as things to review before deployment rather than after. Verify first that the endpoints your client calls exist in the Swagger UI at /swagger/index.html, that your GLOBAL_API_KEY and the two PostgreSQL databases are reachable, and that the release you deploy matches the documented behaviour, because the last push was on 2026-10-01 while the newest tagged release is v0.7.2 from 2026-07-03.
Frequently asked questions
Why do the evolution-go API endpoints return 503 on first run?
evolution-go requires a licence to operate, and endpoints return 503 until activation is complete. You open the Manager at http://localhost:8080/manager/login, enter your API URL and GLOBAL_API_KEY, and complete the license registration flow. Setting EVOLUTION_OPERATOR_EMAIL enables headless auto-activation on startup instead.
How do I link a WhatsApp account to evolution-go?
Pairing is QR based. You create an instance with POST /instance/create and then fetch GET /instance/{name}/qrcode to get the code to scan. Accounts that require a passkey use a WebAuthn flow, which is why PASSKEY_PUBLIC_URL must point at a base URL the browser can reach.
Which databases and storage does evolution-go need?
The configuration expects two PostgreSQL connections, evogo_auth and evogo_users, through POSTGRES_AUTH_DB and POSTGRES_USERS_DB. Message persistence is controlled by DATABASE_SAVE_MESSAGES, which defaults to false, and media can be stored in MinIO or S3 through the MinIO settings in the environment file.
Can evolution-go deliver events over something other than HTTP responses?
Yes. The events package produces AMQP, NATS, webhook and WebSocket events, configured through AMQP_URL, AMQP_GLOBAL_ENABLED, WEBHOOK_URL and the WebSocket support built on gorilla/websocket. A separate NATS_URL variable is also part of the configuration surface.
Is evolution-go actively released?
The repository is not archived and the last push was on 2026-10-01, but the most recent tagged release is v0.7.2 from 2026-07-03, with v0.7.1 the same day and v0.7.0 on 2026-04-17. The CHANGELOG.md file records the changes between the current code and the last tag.
Official sources
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.
[](https://hysenlabs.com/projects/evolution-foundation-evolution-go)Was this useful?