Repository iconcurepo.dev
OpenWA preview

rmyndharis / OpenWA

apibotgatewayself-hosted

Free, Open Source, Self-Hosted WhatsApp API Gateway

11.1k Stars
visibility61 Watchers
fork_right2.5k Forks
TypeScript
historyUpdated recently

description README.md

OpenWA Logo

OpenWA

Open Source WhatsApp API Gateway

FeaturesQuick StartDocsAPIContributing

CI Version License Node NestJS Docker TypeScript


✨ Why OpenWA?

OpenWA is a free, open-source WhatsApp API Gateway designed for developers who need full control over their messaging infrastructure—without vendor lock-in or hidden paywalls.

Built on a pluggable architecture, OpenWA lets you swap database engines (SQLite/PostgreSQL), storage backends (Local/S3), and cache layers (Memory/Redis) without changing a single line of application code.

🔓 100% Open SourceNo licensing fees, no feature locks, full source code access
🏗️ Pluggable ArchitectureSwap adapters for database, storage, and cache via config
🖥️ Full DashboardModern React UI for session, webhook, and API key management
🔹 Multi-Session ReadyRun multiple WhatsApp sessions concurrently on one instance
🐳 Docker NativeProduction-ready with zero configuration
🔗 n8n IntegrationCommunity nodes for workflow automation
🧩 Community AdaptersThird-party integrations (e.g. ioBroker) — see docs

🎯 Features

Core Features

FeatureStatusDescription
REST APIFull WhatsApp API via HTTP endpoints
Multi-SessionManage multiple WhatsApp accounts
WebhooksReal-time events with HMAC signature and optional smart pre-dispatch filters
Web DashboardVisual management interface
API Key AuthSecure API authentication
Swagger DocsInteractive API documentation

Messaging

FeatureStatusDescription
Text MessagesSend/receive text messages
Media MessagesImages, videos, documents, audio
Message ReactionsReact to messages with emoji
Bulk MessagingSend to multiple recipients
Message StatusTrack delivery and read receipts

Advanced

FeatureStatusDescription
Groups APICreate, manage, and message groups
Channels/NewsletterWhatsApp Channels support
Labels ManagementOrganize chats with labels
Proxy SupportPer-session proxy configuration
Rate LimitingConfigurable request limits
CIDR WhitelistingIP-based access control
Audit LoggingTrack all API operations

Infrastructure

FeatureStatusDescription
SQLiteZero-config embedded database
PostgreSQLProduction-grade database
Redis CacheOptional performance caching
S3/MinIO StorageScalable media storage
DockerOne-command deployment
Health ChecksKubernetes-ready probes
Data MigrationExport/import between backends

🚀 Quick Start

Option A: Docker (Recommended)

# Clone and start
git clone https://github.com/rmyndharis/OpenWA.git
cd OpenWA
docker compose -f docker-compose.dev.yml up -d

# Access (the dashboard is bundled into the API image and served on the same port)
# Dashboard: http://localhost:2785
# API: http://localhost:2785/api
# Swagger: http://localhost:2785/api/docs

Using Podman instead of Docker? Podman rootless mode requires the socket to be running and DOCKER_HOST to be set:

systemctl --user start podman.socket
systemctl --user enable podman.socket
export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock

Add the export line to your ~/.bashrc to make it permanent.

Option B: Local Development

# Clone repository
git clone https://github.com/rmyndharis/OpenWA.git
cd OpenWA

# Install dependencies (includes dashboard)
npm install

# Start API + Dashboard (config is auto-generated on first run)
npm run dev

# Access (in dev the dashboard runs on the Vite server with hot reload)
# Dashboard: http://localhost:2886
# API: http://localhost:2785/api
# Swagger: http://localhost:2785/api/docs

🔒 Security Architecture

Docker Socket Proxy

The production stack never exposes /var/run/docker.sock directly to the application container. Instead, a dedicated docker-proxy sidecar (based on tecnativa/docker-socket-proxy) acts as the sole gateway to the Docker daemon:

openwa-api  ──TCP 2375──▶  docker-proxy  ──unix──▶  /var/run/docker.sock

Only the operations needed for container orchestration are enabled (CONTAINERS, IMAGES, VOLUMES, INFO, PING, POST, DELETE). The application connects via the DOCKER_HOST=tcp://docker-proxy:2375 environment variable, which DockerService detects automatically.


🔒 Security Architecture

Non-root Container Execution

The production image never runs the Node.js process as root. On startup, the container follows this chain:

dumb-init (PID 1)
  └─ docker-entrypoint.sh (root — fixes named-volume ownership via chown)
       └─ gosu openwa node dist/main  (drops to the openwa user)
  • dumb-init is PID 1 and forwards signals (SIGTERM, etc.) for graceful shutdown.
  • docker-entrypoint.sh runs as root only long enough to chown the named-volume mount points so the openwa user can write to them.
  • gosu performs a clean exec-based privilege drop — no su or sudo wrappers, so the node process is the direct child of dumb-init.

Named volumes (e.g. openwa-data) get their ownership corrected automatically on every start, so no manual chown step is needed after volume creation.


🏭 Production Deployment

For production, use the main docker-compose.yml with optional services:

# Basic production (SQLite, local storage)
docker compose up -d

# With PostgreSQL database
docker compose --profile postgres up -d

# Full stack (PostgreSQL, Redis, MinIO)
docker compose --profile full up -d
ProfileServices
postgresPostgreSQL database
redisR