On the FreePBX family, you build a call flow from the inbound route forward, wiring each piece as you go, instead of backward through dropdowns. Pick any DID, set the clock to any hour, and see where the call lands, with live status on every node.
Running VitalPBX? The same live canvas spans every tenant. Switch between them and read each one’s whole flow end to end, registration and queue state included.
FreePBX's destination dropdowns only contain modules that already exist. So to wire a new flow you build it backward: queue first, then the IVR that points to the queue, then the time condition that points to the IVR, then the inbound route that points to the time condition.
Or you go top-down with placeholder destinations, then circle back through every node to fix them once the real downstream module exists. Miss one and a holiday call lands in terminate.
Either way, building a 12-node call flow takes an afternoon and three context switches.
And there's no undo. Every fix is a fresh manual edit through the same backward chain.
Drop the inbound. Drop the next node, wire it. Drop the next, wire it. No node or wire is written to the PBX until you click Save.
Build the way you actually think about a call: from "the call comes in" toward "this is what answers."
Change your mind? Ctrl-Z. Linear undo on destination edits, plus an Activity Log that shows who changed what, and when.
You click into Inbound Routes. Then Time Conditions. Then the IVR. Then another Time Condition. Then a Ring Group that points to a Queue. Each screen tells you one step.
To answer "where does the main number go at 6:47pm on a holiday?" you open five tabs, build the path in your head, and hope you didn't miss a CFC toggle.
Pick a DID and the full graph renders: every route, every branch, every failover. Day/night overrides are visible. Holiday conditions are visible.
Simulate a time, the graph dims the paths that wouldn't fire. Open any node's details, edit it, save. Drag to rewire. Export as PNG for the customer handoff.
A ticket asks for one small change: a new IVR option, or someone out of a ring group. You open that module in FreePBX, change it, Submit, Apply Config. The main number tests fine.
The page you edited shows that one module. It doesn't show that the same ring group is where the holiday time condition sends calls, or that a second DID lands on that IVR. On a customer you set up two years ago, you don't remember either.
Nothing looks wrong on Friday. It turns up Saturday morning, or on the next holiday, when calls take the path nobody re-checked.
Open the module's details before you touch it. The Used by list names everything that sends calls there, so the holiday path and the second DID are on screen before you change anything.
Drag a wire to the new destination and the flow redraws with it. Nothing goes live until you click Apply Config, and the change goes in through FreePBX's own code, the same as Submit on its pages. If someone changed the same thing in FreePBX after you opened the call flow, the save stops and asks you to reload rather than write over it.
Try it in the live demo: pick After hours under Simulate time and Cloverdon's path stops at a red dot, a message that goes nowhere. Drag that port to any node and the path follows your wire.
You changed the time condition. Now you call the main number to hear what a caller hears. Then again from a cell, because the first call landed somewhere you didn't expect and you're not sure why.
The paths you can't dial are the ones worth worrying about. You can't call the main number at 6:47pm on Christmas. So you either wait for Christmas, or you roll the clock forward on a production PBX and misroute live calls to find out.
Usually it's fine. You find out it wasn't when the customer calls you.
Make the change, then look at it. The flow you just edited is on the canvas, and the graph shows where a call lands.
Set the clock to 6:47pm on December 25th and the paths that wouldn't fire dim out. Nothing gets dialed, nothing on the PBX changes, and you don't wait until Christmas to learn the holiday route pointed at an extension whose owner left in March.
Wrong turn somewhere? You see it before the caller does.
FreePBX could always do more than most dial plans ask of it. With the whole call flow in front of you, build what the business needs, not what was easy to check. Sometimes that's still five nodes.
A customer signs. On the kickoff call they tell you how calls should work: press 1 for sales, ring the front desk first, roll to the owner's cell after six, closed the week of Christmas. Normally you take notes, go build it backward through dropdowns, and send a screenshot two days later.
Inbound, time condition, IVR, queue, voicemail. Each one goes on the canvas as it comes up in the conversation, wired to the one before it. Save, hit Apply Config, and it's live. What you drew with them is the dial plan that's running, not a diagram of it that drifts out of date by month two.
Pick the DID and the whole journey renders: which greeting answers, what each key press does, which queue it lands in, who's sitting in that queue, and where the call goes when nobody picks up. Set the clock to 6:47pm, or to Christmas morning, and watch the path change. Most owners have never once seen their own phone system do this.
Your new hire opens the customer's graph and reads how the account is routed straight off the canvas. What used to be a week of shadowing whoever built it is one screen now.
A license is one-time and per PBX. It goes in with the rest of the build.
Every feature is built for one job: understanding and modifying production call routing without breaking it.
Drop the inbound, drop the next node, wire it, save. No more starting at the queue and walking backward through dropdowns to make destinations exist before the routes that point at them.
Lay out a whole new call flow on the canvas, from blank or from a copy of an existing one, and the PBX doesn't change. When it's ready, Publish shows you what it will create and flags any exit left unwired. Nothing is written until you click Build, and if building a piece fails, Publish removes the pieces it already built. Apply Config and it's live. Currently in Beta.
Type a greeting and hear it in a natural ElevenLabs or OpenAI voice, on your own key. Numbers, addresses and times come out right. It saves straight to FreePBX or downloads for VitalPBX, and keeps working without a license.
Extension nodes show a registration dot, green for registered and red for offline, with amber and purple chips beside it for DND and call forward. On queue and ring-group rows, each member gets its own status dot. Read live each time the graph loads.
Simulate any date and time. The graph dims paths that wouldn't fire and highlights the one that would. "What happens during the company event next Tuesday afternoon?" Pick the time and the graph shows you, instead of tracing it by hand.
Big call flows get unreadable. Collapse everything downstream of a node, from the node itself, and the diagram shrinks to the path you actually care about. A hidden branch is remembered by what it points at, so it stays hidden in every call flow that reaches it, not only the one you hid it from. Nothing is deleted, and you can reveal it any time.
Two production-shaped call flows: a law firm laid out both directions, and a medical practice in normal hours and after-hours. Sticky notes, multi-user attribution, layout direction, time-of-day simulation. All on one canvas.
Walk into a customer's PBX, pick the main number and read how it routes before you change anything. Export the diagram for the handoff.
The graph is the documentation, so it can't go stale in a wiki nobody updates. When a "why isn't my phone ringing?" call comes in, create a read-only login for whoever's helping: a junior tech, a teammate, or the customer if they can reach it. You both look at the same picture and walk the dial plan together on the phone while you fix it live. No PBX admin access changes hands.
Your backup admin doesn't need to know every page of the PBX admin UI. When a customer calls at 9pm because the main line goes straight to voicemail, they open the graph and see which time condition, holiday rule or CFC toggle sent it there.
On the FreePBX family, the complete read-only visualizer is free for good. Editing is the part a license buys, and you get it free for your first 30 days, no card. On VitalPBX, where Call Flow Studio is read-only for everyone, the free tier covers your first two tenants and the license is about scale.
$79 · one-time · per PBX · or buy a license →
FreePBX 14, 15, 16, 17 and FreePBX-based distributions: full editor (read + write), including commercial distros like PBXact and ClearlyIP and the community Incredible PBX. VitalPBX 3 and 4 get a first-class read-only visualizer. The platform is auto-detected at install. Self-hosted only. CFS installs over SSH as root. Don't see your PBX? Email support@callflowstudio.io.
Yes, and it stays free. On the FreePBX family the complete read-only visualizer is yours for good, no credit card and no expiry. Editing is the optional part: you get it for your first 30 days, and one Call Flow Studio license ($79, one-time and per-PBX) keeps it after that. On VitalPBX the free tier covers your first two tenants and the license opens the rest. No paywall, no locked-out screen. We never delete your data.
No. Your dial plan, extensions, call recordings and call records never leave your server; CFS has no way to send them and never asks for them. What does reach our server: the license check (regularly while CFS is in use), trial registration, activation, update checks, password resets, license release, optional feedback, and a notice when you uninstall. The app’s pages load no analytics, no CDN and no external JavaScript. The PBX does need a route out to us for the license check, so a box with no route out isn’t a fit. Text to speech, if you give it a key, goes from your PBX straight to ElevenLabs or OpenAI on your own account, never through us. Exactly what each one sends →