WhatsApp SaaS Admin

Enter your admin key to continue

Invalid admin key. Try again.

WhatsApp SaaS

Total Messages
Sent
Pending / Queued
Failed
Active Companies
Connected Phones
Banned
Usage by Company
CompanyStatusSent / LimitProgressSub ExpiresLast Message
Loading…
Usage by Phone Number
PhoneNumberStatusSentFailedLast Used
Loading…
Add New Company
All Companies
#NameAPI KeyStatusSent / LimitSub ExpiresActions
Loading…
Add Phone Number

After adding, a WhatsApp QR code will appear below. Scan it to connect.

Phone Numbers
Loading…
Phone Daily Limits

Set a daily send limit per phone to protect against bans. The hint shows the recommended limit based on the phone's age.

Loading…
Message Timeline
Test Message Sender
Global Send Delay

Default random delay between messages (milliseconds). Individual companies can override this.

Global Daily Limit

Default max messages per day for every company. A company's own daily limit overrides this. When the limit is hit, messages are scheduled for the next day instead of being rejected. Leave blank for unlimited.

Phone Daily Limit (anti-ban)

Max messages each phone number can send per day. When a phone hits this limit it is skipped by the balancer and the remaining messages wait until midnight reset. Protects your numbers from being banned. Recommended: 60–80 for new numbers, 150–200 for numbers older than 30 days. Leave blank for unlimited.

Global Working Hours

Restrict all outgoing messages to a time window (local time). Messages outside this window are queued until the window opens. Leave blank to allow sends at any time. A company's own working-hours override this global default.

Recipient Cooldown

Minimum gap between two messages to the same recipient. Set to 0 to disable. Default: 1 hour.

Global Outgoing Webhook

When a customer replies on WhatsApp, this URL receives an automatic POST with the message payload. A company's own webhook URL takes priority over this global one. Leave blank to disable.

Admin Key

Change the admin key used to access this dashboard and the admin API. Leave blank to keep the current key.

Default Auto-Reply Rules

