How It Works
Dragon PBX delegates call routing to your application via HTTP.
The basics
Dragon PBX acts as a B2BUA (Back-to-Back User Agent) — it sits in the middle between callers and destinations, managing both sides of the call independently. The key difference from a traditional PBX is that routing logic isn't configured inside the system. Instead, when a call arrives, Dragon PBX asks your application what to do via a Webhook and JSON response.
Call flow
When a call arrives, this is what happens:
- Domain check — The system verifies the SIP domain is one it manages.
- Source identification — It determines whether the caller is a registered client or arriving via a trunk (matched by IP/CIDR).
- Authentication — Clients are challenged with SIP digest auth. Trunks are identified by source IP or authenticated via credentials.
- Dialplan lookup — The dialled number is matched against the caller's dialplan using pattern matching to find the CallHook URL.
- CallHook request — Dragon PBX POSTs call details (from, to, domain, call ID) to your CallHook URL.
- CallScript execution — Your endpoint returns a JSON array of verbs. The system executes them in order — playing announcements, connecting to destinations, or sending responses.
- Retry — If the call isn't resolved after the script completes, the system retries (up to 3 times), passing an incremented counter so your application can vary the routing.
Webhooks
Three webhook types give you control and visibility:
RegHook
Called when a SIP client registers. Your endpoint authenticates the client and returns a dialplan and optional codec preferences. This lets you dynamically control which numbers each client can reach and how calls are routed.
CallHook
Called when a call needs routing. Receives the caller, destination, domain, and retry count. Returns a CallScript — a JSON array of verbs that define the call flow.
StatusHook
Receives real-time notifications about call events: ringing, answered, hangup, transfer, playback progress, and more. Useful for logging, analytics, or triggering side effects in your application.
Example call script
A simple script that plays a greeting, rings a user, and then rejects with busy if they don't answer:
[
{"verb": "announce", "url": "file:/greeting.wav"},
{"verb": "connect", "dest": [
{"address": "1001", "type": "client", "timeout": 30}
]},
{"verb": "response", "code": 486}
]
Architecture
Dragon PBX is built on three core components:
- Drachtio — An open source SIP server that handles the signalling layer. Dragon PBX connects to it as a client application via the Drachtio SRF framework.
- RTPEngine — A media proxy that handles RTP streams, codec transcoding, and media relay between call legs.
- Redis — Stores ephemeral state: client registrations, contacts, assigned dialplans, and codec preferences, all with TTL-based expiry.
The application itself runs as a Node.js process. It wires together SIP events from Drachtio, media control through RTPEngine, and state management in Redis — then delegates all routing decisions to your HTTP endpoints.