Build a Simple, Powerful, On-call Roster Notification Solution

February 04, 2021
Written by
Reviewed by


Picture the situation. You are working on a task that requires you to immediately connect to an on-call employee. You dial their phone number, but it hits their voicemail. Who do you call to resolve the situation?

This use case is not uncommon in organisations that utilise shifts or rosters for their workforce management, and it usually results in the employee having to manually search an on-call roster document for another phone number to call. This process is fine for some use cases, but imagine that the situation was time-critical and needed an immediate response, where every minute and second was critical. Would you want this process to be manual? Probably not.

So what can we do? We can build an automated notification solution using Twilio Programmable Voice, Twilio SMS and Twilio Functions.


If you are following along and want to implement this solution, you will need to have the following prerequisites:

You can see the full code on GitHub.


Organisations in various industries make use of on-call rosters to respond to events and emergencies outside of working hours. On-call employees are usually expected to be available at any time and with short notice. Clinicians, engineers, emergency services frequently using on-call systems.

An on-call system typically consists of a user interface, where an administrator updates the roster, and a notification mechanism. The inbound event to trigger a notification to the on-call person could be a sensor (IoT), a high severity ticket (webhook), a person in distress (SMS), or a patient contacting a clinician (call).

In this blog post, we will use a call as an example of the inbound event. We will focus on the notification mechanism with the on-call roster hosted in Twilio functions environmental variables. For a more advanced solution that allows you to create rules to automatically adjust your roster, you can consider expanding the solution by using Google Sheets or Microsoft Sharepoint. For Sheets you could explore the use of macros/formulas, and for Sharepoint you could use MS flow to automate the roster updates.

Consider the following use case:

Clinical laboratories usually consist of a number of medical technologists who all work on the analysis of specimens. However, there are certain cases where the expertise of a specialised clinician is required. A medical technologist has to access a portal and can manually call the first person, the secondary etc. on the roster. Wouldn’t it be easier to dial one number and automatically be able to speak to the ‘best’ available person?

Additionally, what if we could also detect when the primary on-call clinician is not available so we can automatically call the secondary, the tertiary, etc. This raises a few different edge cases that could also occur during the process, such as if the primary call hit voicemail, was busy, declined the call or the call timed out.

To detect voicemail we could use Twilio Answering Machine Detection (AMD) and for the rest we evaluate the status callback. The optional StatusCallbackEvent parameter lets you specify which call progress events Twilio will act on. You can use this parameter to tell Twilio to send information to the StatusCallback URL you specified when a call is initiated, ringing, answered, or completed.

The call flow will be as follows:

Call flow for notifications


For the purposes of this tutorial, we would also like to record the calls for compliance and training purposes.

Dependencies and configuration for your build

Download the code and install the dependencies:

git clone
cd twilio-roster
npm install

Update the included  .env file with your Account SID and Authentication Token. You can obtain your Account SID and Authentication Token from your project’s dashboard in the Twilio Console.

Save the .env file and deploy the code using the following command, where roster-test is an arbitrary service name specific to your project:

twilio serverless:deploy --service-name roster-test

Capture the BaseURL of your functions, as shown in the following image. We are going to use it in the next step.


Revisit the included .env file and update it with your other account specific details:

  • Primary and Secondary are the on-call numbers, i.e. the people that you would like to reachout once there is an incoming call to your on-call system.
  • BASEURLSRV is the Twilio Functions URL you obtained in the previous step
  • from is the Twilio phone number that you will use to receive and initiate outbound calls.

The next step is to save and redeploy the code. As of this writing, when you are deploying using the Twilio Serverless plugin you are not allowed to update code, environmental variables, or dependencies using the Twilio Console. Since we updated the .env file, we need to redeploy the code:

twilio serverless:deploy --service-name roster-test --override-existing-project

Lastly, we need to configure our Twilio phone number to call our /app function  every time there is an incoming call.

Select your from phone number and under A call comes in, select your function:

map to number

Test your solution

Time to test out what you’ve built. Call your from number. If everything went well you should be able to hear “On-Call. Attempting to contact primary. Please wait until we connect you”. Then the primary on-call number should ring and be placed in a conference.

Keep an eye on your debug logs


You can also review the logs from Serverless Toolkit:

twilio serverless:logs --tail

There are a few different scenarios that we recommend you try:

  • Decline the primary call.
  • Wait for the first call to timeout.
  • Answer the primary call with a business greeting (to simulate voicemail)
  • Decline the secondary call

Call recordings are also available under Programmable Voice section of the Twilio Console


Ideas to improve the solution

Although we have built a functional on-call system, there are plenty of edge cases that we did not cover and therefore room for potential improvements. Here are some ideas to get you started:

  1. Fetch on-call roster from third party system (i.e. Google Sheets or MS Sharepoint)
  2. What if the caller hangs up before the primary/secondary answers the call? We should be informing the callee that the caller dropped the call and perhaps follow up with an SMS with the caller details.  
  3. What if the caller was not able to reach either primary or secondary? Perhaps we can follow with an SMS with the caller details or have a last-resort hardcoded number to a backup line.
  4. What if we want to provide the caller the ability to provide their number for a callback? Maybe the caller is currently using a line that is not able to receive calls or the calls will be routed to the reception.
  5. Avoid having to populate the Base URL. Make use of Function path as it allows for built-in signature validation and you do not need to populate the BaseURL.


We demonstrated how you can use Twilio Programmable Voice and Twilio Functions to deliver a simple yet powerful on-call roster solution, one that delivers a superior customer experience by giving your employees the option to dial one number and be automatically connected to the ‘best’ available person on your roster. By automating this solution you remove the need for employees to manually search for the next available on-call employee to connect with. Your employees will thank you!

Mike Meisels is an Enterprise Account Executive on the Australia Team. Mike has a background in developing and implementing solution architecture. Mike joined the dark side 4 years ago but still likes to keep his hands dirty with developing solutions for Not For Profits and other organizations. Mike hides in his study away from his 5 daughters, 3 cats, and 2 dogs. Active on LinkedIn, he can be tracked down here.

Adonis is a Twilio Solutions Architect working on the Professional Services team in Singapore.  You can reach him at apanagidis [at]

Paul is a Technical Program Manager in our APJ Professional Services team who advise and support our customers with their Twilio builds. Based in Melbourne, Australia, you can  usually find Paul paddle-boarding in Port Philip Bay or looking after his two young daughters #GirlDad. You can reach him at pfenton [at]