Self-hosting documentation

Run WATeamInbox on your own server.

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

How the self-hosted application works

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

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 notes

Managed service · Available now

WATeamInbox Cloud

Create a hosted workspace without operating the application stack yourself. Cloud plans start at $39 per month.

Create a Cloud account
Beta and account-risk notice.

Review 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

Run the development stack locally

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.

Prerequisites

  • Bun 1.2.18+Workspace package manager and TypeScript runtime.
  • Go 1.25+Builds the orchestrator and WhatsApp worker.
  • Docker ComposeRuns local data and messaging dependencies.
  • GitClones the repository and keeps source changes reviewable.

Before you begin

Local compose uses development credentials and exposed ports. It is for development only, not a production deployment.

Read the root README

Quick start

git 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.

Local service map

ServicePortPurpose
Web app4444React inbox and workspace UI
API4445Hono API on Bun
PostgreSQL4447Application and tenant data
NATS4448Commands, events, and JetStream
Meilisearch4449Search index; PostgreSQL is the fallback
MinIO4450 / 9001S3-compatible media / local console
Centrifugo4451Authenticated 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

Environment and runtime 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.

Replace development secrets.

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.
  • Keep REALTIME_MEMBERSHIP_CACHE_TTL_MS=0 until cross-replica membership invalidation is available.

Email and notifications

  • MAIL_DRIVER=log captures local mail without delivery.
  • Production requires a delivering mail driver—Resend or Cloudflare Email Service—a real EMAIL_FROM, and credentials for the selected provider.
  • Web Push is optional: configure VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, and VAPID_SUBJECT.

Browser URLs

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 website and managed Cloud service

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

Connect WhatsApp and sync message history

  1. 1
    Create and verify your user.

    Open the web app at your configured APP_URL, register, and verify the email link. Create a workspace or accept an invitation.

  2. 2
    Open Settings → Connections.

    Add a named WhatsApp connection. The default maximum is five active or pending connections; a company-level setting can change that limit.

  3. 3
    Scan the pairing QR code.

    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.

  4. 4
    Watch the initial history sync.

    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.

Connection lifecycle

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.

If history is missing

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

Manage teammates, roles, and conversation 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.

Owner

All permissions; ownership cannot be removed by the permission editor.

Admin

All role defaults, subject to the owner/admin hierarchy rules for team operations.

Member

Can send messages and normally sees assigned conversations only.

Invite and hand off

  • Any workspace member with can_invite—including owners and admins by default—can invite an admin or member.
  • Invitation links expire after seven days and can be resent or canceled.
  • An unassigned contact can be claimed; reassignment requires the relevant assignment permission.
  • A first send can claim an unassigned contact, while an active assignment remains an access boundary.

Permission areas

  • Chat visibility, sending, and broadcast sending.
  • Contact assignment, team invites, and team administration.
  • WhatsApp connection management, dashboard, and audit log access.
  • Exports and destructive data actions.

06 / Implemented features

Features in the current beta

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.

01

Shared conversations

Connect multiple WhatsApp accounts to one workspace. The inbox keeps messages, delivery state, reactions, media, presence, typing indicators, groups, and connection-specific history together.

02

Ownership and context

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.

03

Business inbox tools

Use quick replies, sync WhatsApp Business labels to workspace tags, review synced catalogs and products, and control product visibility from the workspace settings.

04

Search and data tools

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.

05

Operational views

The dashboard includes message, contact, team, engagement, response-time, and resolution views. Conversation cases and calendar-aware SLA policies support the operational workflow.

06

Durable background work

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.

07

Notifications

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.

08

Scheduled and bulk messages

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.

Labels are a sync workflow, not magic bidirectional state.

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

Deploy the single-host production baseline

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.

01

Secrets and TLS

Use .env.production.example as a template, generate separate secret files, keep ingress on HTTPS, and do not reuse development credentials.

02

Data and media

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.

03

Operations

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.

Read the full deployment procedure before exposing a host.

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

API routes and authentication

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>
MethodPathUse
GET/api/health/liveLiveness probe; no workspace context
GET/api/health/readyReadiness probe for PostgreSQL, rate limiting, NATS, and realtime dependencies; no workspace context
POST/api/auth/registerCreate a user and send verification mail
GET/api/contactsList visible contacts with filters
POST/api/messagesCanonical message-send endpoint
GET/api/conversations/:id/messagesRead a conversation page
GET/api/search?q=...Search visible contacts and messages
GET/api/analytics/dashboardWorkspace dashboard data
POST/api/realtime/tokenIssue a short-lived Centrifugo token
GET/api/export/fullCreate 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.

Realtime transport

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

Frequently asked questions

Is WATeamInbox an official WhatsApp product?

No. It is an independent project and is not affiliated with, endorsed by, or sponsored by WhatsApp or Meta.

Is there a hosted Cloud service?

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.

Does the project guarantee WhatsApp account safety?

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.

What does the production guide guarantee?

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.

Can I use Web Push without configuring it?

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.

Where should I report a bug or security issue?

Use GitHub Issues for reproducible bugs and questions. Report suspected vulnerabilities privately using the repository's security policy.

Documentation feedback

Found a mismatch?

If a command, setting, or screenshot no longer matches the current code, tell us on WhatsApp or open an issue with the relevant file.

Questions? Message usWhatsApp · +65 8404 2683