| .vscode | ||
| docs | ||
| drizzle | ||
| load-test | ||
| public | ||
| scripts | ||
| src | ||
| tests | ||
| .cta.json | ||
| .cursorrules | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .prettierignore | ||
| .prettierrc | ||
| bun.lock | ||
| CLAUDE.md | ||
| components.json | ||
| docker-compose.yml | ||
| Dockerfile | ||
| drizzle.config.ts | ||
| eslint.config.js | ||
| LICENSE | ||
| package.json | ||
| playwright.config.ts | ||
| prettier.config.js | ||
| README.md | ||
| tsconfig.json | ||
| vite.config.ts | ||
| vitest.config.ts | ||
Wahoo
Self-hosted WhatsApp gateway — send and receive WhatsApp messages through a clean REST API, with multi-app support, end-to-end encryption, webhooks, and a built-in admin dashboard.
Not affiliated with WhatsApp or Meta. Unofficial API. Use at your own risk. See docs/baileys-risk.md for full risk disclosure.
Quickstart
See docs/quickstart.md for the full guide. Short version:
git clone https://github.com/yourorg/wahoo.git && cd wahoo
cp .env.example .env # fill in MASTER_ENCRYPTION_KEY and SESSION_SECRET
docker compose up -d
# open http://localhost:3000
Features
- Multi-app — create isolated apps, each with its own encryption key and API keys
- Multi-session — run multiple WhatsApp numbers per app
- Encrypted at rest — contacts and session credentials encrypted with AES-256-GCM, per-app data encryption keys wrapped by a master key
- Encryption key rotation — rotate the app DEK in the background without downtime
- REST API — send text, image, video, document, and audio messages; broadcast to multiple recipients
- Webhooks — receive real-time events (message received/sent/delivered/read, session status, presence) with HMAC-SHA256 signatures
- Contact management — import via CSV, sync from WhatsApp, tag and group contacts, custom field schemas
- Audit log — tamper-evident log of all admin and API actions
- TOTP 2FA — protect admin accounts with time-based one-time passwords
- OpenAPI docs — interactive Swagger UI at
/api/docs - Admin dashboard — full web UI for managing apps, sessions, webhooks, contacts, and monitoring
Architecture
| Layer | Technology |
|---|---|
| Frontend + SSR | TanStack Start (React, Vite) |
| Routing | TanStack Router (file-based) |
| API | TanStack Start server handlers (Nitro adapter) |
| Database | PostgreSQL via Drizzle ORM |
| Job queue | BullMQ (Redis) |
| WhatsApp protocol | Baileys (unofficial, reverse-engineered) |
| Encryption | AES-256-GCM, per-app DEK + master KEK |
| Auth | Iron Session (cookie) + API key (Bearer) |
Documentation
| File | Contents |
|---|---|
| docs/quickstart.md | Step-by-step getting started guide |
| docs/api.md | REST endpoint reference |
| docs/webhooks.md | Event catalog, HMAC verification |
| docs/security.md | Encryption model, key rotation, audit log |
| docs/deployment.md | Docker Compose deploy, backup, restore |
| docs/baileys-risk.md | Baileys risks, ToS, number warming guide |
Interactive API reference available at http://localhost:3000/api/docs when running.
Baileys risk notice
Wahoo uses Baileys, an unofficial WhatsApp Web client built through reverse engineering. This violates WhatsApp's Terms of Service (§2c). Your number may be temporarily or permanently banned. Read docs/baileys-risk.md before deploying in production.
License
Wahoo is released under the MIT License.
Baileys is separately licensed under the Apache 2.0 License. Wahoo does not bundle Baileys source code; it lists it as an npm dependency.