When a customer replies, these global rules fire automatically. Company-specific rules (set in each company's detail modal) always take priority over these defaults. Match types: contains, exact, startsWith, regex.

Active Rules
Loading…
Loading chats…
Select a chat to start messaging
Pick a conversation from the list on the left
Select a company above.
Select a chat to view messages
Pick a conversation from the list on the left
▶ Message Delivery Workflow
End-to-end flow — from your system sending a request to the customer receiving the WhatsApp message.
1 · API Layer
API
📄Your System
(ERP / App)
Calls POST /send-message with number + customerName + token
🔑API Key Auth
(X-Api-Key)
Validates company API key from header
📊Monthly Limit
Check
429 if company exceeded subscription quota
📝Build Message
from Template
Merges header + customerName + URL + token + phones + signature
📞Verify Number
on WhatsApp
404 if number not registered on WhatsApp
2 · Daily Limit Decision
SERVER
Daily limit
hit today?
Checks phone todaySent vs max_daily_per_phone
📅Schedule for
Tomorrow
Saved as pending with scheduled_at = midnight UTC
OR
Add to Queue
(position N)
HTTP 202 returned immediately with estimated send time
3 · Queue Processing — 6 Steps in Order
QUEUE
① Working
Hours Check
Convert UTC → company/global timezone. Is current hour inside send window?
Outside window → sleep 60s → re-queue front
② Phone
Selector
Score = todaySent×seniority + failRate×30 + (cooldown?500:0). Lowest wins.
All phones full → sleep to midnight → re-queue front
No phone connected → sleep 5s → re-queue front
📷③ Recipient
Cooldown
Last sent to this number < cooldown (default 1 hr)? Don't spam same person.
Still cooling → move job to back of queue (others run first)
Entire queue cooling → sleep up to 60s → re-queue front
④ Random
Delay
Sleep random(delayMin, delayMax) ms. Company override → else global (default 2–6 s).
⑤ Typing
Simulation
Show "typing…" for √(len)×400 + random(300–800) ms, capped at ~5.8 s total.
📥⑥ Send
Attempt
client.sendMessage() via whatsapp-web.js through the selected phone.
Detached frame → sleep 3s → re-queue front (phone reconnecting)
4 · WhatsApp Send & Result
WA
📱Send via
whatsapp-web.js
Message sent through the selected connected phone
Success?
DB → sent
+ sent_at
Phone stats: todaySent++, cooldown starts
OR
DB → failed
+ error msg
consecutiveFails++. Alert if 5 in a row or >30% fail rate
5 · Client Receives
CLIENT
📱Customer's
WhatsApp
Receives the personalised payment reminder message
🔗Clicks Payment
Link
URL = payment_url + unique token → opens their invoice
💬Customer
Replies
Reply comes back to the same phone → appears in Chat inbox via SSE
Legend
API Layer
Server Logic
Queue Engine
WhatsApp
End Customer
Decision point
⚖ Smart Phone Balancer
Score = (todaySent × seniority) + (failRate × 30) + (onCooldown ? 500 : 0)Lowest score = selected first. Cooldown penalty (+500) almost always skips that phone.
Seniority factor = max(0.30, 1.5 ÷ (1 + age_days ÷ 20))Day 0→factor 1.5 (slow) · Day 10→1.0 · Day 40→0.5 · Day 90+→0.30 (fast)
Warmup daily caps: 0–4 d → 20, 4–8 d → 50, 8–15 d → 100, 15–30 d → 200After 30 days only the global max_daily_per_phone applies
Phone cooldown after each send = delayMax × seniorityFactorOld phones (factor 0.30) recover in ~1.8 s → send ~5× more than new ones
⌛ Delays & Human Simulation
Random delay between min–max seconds (per company or global)Prevents burst patterns WhatsApp flags
Typing duration = √(msgLength)×400ms (capped 5 s) + random(300–800 ms)10 chars ≈ 1.6 s · 100 chars ≈ 4.8 s · 200+ chars ≈ 5.3–5.8 s
Per-recipient cooldown (default 1 hr) checked before each sendIf still cooling and other jobs exist → job moves to back. If whole queue cooling → sleep up to 60 s.
🚫 Ban Detection
Alert if 5 consecutive send failuresMay mean phone is rate-limited or banned
Alert if failure rate >30% after 20+ sendsRe-alerts every 10 new failures
Auth failure or "banned" disconnect → immediate alert + auto-rerouteBalancer instantly switches to next best phone
📅 Deferred Messages
If daily phone limit is hit, message saved as pending for next dayscheduled_at = tomorrow 00:00 UTC
Midnight scheduler (runs every 60s) picks up due pending messagesRespects working hours window before sending
Random spacing between deferred messages — not all at midnight togetherAvoids suspicious burst at 00:00
Connected
Total Phones
On Cooldown
Next To Send
Active Alerts
Load Balancer — Live Snapshot auto-refreshes every 4 s
Seniority scoring: Older phones have a lower score multiplier, so they send more messages per day than new phones. Score = todaySent × 1.0 × seniorityFactor + failureRate × 30 + cooldown. Lower score = selected first. New phone factor ≈ 1.5 → old phone factor ≈ 0.3.
Phone Status Seniority Score ↑ Today Sent Total Sent Fail Rate Consec. Fails Cooldown Last Sent
Loading…
How Seniority Works
New Phone (Day 0)
Factor = 1.50
Each message adds 1.5 pts to score → selected ~5× less than a veteran phone
10 Days Old
Factor = 1.00
Balanced — each message adds 1 pt to score
30 Days Old
Factor = 0.60
Each message adds 0.6 pts → handles ~2.5× more than a new phone
90+ Days Old
Factor = 0.30
Senior phone — handles ~5× more than a new phone per day
Smart Alerts
0
🚫 Critical
0
⚠ Warnings
0
ℹ Info
0
✓ Resolved
Severity Type Phone Details Status Time Action
Loading…
How "Maybe Banned" Detection Works
⚠ High Failure Rate
Triggers when failure rate ≥ 30% after at least 20 sends. Re-alerts every 10 new failures.
⚠ 5 Consecutive Failures
Triggers when 5 messages in a row fail — even if overall rate is low. Resets on next success.
🚫 Banned
Triggers on auth_failure event or disconnected with reason containing "banned/blocked/logout". Balancer immediately routes traffic to the next best phone.
🔄 Switched To
When a phone goes down, an alert shows exactly which phone the balancer switched to — or warns if no phone is available.