Interactive voice response (IVR) solution

Build a modern IVR with Twilio to improve your customer experience with logic and AI-based self-service while reducing the need for agent intervention.

What’s possible with an intelligent IVR?

Improve your customer experience without adding complexity for agents.

  • Chat bubble with clock
    Call routing

    Route calls to the right person or department automatically to assist customers quickly.

  • Mobile notification
    Agent escalation

    Escalate calls to agents who can use context gathered by the IVR to pick up where it left off.

  • Package with heart
    Self-service automation

    Complete order processing, bill pay, appointment scheduling, and information retrieval without an agent.

  • User speech bubble
    AI virtual agents

    Deflect calls to virtual agents that can provide conversational AI experiences to save agent bandwidth.

  • Chat Bubble
    Proactive notifications

    Confirm appointments, provide critical account updates, and confirm delivery details quickly and easily.

  • Earth with a chat bubble icon
    Emergency notifications

    Make it easy for people to get critical information at scale without tying up phone lines.

How to build a modern IVR

Create a customizable IVR to expand and modernize your contact center.

Build flows from the widget library
Start with pre-built IVR flows in our visual editor, Studio. Then customize for your business with full control over your phone tree and logic.

Iterate and adapt on the fly
Twilio makes it easy to tweak your IVR flows as new customer needs emerge or your business processes change.

Automate basic self-service tasks
Build in the ability to confirm appointments, process payments compliantly, or retrieve information without requiring agent intervention.

Twilio products for IVR

Build a modern IVR with a strong connectivity foundation and customize with the exact functionality you need.

Step to setup



Learn more

1. Phone number

  • Buy a Twilio phone number
  • Port in a phone number

200+ number types, 100+ countries

Use your existing number

2. Connectivity

  • Use Twilio Super Network
  • Bring your own carrier (BYOC)

4,500 global carrier connections

Use your existing PSTN carrier

3. Build

  • Code with TwiML
  • Drag and drop in Studio

<Pay>, <Gather>,
<Say> commands to
handle common tasks

Low/no-code editor, templates for IVR flows

Explore TwiLM                  

Explore Studio 

4. Channels

  • Make or receive calls with Voice APIs
  • Send follow-up texts with Messaging

Text-to-speech, call
recording, Voice
Intelligence and Voice

SMS, MMS, WhatsApp, reliable real-time delivery

Explore Voice 

Explore Messaging          

Build and launch your IVR in days

Sign up for a free Twilio account to start building your new IVR flows today. Use quickstarts, up-to-date docs, the Twilio CLI, and Code Exchange to build a prototype quickly.

from twilio.twiml.voice_response import VoiceResponse

from ivr_phone_tree_python import app
from ivr_phone_tree_python.view_helpers import twiml

def home():
    return render_template('index.html')

@app.route('/ivr/welcome', methods=['POST'])
def welcome():
    response = VoiceResponse()
    with response.gather(
        num_digits=1, action=url_for('menu'), method="POST"
    ) as g:
        g.say(message="Thanks for calling the E T Phone Home Service. " +
              "Please press 1 for directions." +
              "Press 2 for a list of planets to call.", loop=3)
    return twiml(response)

@app.route('/ivr/menu', methods=['POST'])
def menu():
    selected_option = request.form['Digits']
    option_actions = {'1': _give_instructions,
                      '2': _list_planets}

    if option_actions.has_key(selected_option):
        response = VoiceResponse()
        return twiml(response)

    return _redirect_welcome()
require 'twilio-ruby'

