Versions
Nothing you type reaches a caller until you publish it.
Editing a flow that is already answering your phone does not write through it. It forks a draft, and the number goes on answering with the version you published until you publish again. So the editor is somewhere you can think out loud on a Tuesday morning without that being a live change to your phone system.
A call pins the version it started on. Publish a change while somebody is halfway through your menu and they finish on the version they began with; the next caller gets the new one. The pin holds inside a sub-flow too, where the graph being walked is not the graph the call came in on.
The reason is not tidiness. A call waiting at a menu is holding the identifier of the block it stopped at, and rewriting the graph underneath it would resume that person at a block which no longer exists: silence, or a hang-up, on a call that was going fine.
Every version is kept, with who published it and when. Restoring an older one copies it forward into a new draft rather than rewinding, so the history stays a record of what callers actually heard, which is the shape the question takes when something has gone wrong: what did people hear on Tuesday afternoon?
Follow a call from the first ringThe blocks
28 blocks, in six groups.
They are sorted the way you go looking for them: flow control, communicating, collecting input, routing, logic, and the ones that reach outside. Most working flows use six or seven. Eight of them, and what each one decides, are below.
A phone call arrives as a series of separate requests rather than as one long-running program, so a flow is walked rather than executed. The interpreter moves through blocks until it reaches one that needs something from the caller, writes down where it stopped, and picks up from there when the caller answers. Blocks that need nothing (a condition, a lookup, the hours check) happen inline in the same breath, so a caller does not wait on them.
Three ceilings sit on that walk, and each is there because the alternative is somebody’s phone bill. A request that takes too long is abandoned by the network, which to a caller is a dropped call, so a long stretch of work is broken into a second request rather than risked. There is a cap on how many blocks one request may run. And a Loop block cannot be published without a repeat limit, because a cycle with no ceiling never lets the caller go.
Blocks go onto the canvas by clicking as well as by dragging. Drag and drop cannot be reached from a keyboard, and a builder that needs a mouse is a builder some of your colleagues cannot open.
Eight of the 28
Business hours
Four exits from one saved schedule: Open, Holiday, Emergency, Closed. Runs before anybody could have been asked to answer.
Collect digits / Menu
As many keys as the tree needs, and two exits you did not choose: No input, and Invalid key. Both are wired like any other.
Transfer to queue
Names a queue and a priority. Two exits: Connected, or no agent before the timeout.
Voicemail
Records up to the length you set and transcribes unless you turn that off. A box with no greeting still takes the message.
Play message
Text spoken in a voice you pick, or a recording you uploaded. The same switch is on every block that says anything.
Hold music
Your audio or the default. In-queue flows only, and the pass restarts from the top for as long as somebody is waiting.
Announce wait time
Says about how long, from the queue's own figures. With no usable estimate yet it says nothing rather than guessing: people time their patience by that number.
Offer a callback
A key to press to hang up and be rung back. The second exit is the caller who would rather keep waiting.
Two executors
What a caller hears while waiting runs somewhere else.
A flow that answers a number and a flow that plays while somebody waits are two different kinds of thing, and we keep them as two. The waiting one is not walked and resumed: it is a document the network asks us for again, from the top, for as long as the caller is on hold. The only thing carried from one pass to the next is how long they have been there.
Inside that document the network accepts a short list of instructions and silently drops everything else. A transfer dropped in there does not fail. It simply never happens, and there is no error anywhere to tell you. So the palette offers a different set of blocks depending on which kind of flow you have open, and publishing refuses a block the flow’s own kind cannot run. That refusal is an error rather than a warning precisely because nothing else would ever report it except a confused customer.
The third kind answers no number at all. It is entered from another flow’s sub-flow block and returns to it, so a bilingual greeting or a look-the-caller-up step is written once and used from five flows instead of pasted into five. Nesting stops at five deep, and that is not a setting: a flow that can enter itself is a loop with a per-minute bill attached, and the caller hears the same menu for as long as it lasts.
Where the queue takes overHours
Whether you are open is decided inside the flow.
A business-hours block reads one of your saved schedules, in that schedule’s own timezone, and branches four ways: Open, Holiday, Emergency, Closed. It runs before there is any task for a person to be offered, which is the whole point of the ordering. Somebody dialling at nine in the evening should hear your closed greeting straight away, not wait in a queue nobody is watching until it gives up on them.
Holiday and Emergency were added to a block that already had flows published against it. Because those graphs are frozen and were wired for two exits, both new ones declare a fallback to Closed: without it, the first holiday after that change would have hung up on callers whose flows had always sent them to the closed greeting. Open declares no fallback on purpose: sending “we are open” down a Closed branch would read the wrong message to somebody the block had just decided to let in.
Schedules are shared, so a holiday added once applies in every flow that uses it, and so does turning emergency mode on. That switch does not wait for a publish, because the afternoon you need it is the afternoon you cannot afford to be editing a phone tree.
And the honest half of that: hours live on a schedule and nowhere else. There is no separate organization-wide switch, so a number that is not bound to a flow rings around the clock, by design. The hours check also fails open on anything missing. Closing a phone line is something you have to ask for, not something we do to you because a field was empty.
Reaching out
A flow can call out, to hosts you have named.
An HTTP block sends a request to a system of yours and puts the answer into the rest of the flow, so the next block can speak it, branch on it or pass it along. A second block looks things up inside Ringfully instead (a contact, an agent, a past call) with no network in the way. Both happen while the caller is on the line, which is the constraint everything below follows from.
A block like that is your configuration causing our servers to make a request, so it is fenced. It must be https, and the hostname has to be on your own organization’s list. Nothing is on that list to begin with. Adding a host is an administrator’s decision in settings (not something whoever is editing a flow can do by typing a new address into a block), and the entries are exact hostnames, because a wildcard would reopen the hole the list exists to close.
The check happens inside the name lookup rather than before it, so the address we approved is by construction the address we connect to. A redirect re-runs the whole check from the start. And the request is bounded (five seconds, a quarter of a megabyte, three hops) because a person is holding a phone to their ear while it runs.
How the rest of it is separatedPublishing
What publishing refuses, and what it only mentions.
Refused outright: a flow with no start, or with two. A required setting left empty, or a choice that is no longer one of the options: the queue somebody deleted last month. A block this kind of flow cannot run. A repeat with no limit. An address that is not https. Each one names the block on the canvas, so the message is somewhere you can act on rather than a list of complaints.
One refusal is not negotiable in either direction: a flow may never be set to dial an emergency number, and not the near-misses either: 1911 and 9911 are somebody reaching for the same three digits. A caller who got there through an automated menu would give a dispatcher no location and nobody to talk to.
Mentioned but not blocked: an exit with nothing connected to it. That usually means “and then hang up”, and treating it as an error would make ordinary flows unpublishable. So the warning says which of the two it is (the call ends there, or it follows the fallback exit instead) and lets you decide.
A flow that still answers a number cannot be deleted. It tells you which numbers and asks you to point them somewhere else first, because quietly turning those lines back into something else would change where your calls go without anybody seeing it happen.
6 ways to start
Greeting, then your team
A short greeting, then every caller to a queue. The simplest flow that works.
Open and closed hours
Your team during business hours, voicemail outside them.
Main menu
Press 1 for one team, 2 for another, and something sensible for the caller who presses nothing.
English and French
The caller chooses, then hours are checked and the call is routed. Everything after the choice is spoken in the language they picked.
Look the caller up first
Check the number against your contacts, greet regulars by name, send priority customers to a queue of their own.
While the caller waits
Hold music, a wait estimate, and the option to hang up and be called back. Assigned to a queue rather than to a number.
A template is copied into your flow, not linked to ours. Yours is yours from the moment it exists, and a later change on our side must never rewrite a phone tree that is answering calls.
What this does not do
There is no rehearsal. Nothing in the builder plays a flow back to you or walks a pretend caller through the canvas, so the way to hear what you drew is to publish it and dial the number. Publishing to a spare number first is what people do, and it works, but it is a habit rather than a feature.
Nothing keeps a trail of which exit each caller took. The interpreter knows where a call is while it is happening and the call record says what happened to it, but the two are not joined up into a report. So “how many people pressed 2 last month” is a question this product cannot answer today.
Publishing happens when you press publish. You cannot line a version up to go live at midnight: if a change should land outside your opening hours, somebody presses the button then. The exception is the emergency override, which is deliberately the thing that needs no publish at all.
One block depends on something an account may not have configured yet, and publishing warns rather than refusing: until it is set up, every caller down that branch goes straight to a person. That is the safe direction, and we would rather tell you what will happen than pretend the branch is broken.
If one of those is the thing that decides it for you, ask. I would rather tell you where the product really is than have you find out on your second call.