Appearance
Cloud PBX
Cloud PBX is the customer-facing visual call-flow editor for a tenant's phone system, built on top of a FusionPBX platform. It lets an admin see and change how their inbound numbers ring — through time conditions, a digital receptionist (IVR), ring groups and extensions — without touching the underlying PBX admin console, plus review call records and voice rates. It's used by customer/reseller admins managing their own organization's telephony (a platform superuser can additionally see a wholesale billing dashboard across all tenants).
What you can do
- Visual PBX Manager — a drag-and-connect canvas showing your call flow as columns: Inbound Numbers, Time Conditions, Digital Receptionist (IVR), Ring Groups, Extensions, Voicemail, and Call Forwarding. Real numbers/destinations render as nodes; an empty column shows a dashed "Activate" placeholder.
- Route an inbound number — drag a line from a number to a destination (extension, ring group, IVR menu, or time condition) to point it there, or click a number's destination picker.
- Enable/disable an extension — toggle a switch directly on an extension's node.
- Edit a record in place — double-click any node (a number, extension, ring group, IVR menu, or time condition) to open its edit form in a drawer, without leaving the canvas.
- Add a new record — click "Add" on a column header or empty-column placeholder to open the matching create form (opens the PBX Admin app in a new tab so in-progress canvas changes aren't lost).
- Open the underlying PBX box — an "Open in PBX" link, auto-signed-in, for anything the editor can't do.
- Ask the AI assistant — describe a routing change in plain language (e.g. "route the main line to reception") and let it propose and, on your confirmation, execute the supported actions.
- Call Records (CDR) — a searchable, filterable log of calls for your domain(s): from/to, duration, hangup cause, MOS/quality, direction, billing method, and sell rate, with a period selector (24h / 7 / 30 / 90 days) and click-to-filter Answered/Unanswered/Minutes stat cards.
- Customer Rates — the public retail voice rate deck (destination, prefix, connect cost, included seconds, cost per minute), with a South Africa vs. International split.
- Reseller Rates — the cost-based rate deck for reseller accounts (same shape as Customer Rates, gated to resellers).
- Telephony Settings — configure the org's SIP domain, SIP test-call credentials, codec, and FreeSWITCH ESL connection details.
- Billing dashboard (platform superusers only) — platform-wide call-billing rollup: revenue, gross profit, GP%, and supplier cost-anomaly / margin-alert queues, each linking straight into the relevant domain's admin call records.
Common tasks
Route a number to an extension or ring group Open the Visual PBX Manager. Drag a connector from the inbound number's node to the target destination node (or use the number's picker). The system validates the destination exists on your domain before writing. Re-pointing a number that's already routed elsewhere isn't possible from here — the underlying platform can't delete the old route, so you'll be told to clear it on the PBX first.
Set up an IVR (digital receptionist) menu In the Digital Receptionist column, click "Create receptionist" (or "Add" on the column header) to open the create form in the PBX Admin app. Once created it appears as a node here; route inbound numbers to it the same way you route to an extension.
Enable or disable an extension Find the extension's node in the Extensions column and flip its enabled/disabled toggle. This calls the PBX platform directly, so it needs the platform API key configured.
Use the AI assistant to change routing Open the assistant panel, describe what you want (e.g. "which numbers aren't routed anywhere?" or "route the main line to reception"). It reads your current domain configuration, proposes only actions that are actually possible (routing an unrouted number, or enabling/disabling an extension), and every proposed action is re-validated against the real config before it executes.
Review recent calls Open Call Records (CDR), pick a period (24h/7/30/90 days), and search or filter by any column. Click the Answered/Unanswered stat cards to filter instantly. Cost, margin and gateway columns are visible to staff only — a customer login never sees what a call cost the platform or which carrier it rode.
Check voice rates before quoting a customer Open Customer Rates (or Reseller Rates, if you're a reseller) and search by destination, prefix or country code to find the connect cost and per-minute rate for a destination.
Point the editor at the right SIP domain Open Telephony Settings and set the org's SIP domain (plus, if you place test calls from the browser, the SIP username/password and codec). The Visual PBX Manager and Call Records both default to this domain when no domain is given; if it isn't set, the manager shows a prompt linking straight to this settings page instead of an error.
Data model
Cloud PBX (the call-flow editor and its grids) owns no local database tables. It reads and writes live against two external APIs on every request:
| Source | What it provides |
|---|---|
CloudTools portal API (portal_pbx / cloudtools_portal) | Domain lookup, the dialable routing-options graph, inbound number routing, and CDR reads (route_number, list_routing_options, list_inbound_numbers, list_cdrs). |
FusionPBX platform API (fusionpbx) | Extension/ring-group/IVR/time-condition listings and uuids, extension enable/disable, billing metrics, rate decks (get_reseller_rates), and SSO deep-links into the PBX box. |
The editor never writes to the PBX database directly — every change goes through one of these two token-authed APIs. The only local record it produces is an AuditLog row for each routing change or extension toggle. Per-tenant Telephony Settings (SIP domain, test-call credentials, ESL connection) are stored under tenant.settings.telephony, not a dedicated table.
Configuration & integrations
- FusionPBX is the underlying telephony platform; the editor talks to it through two separate credentials resolved via
erp_credentials: the CloudTools portal token (routing reads/writes, CDR) and the PBX platform key (extension state, uuids, billing metrics, deep-link SSO). Extension enable/disable and "Open in PBX" links degrade gracefully — the routing graph still loads — if the platform key isn't configured. - Domain scoping: which PBX domain(s) an org can see/act on is resolved from its linked accounting records (a customer's own domain, plus a reseller's sub-accounts' domains); an org's SIP domain, set in Telephony Settings, is honoured as the default only when it's genuinely one of that org's own domains.
- Voice rate decks come from the same FusionPBX pricelist API: pricelist id
1for the customer/retail deck, and the box's own reseller-default pricelist for the reseller deck. - AI assistant uses the platform's configured LLM client, constrained to a fixed system prompt and a small, backend-validated action set (route a number, enable/disable an extension) — it can never invent a destination that doesn't exist in your live configuration.
- Double-clicking a node opens the matching record's CRUD form in the PBX Admin app (documented separately) via a same-origin deep link, rather than duplicating that record's edit UI here.
API reference
Beyond the rate-deck and call-log grids (generic grid CRUD, read-only — no create/edit/delete), Cloud PBX has a dedicated API mounted at /pbx (admin role required):
| Method & Path | Purpose |
|---|---|
GET /pbx/call-flow | The full call-flow graph for one domain: inbound numbers with live routing, and every destination (extensions, ring groups, IVR menus, time conditions) they can point at. Defaults to the org's configured SIP domain. |
POST /pbx/route | Route an inbound number to a destination. Refuses (409) to re-point a number that's already routed elsewhere. |
POST /pbx/extension-enabled | Enable or disable one extension. |
GET /pbx/cdrs | Recent call-detail records for one domain (newest first). |
GET /pbx/billing-metrics | Platform-wide call-billing rollup (revenue, GP, anomalies/margin alerts) — superuser only, unscoped by design. |
POST /pbx/assistant | Natural-language routing changes: sends the current config + operator message to the LLM, validates and executes any proposed actions, returns what happened. Staff/superuser only on customer-facing sites. |
The Call Records (pbx-call-logs), Customer Rates (pbx-customer-rates) and Reseller Rates (pbx-reseller-rates) screens are generic, provider-backed grids (GET /grid/{slug}/data) rather than bespoke endpoints — they're read-only (no create/edit/delete) since the underlying data lives entirely on the PBX platform.