class TwilioController < ApplicationController

  def index
    render plain: "Dial Me."

  # POST ivr/welcome
  def ivr_welcome
    response =
    response.gather(num_digits: '1', action: menu_path) do |gather|
      gather.say(message: "Thanks for calling the E T Phone Home Service. Please press 1 for
      directions. Press 2 for a list of planets to call.", loop: 3)
    render xml: response.to_s

  # GET ivr/selection
  def menu_selection
    user_selection = params[:Digits]

    case user_selection
    when "1"
      @output = "To get to your extraction point, get on your bike and go down
        the street. Then Left down an alley. Avoid the police cars. Turn left
        into an unfinished housing development. Fly over the roadblock. Go
        passed the moon. Soon after you will see your mother ship."
      twiml_say(@output, true)
    when "2"
      @output = "Returning to the main menu."


namespace App\Http\Controllers;

use App\Http\Requests;
use Illuminate\Http\Request;
use Twilio\Twiml;

class IvrController extends Controller
    public function __construct()
        $this->_thankYouMessage = 'Thank you for calling the ET Phone Home' .
            ' Service - the adventurous alien\'s first choice' .
            ' in intergalactic travel.';


     * Responds with a welcome message with instructions
     * @return \Illuminate\Http\Response
    public function showWelcome()
        $response = new Twiml();
        $gather = $response->gather(
                'numDigits' => 1,
                'action' => route('menu-response', [], false)

            'Thanks for calling the E T Phone Home Service.' .
            'Please press 1 for directions. Press 2 for a ' .
            'list of planets to call.',
            ['loop' => 3]

        return $response;

     * Responds to selection of an option by the caller
     * @return \Illuminate\Http\Response
    public function showMenuResponse(Request $request)
        $selectedOption = $request->input('Digits');

        switch ($selectedOption) {
            case 1:
                return $this->_getReturnInstructions();
            case 2:
                return $this->_getPlanetsMenu();

        $response = new Twiml();
            'Returning to the main menu',
            ['voice' => 'Polly.Amy', 'language' => 'en-GB']
        $response->redirect(route('welcome', [], false));

        return $response;
const VoiceResponse = require('twilio').twiml.VoiceResponse;

exports.welcome = function welcome() {
  const voiceResponse = new VoiceResponse();

  const gather = voiceResponse.gather({
    action: '/ivr/menu',
    numDigits: '1',
    method: 'POST',

    'Thanks for calling the E T Phone Home Service. ' +
    'Please press 1 for directions. ' +
    'Press 2 for a list of planets to call.',
    {loop: 3}

  return voiceResponse.toString();
}; = function menu(digit) {
  const optionActions = {
    '1': giveExtractionPointInstructions,
    '2': listPlanets,

  return (optionActions[digit])
    ? optionActions[digit]()
    : redirectWelcome();
package com.twilio.phonetree.servlet.ivr;

import com.twilio.twiml.TwiMLException;
import com.twilio.twiml.VoiceResponse;
import com.twilio.twiml.voice.Gather;
import com.twilio.twiml.voice.Play;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class WelcomeServlet extends HttpServlet {

    protected void doPost(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
            throws IOException {
        String mp3file = ""
                + "ivr-phone-tree-servlets/master/et-phone.mp3";
        VoiceResponse response = new VoiceResponse.Builder()
                .gather(new Gather.Builder()
                .play(new Play.Builder(mp3file)

        try {
        } catch (TwiMLException e) {
            throw new RuntimeException(e);
using System.Web.Mvc;
using Twilio.AspNet.Mvc;
using Twilio.TwiML;
using Twilio.TwiML.Voice;

namespace IVRPhoneTree.Web.Controllers
    public class IVRController : TwilioController
        // GET: IVR
        public ActionResult Index()
            return View();

        // POST: IVR/Welcome
        public TwiMLResult Welcome()
            var response = new VoiceResponse();
            var gather = new Gather(action: Url.ActionUri("Show", "Menu"), numDigits: 1);
            gather.Say("Thank you for calling the E.T. Phone Home Service - the " +
                       "adventurous alien's first choice in intergalactic travel. " +
                       "Press 1 for directions, press 2 to make a call.");

            return TwiML(response);

Build your first phone tree

Follow along with this quickstart to learn how to set up your first IVR phone tree with Twilio.

Quick deploy a basic IVR

Use our pre-built app in Code Exchange to deploy a basic IVR that uses SMS and Voice in minutes.

Tips for speech recognition and virtual agent bots with voice calling

Improve your IVR speech recognition performance with 11 best practices from our product team.

Prefer not to code? No problem.

Work with one of our trusted partners to get coding support or explore a pre-built IVR solution.

Work with Twilio Professional Services to set up global call tracking for your company
Work with Twilio Professional Services to set up global call tracking for your company

Why use Twilio to build an IVR

Increase customer satisfaction while reducing cost to resolution.