WuzAPI is an implementation
of the @tulir/whatsmeow library as a
simple RESTful API service with multiple device support and concurrent
sessions.
Whatsmeow does not use Puppeteer on headless Chrome, nor an Android emulator. It communicates directly with WhatsApp’s WebSocket servers, making it significantly faster and much less demanding on memory and CPU than those solutions. The drawback is that any changes to the WhatsApp protocol could break connections, requiring a library update.
Using this software in violation of WhatsApp’s Terms of Service can get your number banned:
Be very careful—do not use this to send SPAM or anything similar. Use at your own risk. If you need to develop something for commercial purposes, contact a WhatsApp global solution provider and sign up for the WhatsApp Business API service instead.
When HMAC is configured, all webhooks include an x-hmac-signature header with SHA-256 HMAC signature.
application/json
* Signed data: Raw JSON request body
* Verification: Use the exact JSON received
application/x-www-form-urlencoded
* Signed data: URL-encoded form string (key=value&key2=value2)
* Verification: Reconstruct the form string from received parameters
multipart/form-data (file uploads)
* Signed data: JSON representation of form fields (excluding files)
* Verification: Create JSON from non-file form fields
Required: * Go (Go Programming Language)
Optional: * Docker (for containerization)
This project uses the whatsmeow library to communicate with WhatsApp. To update the library to the latest version, run:
go get -u go.mau.fi/whatsmeow@latest
go mod tidy
go build .
To install wuzapi via Homebrew use:
brew install asternic/wuzapi/wuzapi
By default it will start a REST service in port 8080. These are the parameters you can use to alter behaviour
-wadebug : enable whatsmeow debug, either INFO or DEBUG levels are suported
-sslcertificate : SSL Certificate File
Example:
To have colored logs:
./wuzapi -logtype=console -color=true
For JSON logs:
./wuzapi -logtype json
With time zone:
Set TZ=America/New_York ./wuzapi ... in your shell or in your .env file or Docker Compose environment: TZ=America/New_York.
WuzAPI uses a .env file for configuration. You can use the provided .env.sample as a template:
cp .env.sample .env
WUZAPI_ADMIN_TOKEN=your_admin_token_here
WUZAPI_GLOBAL_ENCRYPTION_KEY=your_32_byte_encryption_key_here
WUZAPI_GLOBAL_HMAC_KEY=your_global_hmac_key_here
TZ=America/New_York
WEBHOOK_FORMAT=json
SESSION_DEVICE_NAME=WuzAPI
WUZAPI_PORT=8080
WUZAPI_GLOBAL_WEBHOOK=https://your-global-webhook.url
WEBHOOK_RETRY_ENABLED=true
WEBHOOK_RETRY_COUNT=2
WEBHOOK_RETRY_DELAY_SECONDS=30
WEBHOOK_ERROR_QUEUE_NAME=wuzapi_dead_letter_webhooks
If the following settings are not provided, they will be auto-generated:
* WUZAPI_ADMIN_TOKEN: Random 32-character token
* WUZAPI_GLOBAL_ENCRYPTION_KEY: Random 32-byte key for AES-256 encryption
Important: Save auto-generated credentials to your .env file or you will lose access to encrypted data and admin functions on restart!
WUZAPI_GLOBAL_HMAC_KEY: Global HMAC key for webhook signing (minimum 32 characters)For PostgreSQL:
DB_USER=wuzapi
DB_PASSWORD=wuzapi
DB_NAME=wuzapi
DB_HOST=db # Use 'db' when running with Docker Compose, or 'localhost' for native execution
DB_PORT=5432
DB_SSLMODE=false
For SQLite (default): No database configuration needed - SQLite is used by default if no PostgreSQL settings are provided.
TZ=America/New_York
WEBHOOK_FORMAT=json # or "form" for the default
SESSION_DEVICE_NAME=WuzAPI
WUZAPI_PORT=8080 # Port for the WuzAPI server
WUZAPI_GLOBAL_WEBHOOK= # Global webhook URL for all instances
WuzAPI supports sending WhatsApp events to a RabbitMQ queue for global event distribution. When enabled, all WhatsApp events will be published to the specified queue regardless of individual user webhook configurations.
Set these environment variables to enable RabbitMQ integration:
RABBITMQ_URL=amqp://guest:guest@localhost:5672
RABBITMQ_QUEUE=whatsapp # Optional (default: whatsapp_events)
When enabled:
WuzAPI supports HMAC signatures for webhook verification:
WUZAPI_GLOBAL_HMAC_KEY environment variablex-hmac-signature headerPriority: Instance HMAC > Global HMAC > No signature
Configure HMAC keys via the Dashboard or using the /session/hmac/config API endpoints.
When using Docker Compose, docker-compose.yml automatically loads environment variables from a .env file when available. However, docker-compose-swarm.yaml uses docker stack deploy, which does not automatically load from .env files. Variables in the swarm file will only be substituted if they are exported in the shell environment where the deploy command is run. For managing secrets in Swarm, consider using Docker secrets.
The Docker configuration will:
1. First load variables from the .env file (if present and supported)
2. Use default values as fallback if variables are not defined
3. Override with any variables explicitly set in the environment section of the compose file
Key differences for Docker deployment:
- Set DB_HOST=db instead of localhost to connect to the PostgreSQL container
- The WUZAPI_PORT variable controls the external port mapping in docker-compose.yml
- In swarm mode, WUZAPI_PORT configures the Traefik load balancer port
Note: The .env file is already included in .gitignore to avoid committing sensitive information to your repository.
To interact with the API, you must include the Authorization header in HTTP requests, containing the user's authentication token. You can have multiple users (different WhatsApp numbers) on the same server.
You can list, add and remove users using the admin endpoints. For that you must use the WUZAPI_ADMIN_TOKEN in the Authorization header
Then you can use the /admin/users endpoint with the Authorization header containing the token to:
GET /admin/users - List all usersPOST /admin/users - Create a new userDELETE /admin/users/{id} - Remove a userThe JSON body for creating a new user must contain:
name [string] : User's name token [string] : Security token to authorize/authenticate this userwebhook [string] : URL to send events via POST (optional)events [string] : Comma-separated list of events to receive (required) - Valid events are: "Message", "ReadReceipt", "Presence", "HistorySync", "ChatPresence", "All"expiration [int] : Expiration timestamp (optional, not enforced by the system)You can create a user with optional proxy and S3 storage configuration. All fields are optional and backward compatible. If you do not provide these fields, the user will be created with default settings.
{
"name": "test_user",
"token": "user_token",
"proxyConfig": {
"enabled": true,
"proxyURL": "socks5://user:pass@host:port"
},
"s3Config": {
"enabled": true,
"endpoint": "https://s3.amazonaws.com",
"region": "us-east-1",
"bucket": "my-bucket",
"accessKey": "AKIAIOSFODNN7EXAMPLE",
"secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"pathStyle": false,
"publicURL": "https://cdn.yoursite.com",
"mediaDelivery": "both",
"retentionDays": 30
}
}
proxyConfig (object, optional):enabled (boolean): Enable proxy for this user.proxyURL (string): Proxy URL (e.g., socks5://user:pass@host:port).s3Config (object, optional):enabled (boolean): Enable S3 storage for this user.endpoint (string): S3 endpoint URL.region (string): S3 region.bucket (string): S3 bucket name.accessKey (string): S3 access key.secretKey (string): S3 secret key.pathStyle (boolean): Use path style addressing.publicURL (string): Public URL for accessing files.mediaDelivery (string): Media delivery type (base64, s3, or both).retentionDays (integer): Number of days to retain files.If you omit proxyConfig or s3Config, the user will be created without proxy or S3 integration, maintaining full backward compatibility.
API calls should be made with content type json, and parameters sent into the request body, always passing the Token header for authenticating the request.
Check the API Reference
|
|
|
|
|
|
|
|
|
|
|
$ claude mcp add wuzapi \
-- python -m otcore.mcp_server <graph>