SUPPORT.TWILIO.COM END OF LIFE NOTICE: This site,, is scheduled to go End of Life on February 27, 2024. All Twilio Support content has been migrated to, where you can continue to find helpful Support articles, API docs, and Twilio blog content, and escalate your issues to our Support team. We encourage you to update your bookmarks and begin using the new site today for all your Twilio Support needs.

How to Handle “No Answer” and “Busy” Status With a Python Flask Server When Call Forwarding

When forwarding calls, there are instances when the call is not answered (i.e. busy or not well completed). Our customers often want to initiate another action in these scenarios (e.g. redirect the call to another number or connect the caller to a voicemail).

Using Twilio Programmable Voice, we can build a small application that will monitor in an asynchronous way the next action that can be executed by monitoring calling parameters.


This tutorial is for developers at a beginner level or advanced level or for any person that wants to build their first application with Twilio and understand Callbacks and Webhooks, it is recommended that we at least can install and have the following tools:

  • Python
  • Pip
  • Flask
  • A code Editor
  • Ngrok
  • Twilio Account

Use Case

We want to build an application that firstly forwards incoming calls from Twilio number to a cellphone number, in case nobody picks up We will make that the caller does not get any dead air or that the call is missed, We will ensure the caller goes to a Voicemail from Twilio in case the call gets no answered and in case of Busy the call will go to another phone number, We are making sure here that in both scenarios the caller gets to a different possible destination instead of just a missed call.

To do this, We will build a Webserver for webhooks from which Twilio will request instructions from.

When our Twilio phone number is dialed, Twilio will first look for the configuration the number has for incoming calls, in our case, we are setting Twilio uses a Webhook URL to get new instructions, this URL will be our Flask server, and our code will be hosted in it, this server will send TwiML that Twilio will execute creating the Call Forwarding,

A second call will be generated the difference from a regular call forwarding is that in the previous TwiML received We will also have another URL endpoint, which will be an Action URL, this will be used for Twilio to send a few parameters in which one of them will be Twilio reporting the DialCallStatus

Possible DialCallStatus values are:

Value Description
completed The called party answered the call and was connected to the caller.
answered When calling a conference, the called party answered the call and was connected to the caller.
busy Twilio received a busy signal when trying to connect to the called party.
no-answer The called party did not pick up before the timeout period passed.
failed Twilio was unable to route to the given phone number. This is frequently caused by dialing a properly formatted but non-existent phone number.
canceled The call was canceled via the REST API before it was answered.

In this use case, we will be reporting no-answer and busy to our Webhook Server and executing an action that will send the call to a different TwiML.

Setting Up Our Machine

We are going to install the tools that we need in order for our Flask Server to run smoothly.

A Flask server is defined as server software that is capable of running HTTP requests on the public Internet private LAN, and private WANs and comprises of one or many computers bundled together and dedicatedly working for running the software application on the worldwide web.

Install Python

To initiate we will need to install Python in our machine, if you’re using a Mac or Linux machine, you probably already have Python installed.

You can check this by opening up a terminal and running the following command:

python3 --version 

In case you see that there is no Python we can do it by following this guide, which will show how to install it for either Windows, Mac, or Linux Computer:

normally we will just need to download a file and run the installation wizard, then check again with the python3 --version and confirm we have Python installed.

Install PIP

PIP is a package management system used to install and manage software packages/libraries written in Python. These files are stored in a large “online repository” termed as Python Package Index (PyPI). pip uses PyPI as the default source for packages and their dependencies. So whenever you type:

pip install package_name

pip will look for that package on PyPI and if found, it will download and install the package on your local system.

Install it on Mac:

Install it in Windows:

You can check that it is correctly installed by running pip3 --version on either Mac or Windows.

Install Flask Server

Now that we have PIP we can install Flask by running the command: pip3 install flask

We can see if Flask is well installed by running the command: flask --version we should see the Flask version that we have installed on our Windows or Mac computer.

We can download Visual Studio Code which is going to be our Code Editor to write Python for our Flask server application:

