Documentation

PanelOps Setup Guide & Docs

Everything you need to set up and run PanelOps on your SMM panel — WhatsApp command reference, role tables, verification flow, reply modes, and API endpoints.

Want the full feature breakdown?

See every capability across all 8 categories with visual examples.

View Features →

Getting Started

How do I set up the PanelOps WhatsApp bot?

1. Sign up with your WhatsApp number

Create your account at /signup. Enter your phone number, verify via OTP sent to WhatsApp, and set a password. No email required — phone + password login only.

2. Connect your WhatsApp instance

Navigate to Dashboard → WhatsApp Numbers. Click "Connect" and scan the QR code with your WhatsApp. The bot goes live in under 30 seconds. No cables or third-party apps required.

3. Connect PerfectPanel API

Go to Bot Settings → Panel tab. Enter your PerfectPanel URL and Admin API key. The bot connects via PerfectPanel Admin API v2, enabling real-time order checks, refills, cancellations, speed-ups, balance queries, and service lookups from WhatsApp.

Bot Settings → Panel tab
Panel URL:  https://yourpanel.com
API Key:    your-admin-api-key-here

4. Choose your chat mode

Bot Settings → General tab. Three modes available: Auto (fixed hardcoded replies), AI (all replies reformatted through LLM), or Custom (replies from your message templates table, falls back to hardcoded if empty).

5. Add WhatsApp groups

Go to Groups in the dashboard. Groups appear automatically after the bot receives a message from them. Toggle Support (bot responds) and Marketing (bot broadcasts) per group. Silent mode lets the bot process and log without sending any replies.

Order Commands

How do customers check an order status or request a refill on WhatsApp?

Quick reference — customer commands

helporder <id/ids>refill <id/ids>refill status <id/ids>cancel <id/ids>speed up <id/ids> (or start)refund <id/ids>partial <id/ids>fake complete <id/ids>balanceticket <id>my username

The ID can come before or after the word — refill 1234567 or 1234567 refill both work.

Example:

one — id: 1234567

many — ids: 1234567,891011,1213141,...

order <id/ids>

Check order status. Returns service name, status (Pending/In Progress/Completed/etc.), start count, remains, charge, and provider.

Example messages
order 1234567
order 1234567,891011,1213141

refill <id/ids>

Submit a refill request. Bot auto-validates eligibility (order must be Completed or Partial) before submitting. Returns service name, link, qty, and start count.

Example messages
refill 1234567
refill 1234567,891011,1213141

refill status <id/ids>

Check the progress of a refill you already requested. Shows current status and remaining count per order.

cancel <id/ids>

Cancel an order. Checks eligibility before submitting. Bot confirms with next steps. Cooldown applies between cancel requests for the same order.

speed up <id/ids> (or start)

Request order speed-up (resend). Validates active order status, submits priority flag, and confirms. "start" works as an alias for "speed up".

refund <id/ids>

Submit a refund request. Eligibility check runs first. Logged with full provider context including Provider OID.

partial <id/ids>

Request a partial refund for an under-delivered order. Validates and submits via panel API.

fake complete <id/ids>

Report an order marked complete that was not actually delivered. Sent for manual review.

cancel or refill <id/ids> (combined requests)

Name two compatible actions in one message and the bot handles both. Allowed pairs: cancel + refill, refill + refund, refill + partial, cancel + refund, speed up + cancel, speed up + refund. The bot runs the first action’s normal eligibility and cooldown checks, then confirms both requested actions in one reply and logs the order under a combined label (e.g. "Cancel/Refill") for your team.

Example messages
cancel or refill 1234567
refill or partial 1234567,891011

balance

Check your PerfectPanel account balance. Cooldown applies to prevent spam.

ticket <id>

Check the status of a support ticket in the panel.

my username

Show the panel username registered to your WhatsApp number.

help

Display the full command menu. Always hardcoded — identical in all chat modes.

