WPPConnect Server puts a REST API in front of WhatsApp Web
Wppconnect Server is a ready-to-use API, just download, install, and start using, simple as that.
At a glance
- What is it?
- WPPConnect Server is a ready to use API for sending and receiving WhatsApp messages, managing contacts and groups, and pairing sessions, built on Express and SocketIO with Chromium doing the actual work under the hood. It ships as a Docker image, as an npm package and as a source tree, and it ships with a management UI bundled inside the image.
- Who is it for?
- Adopt WPPConnect Server when you are building an internal tool that has to talk to WhatsApp and you have an authorised account and a way to reach the API safely. Do not adopt it as a platform for a public service, because the container exposes an authenticated API that drives a logged-in WhatsApp session and the default secret in the compose file is a published string.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day 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 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An API over an automated browser session
WPPConnect Server is a ready to use API, and the mission statement is to provide a ready to use API for communication with WhatsApp. The server is designed to handle the work of sending and receiving messages, managing contacts, creating groups, and much more, while leveraging the power of JavaScript ES6, NodeJS and a RESTful architecture.
The libraries list makes the shape clear. WPPConnect is the client library that drives the browser, Axios is the HTTP client, Bcrypt handles password hashing, Cors and Express are the web layer, Dotenv loads the environment file, Nodemon is the development watcher, SocketIO is the event channel, and S3 is the object storage.
So the server is a Node process that runs a Chromium instance with a logged-in WhatsApp Web session, and it exposes that session over HTTP and over a socket. The API is a thin, well documented layer over a browser automation library, which is why it can offer a feature set this wide without implementing protocol handling of its own.
The implementation is TypeScript, the licence is Apache-2.0, and the last push was on 2026-10-15. The release cadence is very fast, with v2.10.55, v2.10.54 and v2.10.53 all published on 2026-10-14, which tells you the project tracks WhatsApp Web changes closely.
The feature list, and the session model behind it
The features table is ten rows, and the first one is the one everything else depends on.
Multiple sessions, with the ability to open and close a session, to change the profile or username, to send text, image, video and documents, to get the contacts list, to manage products, to receive and send messages, to create a group, to join a group by invite code, and to receive webhooks.
The session model is what makes this different from a script that logs in once. Each session is a separate logged-in browser context with its own token, its own contact list and its own message stream, and the API addresses them by name. That is what a support tool, a notification relay or a back office integration needs, and it is why the token store is a configurable backend rather than a file, since the sessions have to survive a restart of the server.
The webhook row is the integration point for outbound events, and the webhook configuration in the environment file is more elaborate than the rest, with a URL, an allow list of exact destinations, retry attempts, a retry delay and a request timeout, plus a size limit on automatically downloaded media. Those settings are the difference between a webhook that fires reliably and one that takes the notification service down with it, so they are worth reading before the first deployment rather than after the first outage.
The Docker run command, and the four volumes
The Docker image is the recommended route, and the documented run command is the whole deployment in one block.
docker run -d \
--name wppconnect-server \
--restart unless-stopped \
-p 21465:21465 \
-e SECRET_KEY=change-me \
-v wppconnect_tokens:/usr/src/wpp-server/tokens \
-v wppconnect_user_data:/usr/src/wpp-server/userDataDir \
wppconnect/wppconnect-server:latestTwo things in that command matter. The SECRET_KEY is the administrative credential, and the sample value is change-me, which is fine as a reminder and wrong as a configuration. And the named volumes are what make a session survive the container being replaced, the tokens volume holds the session credentials and the userDataDir volume holds the Chromium profile, and if you lose the second one every session has to be paired again.
The image includes Node.js, Chromium and the native dependencies required by WPPConnect, which is why the container is large and why the native dependency list in the source install section is so long.
The image is published on Docker Hub, and the tags follow the GitHub and npm version, with the vX.Y.Z, X.Y.Z, X.Y and X forms, plus latest, and the main, develop and immutable sha- tags. The WPP_SERVER_TAG variable lets you pin a release instead of following latest, and the readme recommends it for the same reason it recommends replacing the secret.
Compose, the health check, and the environment surface
For Docker Compose the instructions are to clone the repository, copy the example environment file and edit the secret, then bring the stack up.
cp .env.example .env
# Edit .env and replace SECRET_KEY. In PowerShell, use Copy-Item .env.example .env.
docker compose up -d
docker compose ps
curl http://localhost:21465/healthzThe health endpoint is the small detail that makes this operable, because a container that has a health check can be restarted by an orchestrator and can be waited on by a deployment script.
The environment surface is documented in detail in the example file, and it is worth reading as the operational contract. The core variables are PORT, HOST, SECRET_KEY, the webhook settings, TOKEN_STORE_TYPE, CUSTOM_USER_DATA_DIR, MAX_LISTENERS and MANAGER_ENABLED. The token store can be file, redis or mongodb, and the redis and mongodb variables are only used when the corresponding store is selected, which means the example file documents the whole configuration rather than a subset.
The compose file persists five named volumes, for tokens, Chromium session data, uploads, received images and logs, and the readme notes that changing the default secret is required before exposing the API.
The Manager UI rides inside the image
The Docker image includes WPPConnect Manager, and it is served at the manager path on the same port.
The readme describes what it gives you. Server profiles, session management and QR pairing, chat, contacts, groups and media, with Portuguese and English and light and dark themes.
The access model has two levels. You use SECRET_KEY for administration, or a session name or token for restricted access, and the credentials remain in browser memory. The UI can be turned off entirely with MANAGER_ENABLED set to false, and the image pins and verifies the Manager bundle during the build.
That last point is the one to notice. The Manager is downloaded as a release archive during the Docker build and its SHA256 is checked against a value baked into the Dockerfile, so the UI that ships inside the image is a known artefact rather than whatever the download server happened to serve. For a component whose job is to display QR codes for pairing a WhatsApp account, a verified bundle is a reasonable requirement.
There is a separate document for the configuration, the API, the authenticated events and the rollback, in the docs folder, and the readme notes that the existing APIs and the legacy sockets remain compatible, so an existing integration does not break when the manager is added.
The image build verifies what it downloads
The Dockerfile is four stages and the first one is the interesting one.
FROM node:22.22.2-alpine AS manager
ARG MANAGER_VERSION=2.0.0
ARG MANAGER_SHA256=e5cd47cbd56c5eca53751947cf5799f75aa5a4b4d7c2bf189471374a48b9ff7f
RUN wget -q -O /tmp/manager.tar.gz "https://github.com/wppconnect-team/wppconnect-manager/releases/download/v${MANAGER_VERSION}/wppconnect-manager.tar.gz" && \
echo "${MANAGER_SHA256} /tmp/manager.tar.gz" | sha256sum -c - && \
mkdir /manager && tar -xzf /tmp/manager.tar.gz -C /managerSo the Manager bundle is fetched by URL, its checksum is verified against a value in the build arguments, and the archive is only unpacked if the checksum matches. That is the right way to pull a release artefact into a build.
The base stage installs the build and runtime libraries for sharp, including vips, fftw, the compiler toolchain and python3, and it sets PUPPETEER_SKIP_CHROMIUM_DOWNLOAD so the browser comes from the distribution package rather than from a download during install. The build stage compiles the TypeScript and the runtime stage adds chromium and the vips libraries, exposes port 21465 and copies the Manager bundle in.
The dependency ordering is careful. The package.json and the yarn.lock are copied before the source, so a change to a source file does not invalidate the dependency layer, and Corepack is enabled with a pinned yarn 4.14.1 before the immutable install runs. The .yarnrc.yml is copied early as well, with a comment explaining that it is needed to make yarn 4 use the node-modules linker, which is the kind of detail that silently breaks a build if the file is missing.
Running it from source, and the tooling around it
The source install is the familiar three steps.
yarn install --immutable
cp .env.example .env
# PowerShell: Copy-Item .env.example .envThe environment file is optional, since Node loads .env from the directory where you start the server and existing environment variables take precedence, and then there is the Puppeteer dependency installation, which is a long apt-get line of the shared libraries a headless Chromium needs on Debian.
The package manifest shows the toolchain, and it is a well organised one. The engine requirement is Node 22.22.2 and the package manager is yarn 4.14.1. The build is a TypeScript pass for the declarations followed by Babel for the JavaScript, with inline source maps, and the start script runs the built server. The development script is tsx watch on the server entry point, so the source runs directly under Node with a watcher.
The rest of the scripts are the ones a project releases with. There is a Swagger generation script and a set of scripts to assemble the Swagger UI assets and rewrite the spec URL, a changelog script using conventional-changelog with the angular preset, a license checker that adds and verifies headers, and release-it for the release itself.
The repository also carries the usual hygiene files, with commitlint and husky for the commit format, jest as the test runner, eslint for the linting, prettier for the formatting, a requests.http file for poking the API from the editor, and types.d.ts at the root.
Editorial conclusion
Adopt WPPConnect Server when you are building an internal tool that has to talk to WhatsApp and you have an authorised account and a way to reach the API safely. Do not adopt it as a platform for a public service, because the container exposes an authenticated API that drives a logged-in WhatsApp session and the default secret in the compose file is a published string. Verify first that you replace SECRET_KEY before exposing the port, that you set MANAGER_ENABLED to false if you do not want the pairing UI reachable, and that the live send and receive paths are validated against an account you are entitled to automate.
Frequently asked questions
What is WPPConnect Server?
It is a ready to use REST API for sending and receiving WhatsApp messages, managing contacts and groups, creating groups, joining a group by invite code and receiving webhooks, built on Express and SocketIO with Node and Chromium.
How do I run WPPConnect Server with Docker?
Pull the image and run it with a named volume for the tokens and one for the Chromium user data directory, publishing port 21465 and setting SECRET_KEY, which the readme tells you to change before exposing the API. The compose route copies .env.example to .env, edits the secret and runs docker compose up -d, then checks the healthz endpoint.
What can I store the session tokens in?
The TOKEN_STORE_TYPE setting chooses between file, redis and mongodb, and the example environment file documents the full variable set for the Redis and MongoDB options, including the connection URI for the default remote mode. The compose file persists tokens, Chromium session data, uploads, received images and logs in named volumes.
What is the Manager in the WPPConnect Docker image?
It is WPPConnect Manager, served inside the image on the manager path. It provides server profiles, session management and QR pairing, chat, contacts, groups and media, in Portuguese and English with light and dark themes, and it can be disabled with MANAGER_ENABLED set to false.
How does the WPPConnect Docker image obtain the Manager UI?
It downloads the Manager release archive during the build and verifies it against a SHA256 checksum baked into the Dockerfile, and the bundle is only unpacked if the checksum matches.
What are the requirements to run WPPConnect Server from source?
Node 22.22.2 with yarn 4.14.1, an immutable yarn install, a copy of .env.example to .env with SECRET_KEY changed, and the Puppeteer shared libraries installed through apt-get for the headless Chromium.
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/wppconnect-team-wppconnect-server)Was this useful?