Test Flask Server

In Visual Studio Code, we can create a new file called and add these lines to it:

from flask import Flask
app = Flask(__name__)

def hello():
  return "Hello World!"

if __name__ == "__main__":

Now run it. In your terminal, type:


You should see the output:

* Running on 

Navigate to http://localhost:5000 in a browser. You should see a “Hello World” message.

Note: In the case, the "python" gives you an error, you can try "python3"

This is showing us that the Server is running as expected and now we are good to make our Application.

Create the call forwarding in your App:

We are firstly making the call forwarding, You need to create a file in Visual Studio Code, we can call it

from flask import Flask, request

import logging


app = Flask(__name__)

@app.route("/forward", methods=["POST","GET"])

def Incoming():

return ('<Response> <Dial Timeout="10" action="/Dialstatus" method="GET"> +1858258587 </Dial></Response>', 200)

if __name__ == "__main__":, port=4000)

Notice that here we will specify what TwiML will be returned to Twilio to be executed, we are currently setting that we will be going to do forwarding to number +1858258587.

Also, we are setting here the "action" attribute as /Dialstatus which we have not built in our app yet.

This current call can work but we are still not able to handle situations for unanswered or busy calls.

Add an endpoint Webhook in Application for DialStatus:

In order to manage calls that could not be answered or are busy, We need to add a few lines in our same file in Visual Studio for the /Dialstatus endpoint URL which we set as the Action attribute:

from flask import Flask, request

import logging


app = Flask(__name__)

#This is to do the forwarding of the call:

@app.route("/forward", methods=["POST","GET"])

def Incoming():

return ('<Response> <Dial Timeout="10"
action="/Dialstatus" method="GET"> +1858258587 </Dial></Response>', 200)

#This will be for monitoring the DialStatus parameter that We will receive from Twilio
@app.route("/Dialstatus", methods=["POST","GET"])

def WebhookTestInbound():
call_status = request.values.get('DialCallStatus', None)
if call_status == 'no-answer':

return ('<?xml version="1.0" encoding="UTF-8"?> <Response> <Say>hi please leave a message after the tone</Say> <Record playBeep="true" /></Response> ', 200)

elif: call_status == 'busy':
return ('<?xml version="1.0" encoding="UTF-8"?> <Response> <Say>Sending the call to secondar contact</Say> <Dial>+573022918290 </Dial></Response> ', 200)

return'', 204
if __name__ == "__main__":, port=4000)


Notice that now this application is making that in /Dialstatus route we will receive the parameter of the status of the previous outbound dial call to our server and if the DialCallStatus is no-answer or busy We will return now different TwiML for each scenario, in this example, we are sending the call to record a Voicemail for the unanswered call and We are sending the call to a different number for the Busy call, you can modify to do any TwiML like sending the call to another Webhook URL, play a message, etc. 

Run the file with python3, and then test the flask server in Localhost with the route we gave it, in this case, localhost:4000/forward and localhost:4000/Dialstatus if you put this in your browser, in the terminal of Visual Studio we can check if the responses were successful:

Run it with Ngrok

Now we want to make this server accessible from the public internet, to do that we can use Ngrok, if you don't have Ngrok installed you can follow these instructions:

When you install it we will run it in our computer terminal "ngrok http 4000"

This is making that now the localhost:4000 is transformed into a reachable link from the internet and the /Forward and /Dialstatus will be also online since they are in our which is our Flask server that contains both in localhost:4000 now tunneled as the Ngrok URL. 

Now we copy the forwarding URL from this output and we can add that Ngrok URL to the Number in "when a call comes in" in the Twilio console so that we will first ensure we are forwarding calls and then the application itself will be running and making sure the Action URL with the /Dialstatus will be handling the no-answer and busy calls:

We can try testing the forward call and push to ignore the call, then We will be forwarded to Twilio voicemail and that's how We can handle forwarding calls using the Dialstatus parameters with our own built Webserver!

Have more questions? Submit a request
Powered by Zendesk