Ticket AI

How does PanelOps automatically answer panel support tickets?

Support Status Progression

Open

Default on creation

Escalated

Notifies provider group

Ticketed

Panel ticket opened

Resolved

Issue closed

Ignored— skip and close without action (no notification)

Update via <ids> set-<status> in WhatsApp or bulk-select rows in Dashboard → Message Logs.

Enabling Ticket AI

Go to Bot Settings → Panel tab. Enable the "Ticket AI" toggle. Set your ticket subject filter (default: "Orders Support- AI"). Customers must open tickets with this subject for AI handling.

bot_config keys
ticket_ai_enabled       = true
ticket_poll_subject     = "Orders Support- AI"
ticket_poll_interval    = 60  # seconds between polls
ticket_signature        = "Support Team"
ticket_reply_staff_name = aisupport

Command tickets — automatic detection

Tickets containing action keywords (Speedup, Refill, Cancel, Refund, Partial) plus one or more 4-12 digit order IDs are treated as commands. The bot fetches live order data from the panel API, logs the entry with serial number + provider + provider OID (exactly like a bot command), and posts an AI-generated reply confirming the action.

Command ticket processing
# Ticket message: "speedup my order 54321"
# Bot detects: action=Speedup, order_ids=[54321]
# Fetches: order status, provider, external_id
# Logs: action=Speedup, serial=#1247, provider=your-provider.com, provider_oid=2323223
# Posts reply: "Speed-up request submitted for #54321..."

Support tickets — general questions

If no action keyword is found, AI generates a general support reply. Logged as "Ticket AI Reply" with any order context found in the message.

Duplicate prevention

Built-in locking prevents the same ticket from being replied to twice, even when multiple background workers are running simultaneously.

Signature enforcement

The bot strips any AI-generated sign-off from the reply and appends your configured ticket_signature. Fallback: "Support Team". Ensures consistent branding in all ticket replies.

Customer Verification

How does PanelOps verify new WhatsApp customers against the panel?

Verification Chat Flow

1
Hello
Welcome! Please enter your PerfectPanel username to verify your account.
2
johndoe123
Account found. A 6-digit code has been sent to your panel support ticket. Enter it here.
3
284719
Verified! You can now check orders, request refills, and use all bot commands.

Step 1 — Greeting

Customer sends any greeting message ("hello", "hi", etc.) to the group or in DM. Bot sends the welcome message asking for their panel username.

Step 2 — Username lookup

Customer sends their PerfectPanel username. Bot validates the username via PerfectPanel API. If found, a 6-digit OTP code is created and sent to the customer via a panel support ticket.

Step 3 — OTP verification

Customer enters the 6-digit code. Bot verifies it (10-minute expiry, configurable max attempts). On success, the customer's WhatsApp number is permanently linked to their panel username.

Configurable limits
verification_enabled          = true
verification_max_attempts     = 3
verification_cooldown_seconds = 300   # 5 min after max attempts

Bulk verify — !verify-users

Admin command. Verifies all members in the current group under a given username at once. Useful when migrating an existing customer base.

Example
!verify-users johndoe123

Managing customers from dashboard

Dashboard → Customers shows all verified users with their panel username and last active time. Actions: manually verify (skip OTP), block (prevents further commands), or delete (remove verification).

Admin & Staff Commands

What admin and staff commands does PanelOps support?

Full command cheat sheet — copy and share with your team:

CommandDescription
!statusAccount summary — member since, total messages, groups & people
!broadcast <msg>Send message to all support-enabled groups
!support enable|disableToggle bot responses for this group
!marketing enable|disableToggle marketing broadcasts for this group
!silent enable|disableToggle silent mode (process but no replies)
<ids> set-<status>Update log status; set-escalated notifies provider group
!config set <key> <value>Live config update — persists to DB immediately
!config get <key>Read a config value
!config listList all bot_config keys and values
!verify-users <username>Bulk verify all members in this group
!remove-users <username>Unverify all users under this username
!usersList all verified users
!groupsList all whitelisted groups
<ids> refill-verifyLive count vs panel data — refill analysis
<ids> provider-statusShow Provider OID + Provider Status per order
<ids> panel-statusFull order details from panel

