Next.js face · NestJS brain

UnifiedPBX — Self-Hosted Asterisk 22 IP PBX

A signed-in business phone system you can inspect: Next.js is the face, NestJS is the control plane, Asterisk 22 LTS is the muscle, and PostgreSQL owns extensions, queues, routes and trunks — generated conf files are output, not the place operators edit.

For companies that want recordings, trunks and extensions on a box they operate — not a locked UCaaS SKU.

Productized case-study delivery Scope-based estimator BYOC · Twilio · Telnyx · Sinch

Problems we solve

When the admin UI, generated files and AMI disagree, teams typically hit:

  • Admin UI, pjsip.conf and AMI each tell a different story
  • Operators SSH into extensions.conf for every change
  • Queue names sanitised in three places until files and telemetry disagree
  • AMI event socket mixed with commands desyncs the dashboard
  • System Info shells out on every click and blocks for seconds
  • Trunk shows healthy while failure rate stays 0.0 because attempts were never counted
  • Browser talking AMI/ARI — tenant crosstalk and an unversioned protocol
  • Hosted per-seat PBX fails buyers who must keep media on-prem

One platform: Admin change in Next.js → NestJS validates → PostgreSQL → generate PJSIP/queues/dialplan → debounced AMI reload → Asterisk 22 executes

IP PBX administration

  • Extensions with voicemail, forwarding, Follow Me, DND
  • Extension groups and ring strategies
  • Trunks, inbound/outbound routes and restrictions (STD/ISD/emergency)
  • IVR with DTMF maps, timeouts and exit actions
  • Queues with ring strategy, wrap-up and overflow
  • Conference settings and CDR with recording icons
  • Active calls, system info and extension summary

Control plane & operations

  • PostgreSQL as restore-able source of truth
  • Deterministic generated *.conf — operators do not edit them
  • Dual AMI sockets, action IDs, watchdog and circuit breaker
  • ARI for originate/bridge — not mashed in the browser
  • Trunk heartbeat worker (attempts vs failures)
  • Background network health table instead of live shell-outs
  • Optional Prometheus scrape plus JSON health APIs

Optional WebRTC on the same numbering plan

Desk phones and browser clients can share extensions. The admin never talks AMI; the SPA uses JWT REST and a UI-safe WebSocket.

  • Remote workers without a second numbering plan
  • Click-to-call from the signed-in product
  • Recordings and CDR still on your box
  • Tenant-safe events — not raw AMI in the browser

PJSIP/WebRTC on Asterisk 22. BYOC, own SIP trunks, or Twilio/Telnyx/Sinch selectable in the estimator.

Platform architecture

flowchart TB
  UI[Next.js admin JWT WebSocket]
  API[NestJS tenants generate AMI ARI]
  PG[(PostgreSQL source of truth)]
  Conf[Generated pjsip queues dialplan]
  AST[Asterisk 22 LTS]
  UI --> API
  API --> PG
  API --> Conf
  Conf --> AST
  API --> AST

Deployment: Cloud · VPS · On-premises · BYOC · Twilio · Telnyx · Sinch

Proven case study

This product is a productized delivery of the documented engineering case study — evidence stays on this page so you do not have to guess what was shipped.

  • 21:09 public Asterisk 22 walkthrough on its own watch page
  • PBX Monitor, CDR, extensions, trunks, IVR, queues captured from the running admin
  • Canonical queue Asterisk name persisted for files, AMI and UI
  • Lab snapshot numbers are not a published SLA
PBX Monitor trunk status with Active SIP trunk
Trunk health from heartbeat — not a hard-coded zero.
Call Detail Records list with ANSWERED and NO ANSWER
CDR with recording icons on the row.
Add Extension Features tab with voicemail and call forwarding
Features operators expect without editing conf by hand.
Add Call Queue form with ring strategy and agent timers
Queue identity is one persisted Asterisk name.

Full case study with video and FAQ →

Configure this scope & send RFQ →

Built for

IT / telecom leads

Operate Asterisk 22 with a control plane instead of snowflake files.

Regulated offices

On-prem or private DC selectable in the quote builder.

Self-hosted buyers

Recordings and trunks on a box you can inspect.

Ops teams

Health tables and workers instead of blocking OS calls on every dashboard hit.

Integrated vs fragmented stack

Traditional setupThis product direction
Edit pjsip.conf and the adminPostgreSQL owns the row; Asterisk consumes generated output
AMI in the browserNestJS AMI/ARI; SPA gets tenant-scoped events
Queue name in three sanitizersOne persisted Asterisk identifier
Locked UCaaS SKUAsterisk 22 LTS you operate

Outcomes

Establishes a signed-in admin for status, CDR, extensions, trunks, IVR, queues and conference with generated Asterisk files. Isolation that exists only as a dialplan naming convention is not claimed as tenancy — that is a different product line.

Deployment & carriers

  • Managed VPS — operate on your cloud account with runbooks.
  • Your cloud — AWS/GCP/Azure; you own the account.
  • On-premises — regulated or air-gapped cores (quote adjusted).
  • BYOC / own SIP — your carrier contract or trunks on the PBX we deploy.
  • Twilio / Telnyx / Sinch — CPaaS pass-through shown in the estimator (planning only).

Estimates are scope-based planning figures — not binding quotes. Taxes, carrier deposits, DIDs and third-party AI usage are scoped in discovery.

Frequently asked questions

Is this the confidential multi-tenant UCaaS case?

No. This is the self-hosted Asterisk 22 UnifiedPBX product. Multi-tenant IP PBX is a separate case study.

Is this FreeSWITCH CCaaS?

No. CCaaS seats on FreeSWITCH ESL is a different product page.

Can we keep our SIP trunks?

Yes. BYOC and own SIP trunks are first-class in the estimator.

Does the browser talk AMI?

No. NestJS owns AMI command/event sockets; the UI uses JWT and a safe WebSocket.

WebRTC?

Optional requirement in the quote builder — same numbering plan as SIP phones.

On-premises?

Yes. On-prem / private DC is a deployment option (quote adjusted).

Prometheus required?

Optional scrape; JSON health endpoints exist so Grafana is not mandatory.

Can you migrate from a hardware IPPBX?

Yes — see PBX migration solution and include current stack in the RFQ.

Requirements



Request formal quote