Skip to main content
You just bought your first DID and you have never touched an IVR. The first-flow wizard in the Orbit console turns five short screens into a working auto-attendant: a published flow with an opening greeting, one keypad menu, one queue for a human to answer, and a voicemail fallback, ready to receive calls. This guide runs the wizard once, then reads back everything it wrote so you own the result instead of inheriting it. If you would rather start from raw JSON, work through Build and ship your first IVR flow. If you want the drag-and-drop canvas from the start, use First IVR via the Visual Builder canvas. This guide is the shortest path from “new number” to “calls get answered.”

1. What the wizard outputs

The wizard writes three things, all live when the run finishes:
  1. A published IVR flow. It authors a starter DSL graph (greeting, menu, queue, voicemail fallback, hangup), runs the graph validator, and publishes the draft to the live snapshot, so an attached number answers it on the first ring.
  2. A connected queue. The menu’s key 1 branch feeds an ACD queue the wizard creates; your team answers it from the dashboard like any other inbound call.
  3. A DID routing entry. Pick one of your numbers on the last screen and the wizard writes the number’s inbound routing row. Skip that screen and attach a number later (section 6).
The graph is ordinary Orbit IVR DSL, the same { nodes, edges } object the API and the visual builder read and write. Nothing the wizard produces is wizard-only: every node below is editable in the DSL, on the canvas, or through PUT /api/v1/voice/ivr-flows/:id.

2. Run the wizard

Open Voice → IVR Builder. On a workspace with no published IVR flow, the builder opens the first-flow wizard. Answer its five screens: The final screen lists your numbers. Pick the DID this flow should answer, or skip it. Finish. The wizard saves the draft, runs the validator, publishes, and, if you picked a number, attaches it. The closing panel shows the new flow’s ivr_* identifier; keep it for the API calls below. Ten minutes in, you have a number that greets callers, rings a human on 1, and takes a message from everyone else. The rest of this guide makes the generated flow legible so you can change it.

3. Inspect what it wrote

Open the flow in Voice → IVR Builder, or fetch the definition with GET /api/v1/voice/ivr-flows/:id. The generated graph for the answers above:
The graph the wizard writes
Read it node by node against the screens you answered: On the canvas the same graph renders as a five-step tree: Start, Play Audio, and Menu at the trunk, the queue and the voicemail-to-hangup path as the two branches. Pick your IVR surface: canvas or DSL walks that mapping in detail, including the export/import round-trip if you ever move a hand-edited graph back onto the canvas.

4. Extend in DSL

The smallest useful edit: press 2 should ring a mobile phone. That is one new node, one new edge, and one added menu option. The menu node before:
Before
And after, with the new transfer node beside it:
After
plus the edge that wires key 2 to it:
New edge
Submit the full definition to PUT /api/v1/voice/ivr-flows/:id. The validator runs before persistence, exactly as it did on the wizard’s save: a malformed graph returns 422 IVR_FLOW_GRAPH_INVALID and nothing is stored, so a bad edit can never reach your callers. Re-publish after the save to move the edit into the live snapshot.
Outbound termination is Devotel-only. A transfer node whose destination is a raw SIP URI is rejected by the validator with transfer_external_sip; set transferTo to an E.164 phone number or an on-net extension. See Build and ship your first IVR flow for the full rule.

5. Test with the simulator

Drive a scripted caller through the graph before the next real call. POST /api/v1/voice/ivr-flows/:id/simulate (or Simulate in the builder toolbar) consumes a turns array and replays the walk a real call would take. Walk one: press 1, land in the queue.
cURL
Transcript
The caller heard the greeting (say), was offered the menu (gather), pressed 1, and entered the queue (enqueue), where the walk ends as answered. Walk two: no valid key, fall back to voicemail. Send "turns": [{ "digits": "9" }] and the menu takes the default edge:
Transcript
Run both walks after every edit. A red simulation (a 422, or a reached_nodes list missing the node you expected) catches a routing regression before it costs a live minute.

6. Attach a DID and place the first real call

If you picked a number on the wizard’s last screen, this step is already done; verify it under Numbers → your number → Routing, where the inbound type reads ivr and names your flow. To attach later, or to move the flow to a different number, set the routing row:
cURL
The attach is immediate. Call the number from your mobile: you should hear your greeting, press 1 and reach the queue’s hold music, hang up, call again, press 2 and reach the transfer target, then call once more and stay silent at the menu to land in voicemail. The call appears in the dashboard’s call log with its duration and disposition, which closes the loop: wizard output, live on a DID, answered end to end.

7. Promote to the visual builder when edits outgrow the DSL

Stay in the DSL while your edits are node-and-edge sized; the JSON above is the whole contract, and it diffs cleanly in code review. Move to the canvas when the tree stops fitting in your head: a second menu level, speech intents instead of keypad digits, or per-node funnel analytics you want to click through rather than query. The builder reads and writes the identical graph, so promoting loses nothing: open the flow in Voice → IVR Builder and keep editing on the canvas.