!status

Show your account summary: member-since date and days active, total message count, chat mode and cooldown, group breakdown (Support / Silent / Provider / Marketing) and people breakdown (Admins / Staff / Customers). Works in DM or any group.

Example response
Member since: 04 Jun 2026 (12d 3h 5m)
Total messages: 18,420
Chat mode: ai | Cooldown: 30s
Groups — Support: 8 | Silent: 1 | Provider: 3 | Marketing: 5
People — Admins: 2 | Staff: 4 | Customers: 142

!broadcast <message>

Send a custom message immediately to all support-enabled groups. Useful for urgent announcements, service outages, or promotions.

Example
!broadcast Maintenance scheduled tonight 11 PM - 1 AM UTC. Orders will process normally.

!support / !marketing / !silent enable|disable

Toggle group flags inside the target group. Takes effect immediately on the next message — no reload needed.

Run inside the group
!support enable
!marketing disable
!silent enable

Leave Group (Dashboard)

Removes the bot from a WhatsApp group entirely — not just from your dashboard list. Click "Leave" on the Groups page. The bot leaves on every connected WhatsApp number on your account (in case more than one of your numbers is in that group), then the group is removed from your list. There is no WhatsApp command for this — it is dashboard-only.

Where to find it
Dashboard → Groups → [Leave] on the group row

<ids> set-<status>

Update the support_status of a message log entry. When set to "set-escalated", the bot sends the provider order IDs to the mapped provider WhatsApp group for cross-panel follow-up.

Example
54321 set-escalated
54321,54322 set-resolved
# Valid statuses: set-open | set-escalated | set-ticketed | set-resolved | set-ignored

!config set <key> <value>

Update a bot_config setting live without restarting. Changes persist to the database immediately. Admin-only command.

Examples
!config set chat_mode ai
!config set cooldown_seconds 60
!config set marketing_interval_hours 4
!config set failed_order_alert_enabled false
!config set priority_actions Cancel,Refund,Partial
!config list
!config get chat_mode

<ids> refill-verify

Admin + staff command. Shows live count vs panel data for each order ID — used to justify or dispute a refill request without the customer seeing. Works in DM or group.

Example
54321 54322 54323 refill-verify

<ids> provider-status

Comma-separated order IDs followed by "provider-status". Shows Provider OID and Provider Status per order. No ownership check — for staff use only.

Example
54321,54322 provider-status
# Response:
# #54321 | Provider OID: 2323223 | Provider Status: In Progress
# #54322 | Provider OID: 6565655 | Provider Status: Canceled

Failed-order alerts (automatic)

No command needed. Whenever a verified customer runs an order command (refill, cancel, speed up, refund, partial, fake complete, or refill status) and any order comes back with a Failed status from your panel, the bot privately messages your owner and admin numbers with the failed order ID(s), the requested action, the customer’s panel username, and the order’s provider. Staff are not notified. Each failed order alerts only once every 6 hours, so customer retries never spam you. The alert is sent even when the group is in silent mode. Toggle it any time in Bot Settings → General (“Failed-order alerts”) or with !config set failed_order_alert_enabled true|false.

Example DM to admins
⚠️ Failed Order Alert

Order IDs: 8910112,1259654 failed
Action: Refill
Customer: johndoe123
Provider: your-provider.com

Chat Modes

What is the difference between Auto, AI, and Template reply modes?

Auto mode (default)

All bot replies use fixed hardcoded strings. Fast and completely predictable. No AI calls made for command replies. Dirty commands (order ID + action + frustrated text) still trigger AI consolation when AI is configured.

AI mode

