Available now
Self-host the open-source beta
Run the web app, Bun API, Go workers, PostgreSQL, NATS, Centrifugo, search, and media storage on infrastructure you operate.
Read the production notesSelf-hosting documentation
Set up the open-source application locally, connect WhatsApp, manage team access, and prepare a single-host production deployment with optional API replicas. These docs follow the current beta code in the public repository.
01 / Orientation
WATeamInbox is a multi-tenant collaborative inbox. A workspace can connect WhatsApp devices, bring messages into a shared React UI, and give each teammate a controlled view of the work. Its WhatsApp integration is unofficial and the software is still a community beta.
Available now
Run the web app, Bun API, Go workers, PostgreSQL, NATS, Centrifugo, search, and media storage on infrastructure you operate.
Read the production notesManaged service · Available now
Create a hosted workspace without operating the application stack yourself. Cloud plans start at $39 per month.
Create a Cloud accountReview the integration, data handling, backups, monitoring, updates, and WhatsApp terms before using this software with real customer data. No deployment or project page can guarantee that a WhatsApp account will avoid restrictions.
02 / Local setup
The root development compose file provides PostgreSQL, NATS, Centrifugo,
Meilisearch, and MinIO. The root bun run dev command starts the application
processes: the web app, the API, and the Go workers.
Before you begin
Local compose uses development credentials and exposed ports. It is for development only, not a production deployment.
Read the root READMEgit clone https://github.com/ygncode/wateaminbox.git
cd wateaminbox
# Create the ignored local environment file.
cp .env.example .env
# Install JavaScript dependencies and fetch Go dependencies during builds.
bun install
# Start PostgreSQL, NATS, Centrifugo, Meilisearch, and MinIO.
docker compose up -d
# Create the central and tenant database structures.
bun run db:migrate
# Start the web app, API, and Go workers.
bun run dev
Open the web app at http://localhost:4444. The API is at http://localhost:4445/api.
| Service | Port | Purpose |
|---|---|---|
| Web app | 4444 | React inbox and workspace UI |
| API | 4445 | Hono API on Bun |
| PostgreSQL | 4447 | Application and tenant data |
| NATS | 4448 | Commands, events, and JetStream |
| Meilisearch | 4449 | Search index; PostgreSQL is the fallback |
| MinIO | 4450 / 9001 | S3-compatible media / local console |
| Centrifugo | 4451 | Authenticated realtime WebSocket gateway |
NATS monitoring is available at http://localhost:8222. The optional NATS toolbox can be started with docker compose --profile debug up -d nats-box.
03 / Configuration
The checked-in root .env.example is the authoritative development inventory.
Copy it, then change the secrets and any hostnames that differ from the
defaults. Environment variables are loaded from the repository root when
commands run from the root.
At minimum, set independent random values for JWT_SECRET, CENTRIFUGO_API_KEY, and CENTRIFUGO_TOKEN_HMAC_SECRET. The HMAC secret and JWT secret must not be the same. Never commit .env, VAPID private keys, mail keys, WhatsApp session data, or storage credentials.
Application and data
DATABASE_URL: PostgreSQL connection.NATS_URL: NATS server used by the API and workers.S3_*: MinIO locally or private Cloudflare R2 through its account S3 API endpoint in production.MEILISEARCH_*: search service; PostgreSQL search is used when Meilisearch is unavailable.Auth and realtime
JWT_SECRET: access and refresh token signing.CENTRIFUGO_*: server API, health, and token-signing configuration.APP_URL and CORS_ORIGINS: browser origin policy.RATE_LIMIT_*: request and resource limits; production cannot disable rate limiting.API_REPLICA_COUNT: 1–10 homogeneous API replicas; multiple replicas require shared PostgreSQL or Redis rate limiting, and the supplied baseline uses PostgreSQL.PUBLIC_DB_POOL_MAX and TENANT_DB_POOL_MAX: per-replica database pool ceilings.REALTIME_MEMBERSHIP_CACHE_TTL_MS=0 until cross-replica membership invalidation is available.Email and notifications
MAIL_DRIVER=log captures local mail without delivery.EMAIL_FROM, and credentials for the selected provider.VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, and VAPID_SUBJECT.The web client defaults to the local API URL. Set these values when the browser reaches the API or Centrifugo through a different host, port, or TLS endpoint:
VITE_API_URL=http://localhost:4445/api
VITE_CENTRIFUGO_URL=ws://localhost:4451/connection/websocket
The public marketing site and the commercial Cloud control plane are maintained outside this open-source project. Self-hosted deployments do not need either repository and should configure their own application, API, realtime, storage, and email origins.
The public website links to https://app.wateaminbox.com for the managed
service. That hosted environment has its own billing and entitlement controls;
none of its commercial configuration belongs in the MIT-licensed repository.
04 / WhatsApp connections
Open the web app at your configured APP_URL, register, and verify the email link. Create a workspace or accept an invitation.
Add a named WhatsApp connection. The default maximum is five active or pending connections; a company-level setting can change that limit.
On the phone, open WhatsApp → Settings → Linked Devices → Link a Device, then scan the code shown by the workspace. The code expires quickly; restart the pairing attempt if the UI reports expiry.
Messages, contacts, groups, receipts, and available media are imported through the worker and API. The UI exposes sync progress; a connected account may continue processing history after pairing.
Disconnect stops the worker while retaining the linked-device session for reconnect. Archive & unlink logs out and removes session credentials while retaining inbox history. Permanent deletion is separate, permission-gated, and only applies to an archived connection.
Let the first sync finish, check the connection health, and use the conversation's older-history action when the local page is exhausted. Older history depends on what the primary WhatsApp device makes available.
05 / Teams and access
Access is workspace-scoped. Roles provide defaults, while the owner can apply
custom permissions to admins and members. Conversation visibility is not
automatically global: without can_view_all_chats, a member normally sees
active assignments.
All permissions; ownership cannot be removed by the permission editor.
All role defaults, subject to the owner/admin hierarchy rules for team operations.
Can send messages and normally sees assigned conversations only.
can_invite—including owners and admins by default—can invite an admin or member.06 / Implemented features
These are the main surfaces represented by the current web, API, database, and worker code. Feature access still depends on role, connection state, migrations, and configuration.
Connect multiple WhatsApp accounts to one workspace. The inbox keeps messages, delivery state, reactions, media, presence, typing indicators, groups, and connection-specific history together.
Assign contacts, restrict member visibility to assigned conversations when appropriate, and keep shared or private notes, tags, assignment history, and WhatsApp public usernames with the contact. Block or unblock contacts; blocked contacts cannot receive outbound actions until unblocked.
Use quick replies, sync WhatsApp Business labels to workspace tags, review synced catalogs and products, and control product visibility from the workspace settings.
Search contacts and messages, import contacts from CSV, export contacts or messages as CSV/JSON, and create a full ZIP backup when the caller has the required access.
The dashboard includes message, contact, team, engagement, response-time, and resolution views. Conversation cases and calendar-aware SLA policies support the operational workflow.
NATS JetStream, transactional outboxes, worker event handling, and idempotent processing cover the command and synchronization paths. Realtime events are update signals; PostgreSQL remains the source of truth.
Use the in-app notification center and browser desktop notifications. Web Push is optional and requires a stable VAPID key pair plus HTTPS outside localhost.
The application includes scheduled messages and permission-gated broadcast jobs. Bulk sending is paced and quota-limited by configuration; operators remain responsible for consent, policy, and WhatsApp account risk.
A connection manager can request a label sync, link labels to workspace tags, auto-create tags, and apply or remove a label from a contact. Treat the WhatsApp account and the workspace as systems that can diverge until a sync or action completes.
07 / Production self-hosting
Do not promote the development docker-compose.yml to production. The
repository’s compose.production.yml is a single-host baseline with Caddy at
the edge, an internal readiness-aware HAProxy router, and private data services.
It can run 1–10 homogeneous API replicas while keeping the orchestrator as a
singleton. Multiple API processes improve process and release resilience, not
host availability. This is deployment guidance, not a hosted service or a
guarantee of production readiness for every environment.
Use .env.production.example as a template, generate separate secret files, keep ingress on HTTPS, and do not reuse development credentials.
Keep PostgreSQL authoritative and use the private Cloudflare R2 bucket through its account S3 API endpoint with short-lived signed URLs. Define encrypted backups for database, media, NATS, search, and secret material.
Run migrations and worker artifact installation as gated steps, pin image tags, monitor health and queue signals, test restores, and document upgrade and rollback decisions.
It covers DNS, Caddy, secret files, the migration service, backups, restore drills, proxy trust, monitoring, upgrades, and rollback. Open docs/deployment.md
08 / API guide
The API base is /api in the documented reverse-proxy shape, or
http://localhost:4445/api locally. Most workspace routes require a
short-lived bearer access token and the X-Company-ID header. Refresh tokens
are held in an HttpOnly cookie; do not copy server secrets into browser
variables.
Authorization: Bearer <access-token>
X-Company-ID: <workspace-uuid>
| Method | Path | Use |
|---|---|---|
| GET | /api/health/live | Liveness probe; no workspace context |
| GET | /api/health/ready | Readiness probe for PostgreSQL, rate limiting, NATS, and realtime dependencies; no workspace context |
| POST | /api/auth/register | Create a user and send verification mail |
| GET | /api/contacts | List visible contacts with filters |
| POST | /api/messages | Canonical message-send endpoint |
| GET | /api/conversations/:id/messages | Read a conversation page |
| GET | /api/search?q=... | Search visible contacts and messages |
| GET | /api/analytics/dashboard | Workspace dashboard data |
| POST | /api/realtime/token | Issue a short-lived Centrifugo token |
| GET | /api/export/full | Create a permission-gated ZIP backup |
The canonical send route is POST /api/messages. POST /api/conversations/:id/messages remains for compatibility and is deprecated. Export routes return CSV, JSON, or ZIP rather than only JSON. See the route source for the current surface.
The browser obtains a short-lived token from POST /api/realtime/token and
connects to the configured Centrifugo WebSocket endpoint. Events invalidate or
update local UI state; clients reconcile with PostgreSQL-backed API reads after
reconnects.
message:new
message:status
contact:updated
connection:status
notification:new
labels:updated
catalogs:updated
09 / FAQ
No. It is an independent project and is not affiliated with, endorsed by, or sponsored by WhatsApp or Meta.
Yes. WATeamInbox Cloud is available at app.wateaminbox.com, with current plan details on the pricing page. These documentation sections continue to cover the separate self-hosted edition.
No. The integration is unofficial and the project cannot guarantee prevention or reversal of restrictions. Follow WhatsApp's terms and avoid unsolicited or high-volume messaging.
Nothing by itself. It documents a concrete single-host baseline that can run 1–10 homogeneous API replicas behind an internal router. Multiple processes improve process and release resilience but do not provide host HA or an SLA; the orchestrator remains a singleton. Operators still own domain configuration, secrets, TLS, access control, backups, updates, monitoring, incident response, and compliance decisions.
Yes, Web Push is optional. Without it, desktop notifications work while the application is loaded. Configure a stable VAPID pair and HTTPS for background delivery.
Use GitHub Issues for reproducible bugs and questions. Report suspected vulnerabilities privately using the repository's security policy.
Documentation feedback
If a command, setting, or screenshot no longer matches the current code, tell us on WhatsApp or open an issue with the relevant file.