# WhatsApp Channel as a Service — SaaS Plan

> Consolidated from 5 domain expert analyses. 2026-03-24.

## Executive Summary

Turn the WAHA OpenClaw plugin into a multi-tenant SaaS that lets **any AI agent platform** (OpenClaw, ZeroClaw, NanoBot, custom) add WhatsApp messaging via subscription. Not a messaging API (Twilio's game) — an **AI agent WhatsApp runtime** with 100+ actions, fuzzy name resolution, group policies, admin panel, and directory management built in.

**Timeline**: 15-22 weeks MVP | **Year 1 target**: 200 customers, $16K MRR | **Infra cost at 100 tenants**: ~$150/mo

---

## 1. Architecture

### Multi-Tenant Strategy

| Decision | Choice | Rationale |
|----------|--------|-----------|
| Database | Schema-per-tenant PostgreSQL | Hard isolation without per-DB operational overhead. Migration from SQLite is mechanical — `DirectoryDb` is already a clean abstraction |
| WAHA instances | Shared pool, ~30 sessions/node | Cost-efficient. Premium tier gets dedicated nodes |
| Webhook routing | Central router, session ID → tenant lookup | WAHA webhooks hit router, router forwards to tenant callback URL |
| Data isolation | Schema (DB), prefix (S3), namespace (containers) | No cross-tenant data access possible at DB level |
| Config | Database-stored per tenant | Replaces file-based `openclaw.json` |

### Service Topology

```
[CDN/WAF] → [Load Balancer] → [API Gateway] → [Session Manager] → [WAHA Pool]
                              → [Webhook Router] → [Delivery Workers]
                              → [Admin Panel (static)]

[PostgreSQL] [Redis] [S3/R2]
```

### API Structure

```
Base: https://api.whatsapp-channel.service/v1

POST   /sessions/:sid/messages/send      # Send text
POST   /sessions/:sid/messages/media     # Send media
POST   /sessions/:sid/messages/poll      # Send poll
GET    /sessions/:sid/contacts           # List contacts
GET    /sessions/:sid/groups             # List groups
POST   /tenants/:id/sessions            # Create WhatsApp session
GET    /tenants/:id/sessions/:sid/qr    # QR code for pairing
PUT    /tenants/:id/webhooks            # Configure callback URL
GET    /tenants/:id/directory           # Directory API
```

Auth: Bearer API keys (`wcs_live_xxx`), SHA-256 hashed in DB, scoped permissions.

### What's Reused vs New

**Reused** (modify, not rewrite):
- `send.ts` — all WAHA API calls, add tenant context routing
- `inbound.ts` — webhook processing, add tenant lookup
- `directory.ts` — swap SQLite for PG adapter
- `http-client.ts` — per-tenant rate limiting (already has TokenBucket)
- `admin/` React panel — add auth, scoped to tenant data
- `accounts.ts` — already has `tenantId` field

**New components**:
- API Server (REST gateway, auth, rate limiting)
- Session Manager (WAHA node ↔ session mapping)
- Webhook Router + Delivery Workers (reliable delivery with retry/DLQ)
- Tenant Service (CRUD, API keys, plan enforcement)
- Billing Service (Stripe integration)
- Migration Runner (per-tenant schema management)

**Removed**:
- `monitor.ts` webhook server → splits into API Server + Webhook Router
- SQLite → PostgreSQL
- File-based config → database config
- OpenClaw SDK coupling → platform adapter interface

### Migration Path

| Phase | Duration | Scope |
|-------|----------|-------|
| 1. Decouple from OpenClaw SDK | 4-6 weeks | Extract `ChannelPlatformAdapter` interface, OpenClaw becomes one adapter |
| 2. Database migration | 2-3 weeks | `DirectoryStore` interface, PG implementation, dedup to Redis |
| 3. Multi-tenant API layer | 4-6 weeks | API Server, Session Manager, Webhook Router |
| 4. Infrastructure | 2-3 weeks | Dockerize, K8s manifests, CI/CD, monitoring |
| 5. Billing & onboarding | 3-4 weeks | Stripe, usage metering, self-service flow |

---

## 2. Business Model

### Positioning

**Not a messaging API** (Twilio's game). An **AI agent WhatsApp runtime**. The 100+ actions, fuzzy name resolution, group policies, multi-session management, and admin panel are the moat — no competitor has this combination.

### Pricing Tiers

| | Sandbox | Starter | Pro | Enterprise |
|--|---------|---------|-----|------------|
| Price | $0 | $29/mo | $149/mo | Custom |
| Sessions | 1 | 2 | 10 | Unlimited |
| Messages/mo | 1,000 | 10,000 | 100,000 | Unlimited |
| Admin panel | Read-only | Full | Full + analytics | Full + SSO |
| Support | Community | Email (48h) | Priority (4h) | Dedicated |
| Webhooks | 1 endpoint | 3 endpoints | 10 endpoints | Unlimited |
| Overage | Blocked | $0.005/msg | $0.003/msg | Negotiated |
| Gross margin | — | 55% | 71% | 80%+ |

### Revenue Projections (Year 1)

| Scenario | Customers | MRR | ARR |
|----------|-----------|-----|-----|
| Conservative | 100 | $8K | $96K |
| Moderate | 200 | $16K | $192K |
| Aggressive | 500 | $40K | $480K |

Unit economics: LTV:CAC ratio of 20x (capital-efficient).

### Go-to-Market

1. **Open-core model**: MIT core plugin (GitHub), proprietary multi-tenant SaaS
2. **Launch**: Product Hunt + Hacker News + AI agent communities
3. **Content**: Integration tutorials, comparison pages (vs Twilio, vs self-hosted WAHA)
4. **Partnerships**: AI platforms as distribution (OpenClaw, ZeroClaw, NanoBot built-in)
5. **Developer evangelism**: Demo sandbox, quickstart in <5 minutes

### Marketing Materials Needed

- Landing page (hero + pricing + comparison + quickstart)
- Documentation site (OpenAPI reference, SDKs, tutorials)
- Demo sandbox environment (free tier)
- Video walkthroughs (setup, first message, admin panel tour)
- Comparison pages (vs Twilio WhatsApp, vs WATI, vs self-hosted)
- Case studies (OpenClaw as first customer)

---

## 3. Onboarding: Two Paths

### Philosophy

Every tenant should be able to go from zero to sending their first WhatsApp message in **under 3 minutes**. Two paths to get there:

| Path | For | Effort | Time |
|------|-----|--------|------|
| **A. Agent-Guided** (skill) | Developers with an AI agent already running | Tell agent one sentence | ~60 seconds |
| **B. Traditional** (web wizard) | Everyone else, non-technical, first-time users | Click-through wizard | ~3 minutes |

Both paths start the same way: **register on the website and get an API key**.

---

### Path A: Agent-Guided Onboarding (OpenClaw Skill)

**The idea**: The user tells their AI agent a single sentence, and the agent does everything else.

```
User: "Add WhatsApp to my agent. My API key is wcs_live_a8f3k2..."

Agent: Got it. Let me set up WhatsApp for you.
       1. Installing waha-openclaw-channel...  ✅
       2. Writing config to openclaw.json...   ✅
       3. Restarting gateway...                ✅
       4. Connecting to WhatsApp SaaS...       ✅
       5. Your WhatsApp session is ready.

       Scan this QR code to link your phone:
       [QR code URL displayed]

       Once scanned, say "send test message to +972..." to verify.
```

#### The Onboarding Skill (OpenClaw-compliant)

This is a **separate skill** from the existing SKILL.md (which describes how to USE WhatsApp actions). This is a **setup skill** — it guides the agent through installation and configuration.

**Skill structure** (OpenClaw-compliant SKILL.md format):

```markdown
---
name: whatsapp-channel-setup
description: Install and configure WhatsApp messaging via WAHA SaaS
version: 1.0.0
---

# WhatsApp Channel Setup

This skill guides you through adding WhatsApp messaging to your agent
via the WhatsApp Channel SaaS platform.

## Prerequisites
- An API key from https://whatsapp-channel.service (starts with `wcs_live_`)
- OpenClaw gateway running
- A phone with WhatsApp installed

## Setup Steps

### Step 1: Install the plugin
Run: `npm install waha-openclaw-channel`
Or if using local path: copy to `~/.openclaw/workspace/skills/waha-openclaw-channel/`

### Step 2: Configure
Add to `~/.openclaw/openclaw.json` under `channels`:

\`\`\`json
{
  "channels": {
    "waha": {
      "enabled": true,
      "baseUrl": "https://api.whatsapp-channel.service/v1/waha-proxy",
      "apiKey": "<TENANT_API_KEY>",
      "session": "<SESSION_NAME>",
      "webhookPort": 0,
      "webhookPath": ""
    }
  }
}
\`\`\`

Notes:
- `baseUrl` points to the SaaS proxy (NOT localhost)
- `apiKey` is the tenant's `wcs_live_` key (NOT a WAHA key — SaaS handles that)
- `session` is assigned during QR pairing (use "default" until pairing)
- `webhookPort: 0` disables local webhook server (SaaS handles inbound routing)

### Step 3: Restart gateway
Run: `systemctl --user restart openclaw-gateway`

### Step 4: Pair WhatsApp
Call action: `send` with parameter `{ "setup": "pair" }`
This returns a QR code URL. User scans with WhatsApp → Linked Devices.

### Step 5: Test
Send a test message:
Action: `send`
Target: `<user's phone number>`
Text: "Hello from WhatsApp Channel! Setup complete."

## After Setup
Once paired, the full WhatsApp SKILL.md loads automatically.
Available actions: send, poll, react, edit, unsend, pin, unpin,
read, delete, reply, plus 30+ utility actions.
See the main SKILL.md for full action reference.

## Troubleshooting
- "401 Unauthorized" → API key is wrong or expired
- "Session not found" → QR pairing not completed
- "Connection refused" → Gateway not restarted after config change
```

#### How It Works (Architecture)

```
┌─────────────────────────────────────────────────────────────┐
│ CURRENT (self-hosted)                                       │
│                                                             │
│ Agent → Plugin → WAHA (localhost:3004) → WhatsApp           │
│                  ↑                                          │
│           Tenant runs WAHA themselves                       │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ SAAS (agent-guided)                                         │
│                                                             │
│ Agent → Plugin → SaaS API Proxy → WAHA Worker → WhatsApp   │
│                  ↑                ↑                          │
│           baseUrl = SaaS URL     We run WAHA                │
│           apiKey  = wcs_live_    We manage sessions          │
│           webhookPort = 0        SaaS delivers inbound       │
│                                  via tenant's callback URL   │
└─────────────────────────────────────────────────────────────┘
```

The key insight: **the existing plugin works unchanged**. The only difference is:
- `baseUrl` points to our SaaS proxy instead of `localhost:3004`
- `apiKey` is the SaaS tenant key (our proxy authenticates and routes to the right WAHA worker)
- Webhook server is disabled — SaaS pushes inbound messages to the tenant's registered callback

The SaaS API proxy translates tenant API calls into WAHA calls on the correct worker:
```
Tenant: POST https://api.wcs.example/v1/waha-proxy/api/sendText
        Authorization: Bearer wcs_live_xxx
        Body: { "chatId": "972...", "text": "hello", "session": "prod" }

Proxy:  1. Validate wcs_live_xxx → tenant_id = abc123
        2. Lookup WAHASession "prod" for tenant abc123 → worker_id = 7
        3. Lookup Worker 7 → url = http://waha-node3:3004, api_key = internal_key_7
        4. Forward: POST http://waha-node3:3004/api/sendText
           X-Api-Key: internal_key_7
           Body: { "chatId": "972...", "text": "hello", "session": "abc123_prod" }
```

#### Cross-Platform Support

The onboarding skill can be adapted for other agent platforms:

| Platform | How the skill is delivered |
|----------|--------------------------|
| **OpenClaw** | SKILL.md in the npm package (native) |
| **ZeroClaw** | Plugin manifest + setup instructions |
| **NanoBot** | .nanobot skill file |
| **Claude Code** | .claude/skills/ directory skill |
| **Custom agents** | REST API docs + SDK (Node/Python/Go) |

For non-OpenClaw platforms, the "skill" is really just:
1. An SDK package (`npm install @wcs/sdk` or `pip install wcs-sdk`)
2. Initialize with API key: `const wcs = new WhatsAppChannel("wcs_live_xxx")`
3. Send: `await wcs.send("+972...", "hello")`

No plugin installation, no config files, no gateway restarts. Pure API.

---

### Path B: Traditional Web Onboarding (Setup Wizard)

For users who don't have an agent yet, or prefer a visual setup.

#### B1. Registration

```
┌─────────────────────────────────────────────────────┐
│  GET STARTED                                        │
│                                                     │
│  ○ Continue with GitHub                             │
│  ○ Continue with Google                             │
│  ──────── or ────────                               │
│  Email:    [________________________]               │
│  Password: [________________________]               │
│                                                     │
│  [Create Free Account]                              │
│                                                     │
│  No credit card required. 1,000 free messages/mo.   │
│  By signing up you agree to our ToS.                │
└─────────────────────────────────────────────────────┘
```

- OAuth preferred (GitHub/Google) — zero friction, no email verification
- Email signup requires verification before creating sessions
- Auto-provisioned on **Sandbox plan** (free, 1 session, 1000 msgs/mo)

#### B2. "How will you connect?" (routing screen)

```
┌─────────────────────────────────────────────────────┐
│  HOW WILL YOU USE WHATSAPP CHANNEL?                 │
│                                                     │
│  ┌─────────────────┐  ┌─────────────────┐          │
│  │  🤖 I have an   │  │  🔌 I'll use    │          │
│  │  AI agent       │  │  the REST API   │          │
│  │                 │  │                 │          │
│  │  OpenClaw,      │  │  Custom app,    │          │
│  │  ZeroClaw,      │  │  webhook        │          │
│  │  NanoBot, etc.  │  │  integration    │          │
│  │                 │  │                 │          │
│  │  [Agent Setup]  │  │  [API Setup]    │          │
│  └─────────────────┘  └─────────────────┘          │
│                                                     │
│  Either way, let's connect your WhatsApp first.     │
└─────────────────────────────────────────────────────┘
```

**"Agent Setup"** shows:
```
Your API key: wcs_live_a8f3k2m9... [📋 Copy]

Tell your agent:
"Add WhatsApp channel with API key wcs_live_a8f3k2m9..."

That's it. Your agent handles the rest.

Don't have the skill installed?
  npm install waha-openclaw-channel

Or download the onboarding skill:
  https://whatsapp-channel.service/skills/setup.md
```

**"API Setup"** continues to the visual wizard (B3).

#### B3. Connect WhatsApp (QR Pairing)

```
Step 1 of 3: Connect WhatsApp
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Scan this QR code with WhatsApp:

  1. Open WhatsApp → ⚙ Settings → Linked Devices
  2. Tap "Link a Device"
  3. Point camera at the QR code below

  ┌─────────────┐
  │  ██ QR ██   │    ← Live WebSocket stream
  │  ██ CODE██  │      Auto-refreshes on expiry
  │  ██ HERE██  │      Auto-detects successful scan
  └─────────────┘

  Status: ⏳ Waiting for scan...

  💡 Use a dedicated business number. The session
  stays connected 24/7 on our servers.
```

On successful scan → auto-advances:

```
  Status: ✅ Connected as +972-54-432-9000

  Session name: [production           ]
  (you'll use this name in API calls)

                          [Next →]
```

#### B4. Send Test Message

```
Step 2 of 3: Test It
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Let's verify everything works.

  Send a test message to your own number:

  Phone number: [+972544329000         ]

  [Send Test Message]

  ────────────────────────────────────

  ✅ Message sent and delivered!
  Check your phone — you should see it now.

                          [Next →]
```

#### B5. Integration Guide

```
Step 3 of 3: Start Building
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Your API key (save it — shown only once):

  ┌──────────────────────────────────────────┐
  │ wcs_live_a8f3k2m9x1p4q7... [📋 Copy]    │
  └──────────────────────────────────────────┘

  ── Choose your integration ──

  [Node.js] [Python] [Go] [curl] [OpenClaw]

  ┌─ Node.js ─────────────────────────────────
  │ import { WhatsAppChannel } from '@wcs/sdk'
  │
  │ const wcs = new WhatsAppChannel({
  │   apiKey: 'wcs_live_a8f3k2m9...',
  │   session: 'production'
  │ })
  │
  │ await wcs.send('+972544329000', 'Hello!')
  └────────────────────────────────────────────

  ┌─ OpenClaw tab ─────────────────────────────
  │ Already installed? Just tell your agent:
  │
  │ "Send hello to +972544329000 via WhatsApp"
  │
  │ Need to install? Run:
  │ npm install waha-openclaw-channel
  │
  │ Then add to openclaw.json:
  │ { "channels": { "waha": {
  │     "baseUrl": "https://api.wcs.example/v1/waha-proxy",
  │     "apiKey": "wcs_live_a8f3k2m9..."
  │ }}}
  └────────────────────────────────────────────

  ☐ Set up webhook for inbound messages (optional)
    Your webhook URL: [https://myapp.com/webhook    ]
    [Save webhook]

                    [Go to Dashboard →]
```

#### B6. Dashboard (day-to-day)

```
┌─────────────┬──────────────────────────────────────────┐
│ Dashboard   │  Messages today: 1,247 ↗                 │
│ Directory   │  Sessions: 2/2 (all online)              │
│ Sessions    │  Webhook delivery: 99.8%                 │
│ Settings    │  Usage: 4,200 / 10,000 msgs ████░░ 42%  │
│ API Keys    │                                          │
│ Webhooks    │  ┌─ Quick Actions ──────────────────┐    │
│ Analytics*  │  │ [Send test msg] [Add session]    │    │
│ Billing     │  │ [View API docs] [Get support]    │    │
│ Team        │  └──────────────────────────────────┘    │
└─────────────┴──────────────────────────────────────────┘
  * Analytics = Chatlytics Lite (Pro+ only)
```

#### B7. Upgrade / Downgrade

From **Billing** tab:
- **Upgrade**: Immediate, prorated. New limits apply instantly.
- **Downgrade**: End of billing period. Must remove excess sessions first if over new limit.

#### B8. Offboarding / Account Deletion

From **Settings → Danger Zone**:

```
⚠️  Delete Account

This permanently deletes:
• All WhatsApp sessions (phones unlinked)
• All contacts, messages, media, analytics
• All API keys (integrations stop immediately)
• All team member access

Type "DELETE MY ACCOUNT" to confirm:
[                                    ]

[Export my data first]          [Delete Account]
```

**Deletion timeline**:
- Day 0: Stripe cancelled, prorated refund issued
- Day 0: Sessions disconnected, API keys revoked (401 immediately)
- Day 0-7: **Soft delete** — tenant can email support to reverse
- Day 7-37: **Hard delete** — async job purges PG schema, S3 media, WAHA session data
- Retained: billing records (tax law, 7 years), anonymized aggregate metrics

**Involuntary offboarding** (non-payment):
- Day 0: Invoice fails → Stripe retries
- Day 3: 2nd retry → warning email
- Day 7: 3rd retry fails → account suspended (API returns 402, sessions stay alive)
- Day 30: Cancelled, sessions disconnected
- Day 37: Data deletion begins

---

## 4. Billing & Admin Panels

### Stripe Integration

- **Subscription lifecycle**: Create → trial (14 days) → active → upgrade/downgrade → cancel
- **Usage metering**: Message count via Stripe Usage Records, reported hourly
- **Checkout**: Stripe Checkout for signup, Customer Portal for self-service management
- **Dunning**: 3 retry attempts over 7 days, then suspend tenant (don't delete)
- **Webhooks**: `invoice.paid`, `invoice.payment_failed`, `customer.subscription.updated`, `customer.subscription.deleted`

### System Admin Panel (for us)

- Tenant list with search, status, plan, MRR contribution
- Global WAHA health dashboard (all nodes, all sessions)
- Billing overview (MRR, churn, plan distribution chart)
- Usage analytics (messages/API calls/media per tenant)
- Tenant impersonation (view their admin panel)
- Feature flags per tenant
- Support ticket integration

### Tenant Admin Panel (evolution of current)

Current React admin panel stays, with additions:
- **Auth**: JWT login (Auth0/WorkOS), MFA required
- **Billing tab**: Current plan, usage meter, invoices, upgrade button
- **API Keys tab**: Generate, revoke, scope management
- **Webhooks tab**: Configure endpoints, delivery logs, retry failed
- **Team tab**: Invite members, RBAC (Owner/Admin/Viewer)
- **Sessions tab**: Multi-session management, QR pairing per session

### Onboarding Flow

```
Sign up → Plan selection → Stripe Checkout → QR scan (WhatsApp pairing)
→ Configure webhook URL → Get API key → Send test message → Done
```

### Database Schema (key tables)

```sql
-- Shared schema
CREATE TABLE tenants (
  id UUID PRIMARY KEY, name TEXT, plan TEXT DEFAULT 'starter',
  stripe_customer_id TEXT, status TEXT DEFAULT 'provisioning',
  created_at TIMESTAMPTZ DEFAULT NOW(), config JSONB DEFAULT '{}'
);

CREATE TABLE api_keys (
  id UUID PRIMARY KEY, tenant_id UUID REFERENCES tenants(id),
  key_hash TEXT UNIQUE NOT NULL, -- SHA-256 of wcs_live_xxx
  scopes TEXT[] DEFAULT '{messages:send,messages:read,contacts:read}',
  expires_at TIMESTAMPTZ, revoked_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE usage_records (
  id BIGSERIAL PRIMARY KEY, tenant_id UUID REFERENCES tenants(id),
  metric TEXT NOT NULL, -- 'messages_sent', 'messages_received', 'api_calls'
  count INT NOT NULL, period_start TIMESTAMPTZ, period_end TIMESTAMPTZ
);

CREATE TABLE audit_log (
  id BIGSERIAL PRIMARY KEY, tenant_id UUID, actor_id UUID,
  action TEXT NOT NULL, resource TEXT, result TEXT,
  ip_address INET, created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Per-tenant schema (tenant_{id})
-- Same tables as current SQLite: contacts, dm_settings, allow_list, group_participants, analytics
```

---

## 5. Security & Compliance

### Authentication Layers

| Layer | Method | Details |
|-------|--------|---------|
| API (programmatic) | Bearer API keys | `wcs_live_` prefix, SHA-256 hashed, scoped, 90-day max age |
| Admin panel | OAuth 2.0 (Auth0/WorkOS) | MFA required, session cookies (HTTP-only, Secure, SameSite=Strict) |
| Service-to-service | mTLS | Short-lived certs via cert-manager |
| WAHA instances | Per-instance API keys | Stored in Vault, never in env vars |

### Data Security

- **Encryption in transit**: TLS 1.3 everywhere, mTLS internally
- **Encryption at rest**: PostgreSQL TDE, S3 SSE-KMS (per-tenant key), LUKS encrypted WAHA volumes
- **Media**: ClamAV scan, UUID-based filenames (no path traversal), presigned URLs with 15-min expiry
- **Retention**: Configurable per tenant (default: 90 days messages, 30 days media)
- **GDPR**: Data export API, deletion API (30-day completion), DPA for EU tenants

### Top Threats & Mitigations

| # | Threat | Impact | Mitigation |
|---|--------|--------|------------|
| T1 | Cross-tenant data leakage | CRITICAL | Schema-per-tenant + dedicated DB users |
| T2 | WhatsApp session hijacking | CRITICAL | Encrypted volumes, no shell in containers, network isolation |
| T3 | Webhook SSRF | HIGH | Block private IPs, DNS rebinding defense, isolated egress |
| T4 | API key leakage | HIGH | GitHub secret scanning, IP allowlisting, anomaly detection |
| T5 | Malicious media | HIGH | ClamAV, UUID filenames, separate media domain |
| T6 | Webhook replay/forgery | MEDIUM | HMAC-SHA256 signing, timestamp replay protection |
| T7 | Message flooding | MEDIUM | Per-tenant/per-chat rate limits, auto-mute |
| T8 | SQL injection | CRITICAL | ORM (Prisma/Drizzle), minimal DB privileges, WAF |
| T9 | Admin session hijacking | HIGH | HTTP-only cookies, CSP, session binding to IP/UA |
| T10 | Supply chain attack | CRITICAL | npm audit, pin Docker digests, Trivy scanning, SCA |

### Compliance

- **WhatsApp ToS**: Opt-in tracking, 24h messaging window enforcement, template validation, rate limiting new conversations
- **GDPR**: Schema isolation, data export/deletion APIs, DPA template, EU hosting option
- **SOC 2**: Audit logging from day 1, 6-month observation period, controls mapped to Trust Service Criteria

### Security Implementation Priority

**Phase 1 (launch blockers)**: API keys, schema isolation, admin auth+MFA, TLS, webhook signing, rate limiting, SSRF protection, audit logging

**Phase 2 (first 90 days)**: Vault secrets, container hardening, media scanning, retention automation, monitoring/alerting, GDPR APIs

**Phase 3 (6-12 months)**: SOC 2 audit period, pen test, DPA template, data residency

---

## 6. Infrastructure & DevOps

### Cloud Strategy: Hetzner + Cloudflare

Why Hetzner: 3-5x cheaper than AWS. WhatsApp doesn't need geographic proximity (messages route through Meta). Use Cloudflare for CDN/edge/R2.

### Cost at Scale

| Scale | Infra | Monthly Cost |
|-------|-------|-------------|
| MVP (10 tenants) | 1x CX41 (8vCPU/16GB), managed PG, CF free tier | ~$45 |
| Growth (100 tenants) | 2x CX41 + 1x CX31, managed PG, CF R2 | ~$150 |
| Scale (500 tenants) | K8s 5x CX41, managed PG + replica, Redis | ~$500 |
| Full (1000 tenants) | K8s 12x CX41 + 2x CX51, PG HA cluster | ~$1,200 |

### WAHA Session Density

- Idle session: ~50MB RAM, <1% CPU
- Active session: ~100MB RAM, 5% CPU
- **Target: 30 tenants per CX41** (with burst headroom)

### Scaling Roadmap

| Phase | Trigger | Orchestration |
|-------|---------|---------------|
| MVP | <30 tenants | Docker Compose, single node |
| Multi-node | >30 tenants or CPU >70% | Add WAHA workers via Ansible |
| K3s | >150 tenants or >4h/week ops | Lightweight Kubernetes |
| Full K8s | >500 tenants | Node autoscaling, DB replicas, Redis cluster |

### CI/CD

GitHub Actions: lint → typecheck → test → security scan → build images → DB migration → rolling deploy

- Admin panel: Cloudflare Pages
- Backend: Docker images → rolling restart (zero downtime)
- WAHA: Version management with canary rollouts

### Monitoring Stack

Prometheus + Grafana + Loki (self-hosted on Hetzner).

Per-tenant metrics: message volume, API latency, error rate, webhook delivery success, WAHA session health.

Alerts: session down >5min (critical), error rate >5% (warning), webhook failing (warning), disk <15% (critical).

### Disaster Recovery

| Component | RPO | RTO |
|-----------|-----|-----|
| PostgreSQL | 5 min (WAL) | 1 hour |
| WAHA sessions | 6 hours | 15 min |
| Media (R2) | 0 (replicated) | 0 |
| Full platform | 6 hours | 1 hour |

Automated backups every 6 hours to R2. WAHA sessions are the hard part — failover requires QR re-scan.

---

## 7. WAHA Scaling Model (from official docs)

> Source: WAHA Scaling article (dev.to, Aug 2024) + waha.devlike.pro/docs

### Key Facts (corrects DevOps agent assumptions)

The DevOps agent assumed ~30 sessions per server. WAHA's actual benchmarks:

| Engine | Sessions | CPU | RAM |
|--------|----------|-----|-----|
| NOWEB | 50 | 150% | 4 GB |
| NOWEB | 500 | 300% | 30 GB |
| WEBJS | 10 | 270% | 2.5 GB |
| WEBJS | 50 | 1500% | 20 GB |

**We use NOWEB.** A single Hetzner CX41 (8 vCPU, 16 GB) can handle **~200 sessions** comfortably. A CX51 (16 vCPU, 32 GB) handles the full 500.

### Scaling Strategy: Sharding (NOT one-per-tenant)

WAHA is **stateful** — sessions have a live WebSocket connection to WhatsApp that cannot be moved between nodes. All API requests for a session MUST be "sticky" to the worker running that session.

WAHA's recommended pattern:

```
[Your App] → [Sharding Logic] → picks correct WAHA Worker by session lookup
                                      ↓
         ┌──────────┐  ┌──────────┐  ┌──────────┐
         │ Worker 1  │  │ Worker 2  │  │ Worker N  │
         │ NOWEB     │  │ NOWEB     │  │ NOWEB     │
         │ ~200 sess │  │ ~200 sess │  │ ~200 sess │
         └──────────┘  └──────────┘  └──────────┘
```

**Entities schema** (from WAHA docs):
- **Worker**: `id, url, api_key, capacity` — represents one WAHA instance
- **WAHASession**: `id, name, user_id, worker_id` — maps session to worker
- **Tenant/User**: `id` — the customer

**Session placement**: Query workers with `capacity > 0`, pick highest available capacity, create session on that worker, decrement capacity, save `user ↔ session ↔ worker` mapping.

**Request routing**: Look up WAHASession by tenant, get `worker_id`, route API call to that worker's `url` with its `api_key`.

**Each worker needs its own storage** (file or MongoDB). `WHATSAPP_RESTART_ALL_SESSIONS=True` restarts ALL sessions on a worker — disable it and manage session lifecycle in your app.

**WAHA Dashboard**: Run a dedicated WAHA instance as a dashboard (no sessions) to manage all workers from one place.

### Corrected Cost Model

| Scale | WAHA Workers | Server | Monthly Cost |
|-------|-------------|--------|-------------|
| 10 tenants (20 sessions) | 1 NOWEB | CX21 (4 vCPU, 8 GB) | ~$8 |
| 100 tenants (200 sessions) | 1 NOWEB | CX41 (8 vCPU, 16 GB) | ~$16 |
| 500 tenants (1000 sessions) | 3 NOWEB | 3x CX41 | ~$48 |
| 2000 tenants (4000 sessions) | 8 NOWEB | 8x CX51 | ~$250 |

This is **10x cheaper** than the per-tenant model the DevOps agent proposed.

---

## 8. Backup & Recovery Policy

### What's Backed Up

| Data | Method | Frequency | Retention | Priority |
|------|--------|-----------|-----------|----------|
| PostgreSQL (all tenant data) | pg_dump + WAL archiving | Continuous WAL, daily full dump | 30 days | CRITICAL |
| WAHA session auth state | Volume snapshots | Every 4 hours | 7 days | CRITICAL — loss requires QR re-scan |
| Media files (S3/R2) | Cross-region replication | Real-time | Per tenant retention setting | HIGH |
| Config & secrets | Vault snapshots | Daily | 90 days | HIGH |
| Redis (cache/queues) | No backup — ephemeral | N/A | N/A | LOW |

### Recovery Scenarios

| Scenario | RTO | RPO | Procedure |
|----------|-----|-----|-----------|
| Single tenant data loss | 15 min | 5 min | Restore schema from WAL point-in-time |
| WAHA worker crash | 2 min | 0 | Auto-restart via K8s/Docker, sessions reconnect |
| WAHA session auth lost | 5 min | 4 hours | Restore volume snapshot, sessions auto-reconnect. If snapshot too old → QR re-scan |
| Full database loss | 1 hour | 5 min | Restore from daily dump + replay WAL |
| Complete datacenter failure | 4 hours | 6 hours | Failover to standby, restore backups, tenants re-scan QR |

### Tenant Self-Service

- **Export**: `GET /api/v1/tenant/export` — async job produces ZIP (contacts, messages, settings, media links)
- **Delete**: `DELETE /api/v1/tenant/data` — full erasure within 30 days (GDPR compliant)

---

## 9. Customer Support (AI-Powered)

### Tier 1: AI Agent Support (24/7, instant)

Deploy an **OpenClaw agent** as the support bot, eating our own dog food:
- Trained on product docs, API reference, common issues, and changelog
- Lives in Discord, the admin panel (chat widget), and a dedicated WhatsApp number
- Handles: onboarding questions, API usage help, error message explanation, billing FAQ
- Escalates to human when: billing disputes, session failures > 30 min, security concerns
- **Knowledge sources**: docs site, FAQ, CHANGELOG, API OpenAPI spec, common error patterns

### Tier 2: Human Support

| Plan | Channel | SLA |
|------|---------|-----|
| Sandbox | Discord + docs only | Best effort |
| Starter | Email + Discord | 48h response |
| Pro | Priority email + Discord | 4h response |
| Enterprise | Dedicated Slack/Teams channel | 1h response, named account manager |

### Support Tooling

- **Admin panel "impersonate"** — support can view tenant's panel to diagnose issues
- **Session health dashboard** — instant visibility into tenant's WAHA status
- **Automated alerts** — proactive outreach when session disconnects or error rate spikes
- **Runbook library** — documented procedures for common issues (session stuck, webhook failing, rate limited)

---

## 10. Documentation Site

### Structure

```
docs.whatsapp-channel.service/
├── Getting Started
│   ├── Quickstart (< 3 min to first message)
│   ├── Concepts (sessions, webhooks, actions)
│   └── Authentication (API keys)
├── API Reference
│   ├── OpenAPI 3.1 spec (auto-generated)
│   ├── Swagger UI (interactive)
│   └── Per-endpoint examples (curl, Node, Python, Go)
├── Guides
│   ├── Send your first message
│   ├── Receive messages via webhooks
│   ├── Manage groups
│   ├── Send media (images, videos, files)
│   ├── Handle contacts and directory
│   ├── Set up DM filtering
│   └── Integrate with [OpenClaw / ZeroClaw / NanoBot]
├── Admin Panel
│   ├── Dashboard overview
│   ├── Directory management
│   ├── Settings and configuration
│   └── Analytics
├── SDKs
│   ├── Node.js
│   ├── Python
│   └── Go
├── Billing
│   ├── Plans and pricing
│   ├── Usage metering
│   └── Invoices
├── Security
│   ├── Webhook signatures
│   ├── API key best practices
│   └── Data privacy
└── Changelog
```

### Tech Stack

- **Mintlify** or **Docusaurus** (developer docs standard)
- Auto-generated API reference from OpenAPI spec
- Code examples in multiple languages with copy button
- Search (Algolia DocSearch or built-in)
- Versioned docs (v1, v2 when API changes)

---

## 11. Discord Community

### Structure

```
WhatsApp Channel SaaS Discord
├── #announcements          — releases, downtime, features
├── #general                — community chat
├── #support                — AI bot + human escalation
├── #showcase               — "look what I built"
├── #feature-requests       — upvote system
├── #bugs                   — issue reports
├── #integrations           — platform-specific help (OpenClaw, ZeroClaw, etc.)
├── #api-help               — API usage questions
├── #self-hosted            — for open-source plugin users (pipeline to SaaS)
└── Voice Channels
    └── #office-hours       — weekly live Q&A
```

### Roles

- **Founder** — Omer
- **Team** — staff
- **Pro** — paying Pro/Enterprise customers (priority support channel)
- **Builder** — verified developers using the platform
- **Community** — everyone else

### Automation

- **Bot**: New member welcome with quickstart link
- **Support bot**: AI agent in #support (same as admin panel bot)
- **Status bot**: Posts when sessions go down, maintenance windows
- **Release bot**: Auto-posts from CHANGELOG on new versions

---

## 12. Value-Add Products

### 12a. Chatlytics Lite Integration

**Chatlytics Lite** (`D:\docker\chatlytics lite\`) is a Rust-native, multi-tenant WhatsApp analytics platform that:
- Ingests WAHA webhooks and stores/indexes messages in PostgreSQL + pgvector
- Provides REST API for querying, analytics, and semantic search
- Achieves 65x RAM reduction over v1 (< 120 MB for both binaries)
- Already multi-tenant with per-tenant AES-256-GCM encryption

**SaaS Integration**: Bundle Chatlytics Lite as a built-in analytics tier:

| Feature | Starter | Pro | Enterprise |
|---------|---------|-----|------------|
| Message count & volume | Yes | Yes | Yes |
| Contact analytics | - | Yes | Yes |
| Semantic search (pgvector) | - | Yes | Yes |
| Custom dashboards | - | - | Yes |
| Data export (CSV/JSON) | - | Yes | Yes |
| Webhook event replay | - | - | Yes |

**Architecture**: Chatlytics Lite runs as a sidecar service. Each tenant's WAHA webhook is dual-routed: one copy to tenant's callback, one copy to Chatlytics Lite for analytics ingestion. No extra tenant configuration needed — analytics "just work."

**Monetization**: Analytics is a Pro+ feature. Free/Starter see basic message counts only. Pro gets full Chatlytics search and dashboards. This is a natural upsell driver.

### 12b. Pre-Made Agent Marketplace

Offer **ready-to-deploy AI agent templates** that tenants can activate with one click:

| Agent Template | Description | Tier |
|----------------|-------------|------|
| Customer Support Bot | FAQ answering, ticket creation, human handoff | Starter+ |
| Appointment Scheduler | Calendar integration, booking/rescheduling via WhatsApp | Pro+ |
| Order Status Tracker | E-commerce order lookup, shipping updates | Pro+ |
| Lead Qualifier | Capture leads, ask qualifying questions, route to sales | Pro+ |
| Survey Bot | Send surveys, collect responses, aggregate results | Starter+ |
| Broadcast Manager | Scheduled broadcasts with opt-in/opt-out management | Pro+ |
| Group Moderator | Auto-moderate groups, enforce rules, filter spam | Starter+ |
| Onboarding Assistant | Walk new users through product setup via WhatsApp | Pro+ |

**How it works**:
1. Tenant browses marketplace in admin panel
2. Clicks "Activate" on an agent template
3. Configures variables (business name, hours, FAQ content)
4. Agent is deployed to their WhatsApp session
5. Runs on our infrastructure (OpenClaw-powered)

**Revenue**: Agent templates are a **premium add-on** ($10-50/mo each) or included in higher tiers. Enterprise gets custom agent development.

**Technical**: Each template is an OpenClaw skill package with pre-configured prompts, action routing, and conversation flows. The platform adapter interface (from Phase 1 decoupling) makes this work across any agent runtime.

---

## 13. Risk Matrix (Updated)

| Risk | Impact | Likelihood | Mitigation |
|------|--------|-----------|------------|
| WhatsApp bans sessions at scale | CRITICAL | MEDIUM | Rate limiting, anti-spam, ToS compliance. Offer Cloud API migration path for enterprise |
| OpenClaw SDK coupling too deep | HIGH | HIGH | Phase 1 priority — extract adapter interface. Budget extra time |
| WAHA upstream breaking changes | HIGH | LOW | Pin version, integration tests |
| Noisy neighbor on shared WAHA | MEDIUM | MEDIUM | Per-tenant rate limits, dedicated tier |
| PG migration data loss | HIGH | LOW | Dual-write period, checksums, rollback plan |
| QR scan onboarding friction | MEDIUM | HIGH | Live stream, auto-detect, clear instructions. Can't eliminate — WhatsApp requirement |
| AI support bot gives wrong answers | MEDIUM | MEDIUM | RAG on verified docs only, human escalation path, confidence threshold |
| Pre-made agents don't fit use cases | LOW | MEDIUM | Start with 3-4 high-demand templates, iterate based on feedback |

---

## 14. What's Missing / Next Steps

1. **Legal**: Terms of Service, Privacy Policy, DPA template, WhatsApp disclaimer (unofficial API)
2. **SDK/Libraries**: Python, Node.js, Go client SDKs for the API
3. **Documentation site**: Mintlify/Docusaurus, OpenAPI spec, quickstart guides
4. **Landing page**: Design + copy + pricing page + comparison pages
5. **Demo environment**: Sandbox with pre-configured session
6. **Domain & branding**: Product name, domain, logo
7. **Stripe account**: Set up products, plans, webhooks
8. **GitHub organization**: Separate repo for SaaS layer vs open-source plugin
9. **Status page**: Public uptime monitoring (Betteruptime or similar)
10. **Discord server**: Set up channels, bots, roles
11. **AI support agent**: Deploy OpenClaw bot on docs, Discord, admin panel
12. **Chatlytics Lite integration**: Wire up dual webhook routing, add analytics tab
13. **Pre-made agent templates**: Build first 3-4 templates
14. **Backup automation**: Implement pg_dump cron, WAHA volume snapshots, R2 lifecycle

---

*Generated by 5 parallel domain agents (Software Architect, Product Strategist, Security Engineer, Fullstack Engineer, DevOps Automator) + manual additions from WAHA scaling docs, Chatlytics Lite codebase analysis, and user input.*