All customer-facing command replies are reformatted through LLM. Unrecognised messages are routed to AI with full PerfectPanel context. Dirty commands always get a merged reply (action result + consolation). Auto language detection.

Custom mode

Replies served from your message_templates table (35+ keys covering every bot interaction). Falls back to hardcoded strings if a template is empty or missing. Changes to templates take effect on the next message — no restart.

Template key examples
# Template keys (sample)
welcome_message
verification_username_prompt
verification_code_sent
verification_success
refill_submitted
cancel_submitted
speedup_submitted
balance_cooldown
ticket_signature

AI consolation — works in all modes

When a customer sends an order ID + action keyword + extra frustrated text (a "dirty command"), the bot always executes the action first and then generates a merged empathetic AI reply. This works regardless of chat_mode as long as LLM credentials are configured. The log is automatically flagged as priority.

Marketing Broadcasts

How do scheduled marketing broadcasts work?

Adding broadcast messages

Dashboard → Marketing. Click "Add Message" and write your promotional text. Supports full WhatsApp formatting (*bold*, _italic_, ~strike~, `mono`). Multiple messages rotate automatically.

Scheduling configuration

Bot Settings → General. Set marketing_interval_hours (base interval). A random jitter of 0–60 minutes is added to each broadcast to avoid predictable patterns that trigger spam filters.

bot_config keys
marketing_interval_hours = 4

Timezone support

Set your timezone from Settings → Timezone using UTC offset format: UTC, UTC+6, UTC-5, etc. Do not use IANA timezone names (e.g. Asia/Dhaka) — use UTC offsets only. The dropdown shows UTC-12 through UTC+14. The owner's timezone drives daily reset times (e.g. messages today); each user can also set their own display timezone for timestamps.

Per-group targeting

Only groups with marketing_enabled = true receive broadcasts. Toggle per-group from Dashboard → Groups or via !marketing enable|disable in the target group.

SMM Providers

How does PanelOps sync services and escalate to SMM providers?

Adding a provider

Dashboard → Providers → Add Provider. Enter the provider name, panel URL, and API key. Click Sync to fetch the initial service catalog and account balance.

Service catalog sync

Every sync fetches the full service list from your provider panel. Services are updated or added automatically. New services detected on subsequent syncs trigger a WhatsApp notification to admin-role numbers.

is_new tag logic
# First sync: baseline — nothing tagged new, no notification
# Subsequent sync: new services tagged is_new
# Notification sent to admin-role numbers only (not staff)

Balance tracking

Account balance is fetched alongside the service catalog on every sync. Best-effort — a sync succeeds even if the balance call fails.

Auto-sync and locking

Each provider has a configurable sync interval. Auto-sync runs automatically in the background. Built-in locking prevents duplicate syncs. Disable a provider to pause auto-sync for it.

Provider escalation group

Map a WhatsApp group to a provider in the dashboard. When a log entry is escalated (<ids> set-escalated), the bot sends the provider order IDs to that provider group for cross-panel investigation.

Service search

Dashboard → Service Search. Search across all synced providers by service name or ID. Filter by provider. Paginated results.

Roles & Access

What are the owner, admin, and staff roles and permissions?

PermissionOwnerStaff AdminStaff
All bot commands
!config set/get/list
!broadcast to all groups
Group flag toggles (!support / !marketing / !silent)
Bulk verify/remove users
<ids> set-<status>
<ids> refill-verify
<ids> provider-status
<ids> panel-status
Dashboard — Bot Settings, Templates, Groups, Marketing
Dashboard — Customers, Providers, Service Search
Dashboard — Message Logs
Dashboard — Billing
Dashboard — Admin & Staff, Settings

Owner

Full bot and dashboard access. The phone number used to sign up becomes the owner. Authenticates with phone + password.

Staff Admin

Dashboard access: Bot Settings, Templates, Groups, Marketing, Customers, Message Logs, Providers, Service Search. Bot commands: all except !config set/get/list.

