Public docs / self-hosting

Run the inbox where your team can see the boundaries.

WATeamInbox is an open-source beta for teams sharing customer conversations on WhatsApp. This guide describes the code that is in the repository now: local setup, configuration, connections, access, and the self-hosted production baseline.

01 / orientation

Know what you are running.

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

Planned, not live

WATeamInbox Cloud

The public waitlist collects confirmed interest for a future managed option. There is no Cloud account, price, launch date, feature set, or service level promised here.

See the waitlist
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

Get a complete development stack running.

The root development compose file provides PostgreSQL, NATS, Centrifugo, Meilisearch, and MinIO. The root bun run devcommand starts the application processes, including the web and marketing servers.

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, workers, and marketing site.
bun run dev

Open the web app at http://localhost:4444. The API is athttp://localhost:4445/api; the marketing site useshttp://localhost:4446.

Local service map

ServicePortPurpose
Web app4444React inbox and workspace UI
API4445Hono API on Bun
Marketing4446Static Astro site
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 withdocker compose --profile debug up -d nats-box.

03 / configuration

Configure the runtime without guessing.

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 forJWT_SECRET, CENTRIFUGO_API_KEY, andCENTRIFUGO_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 S3/R2-compatible storage.
  • 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.

Email and notifications

  • MAIL_DRIVER=log captures local mail without delivery.
  • Production requires the Resend driver, a real EMAIL_FROM, and a real provider key.
  • 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 static marketing site and waitlist

The marketing site is a static Astro build. Its Cloud waitlist form uses the explicit build-time PUBLIC_WAITLIST_API_URL; it does not guess a missing /api proxy. If this copy is self-hosted without a waitlist Worker, leave the value unset and the form explains that no signup service is configured.

# Separate Worker origin for a self-hosted marketing deployment.
PUBLIC_WAITLIST_API_URL=https://waitlist-api.example.com

# Optional public Turnstile site key; the Worker validates the token server-side.
PUBLIC_WAITLIST_TURNSTILE_SITE_KEY=your-public-site-key

The documented Cloudflare Pages setup uses the same-origin Worker route at https://wateaminbox.com. Use that value only when the reviewed route exists; otherwise use the real Worker origin. See the Cloud waitlist guide .

04 / WhatsApp connections

Pair a device, then let the sync settle.

  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

Make visibility and ownership explicit.

Access is workspace-scoped. Roles provide defaults, while the owner can apply custom permissions to admins and members. Conversation visibility is not automatically global: withoutcan_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

  • Owners and members with can_invite 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

A capability map, not a roadmap.

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, and assignment history with the contact.

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

Use the hardened baseline, then do your own review.

Do not promote the development docker-compose.yml to production. The repository's compose.production.ymlis a single-host baseline with Caddy at the edge and private data services. It 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, use private S3-compatible media storage, and define encrypted backups for database, media, NATS, search, and secret material.

03

Operations

Run migrations as a gated step, 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

Integrate against the routes that exist.

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 theX-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
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 fromPOST /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

Short answers for the decisions that matter.

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 to use now?

No. The Cloud waitlist is for updates about a planned managed option. Joining does not create an account, start billing, or provide access. Self-hosting is the available path in this repository.

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

Keep the guide honest

Found a mismatch?

Documentation should follow the code, configuration, and deployment decisions. Send a correction by email or open a focused issue with the command, route, or file that needs updating.