Staff

Dashboard access: Message Logs only. Bot commands: refill-verify, provider-status, panel-status, set-<status>.

Adding staff — OTP verified flow

Dashboard → Admin & Staff → Add Number. Enter the staff phone number. Bot sends a 6-digit OTP to their WhatsApp. They enter the code to verify. System auto-generates a random password and sends login credentials to their WhatsApp.

API endpoints
POST /api/v1/admin-numbers/send-code   → sends OTP to WhatsApp
POST /api/v1/admin-numbers/verify      → verifies OTP, saves to tenant_admins

API Reference

What API does PanelOps use to connect to PerfectPanel?

Authentication — phone + password

No email. Phone-based OTP for signup, phone + password for login. Returns HttpOnly JWT cookies (separate secrets for tenant and admin panel).

Auth endpoints
# Signup (new phone only)
POST /api/v1/auth/phone/send         { phone }
POST /api/v1/auth/phone/verify       { phone, otp, password }

# Login
POST /api/v1/auth/login/phone        { phone, password }

# Forgot password
POST /api/v1/auth/phone/forgot-password/send    { phone }
POST /api/v1/auth/phone/forgot-password/reset   { phone, otp, new_password }

# Session
GET  /api/v1/auth/me
POST /api/v1/auth/logout
POST /api/v1/auth/refresh

Bot config — GET / PATCH

Fetch and update the bot_config table for the authenticated tenant. All saves trigger a live reload of the bot — no restart needed.

Config endpoints
GET  /api/v1/config
PATCH /api/v1/config   { key: string, value: string }

POST /api/v1/config/validate-panel

Message logs

Searchable log history with support status management. Bulk status update supported.

Log endpoints
GET  /api/v1/logs?date=&action=&status=&priority=&page=
PATCH /api/v1/logs/{id}/support-status   { status }
POST /api/v1/logs/bulk-status            { ids: [], status }

Providers & services

Full CRUD for SMM providers plus sync and paginated service search.

Provider endpoints
GET    /api/v1/providers
POST   /api/v1/providers
PATCH  /api/v1/providers/{id}
DELETE /api/v1/providers/{id}
POST   /api/v1/providers/{id}/sync

GET    /api/v1/providers/services?q=&provider_id=&sort=&limit=&offset=

Groups

Manage whitelisted groups — toggle support, marketing, and silent flags.

Group endpoints
GET    /api/v1/groups
PATCH  /api/v1/groups/{id}   { support_enabled, marketing_enabled, silent_mode }
DELETE /api/v1/groups/{id}
POST   /api/v1/groups/sync
POST   /api/v1/groups/{id}/leave

Admin & Staff numbers

Two-step OTP-verified flow for adding admin/staff WhatsApp numbers.

Admin number endpoints
GET    /api/v1/admin-numbers
POST   /api/v1/admin-numbers/send-code   { phone }
POST   /api/v1/admin-numbers/verify      { phone, code, role }
DELETE /api/v1/admin-numbers/{id}

Billing

In-app card payments (Stripe) and crypto payments (Coinbase Commerce, Cryptomus), with in-place upgrade/downgrade.

Billing endpoints
GET  /api/v1/billing/plans
GET  /api/v1/billing/config
POST /api/v1/billing/subscribe       { plan_id }
POST /api/v1/billing/setup-intent
GET  /api/v1/billing/payment-method
POST /api/v1/billing/payment-method  { payment_method_id }
POST /api/v1/billing/crypto/charge   { plan_id }
POST /api/v1/billing/change-plan     { plan_id }
GET  /api/v1/billing/usage
GET  /api/v1/billing/invoices

Message templates

Read and update individual template keys. Reset to default is supported per key.

Template endpoints
GET  /api/v1/templates
PATCH /api/v1/templates/{key}   { value }
POST  /api/v1/templates/{key}/reset

Ready to get started?

Create your account