Twilio Critical Alert Voice Call Escalation
When a critical alert fires and isn't acknowledged by SMS within a threshold, the flow places an automated Twilio voice call to the on-call engineer that reads the alert and accepts a keypress to acknowledge, then escalates to the next person if unanswered. Posts status to Teams. Ensures truly urgent alerts wake someone up.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
This solution adds a last-resort, attention-guaranteed escalation layer for critical (SEV1) alerts using Twilio voice calls. When a critical alert fires, the on-call engineer is first paged by SMS. If they do not acknowledge within a threshold, the flow places an automated Twilio voice call that reads the alert aloud and accepts a phone-keypress to acknowledge. If it is still unacknowledged, the flow escalates to the next responder (SMS + voice) and emails the ops manager as a final fallback. Every state change is posted to Microsoft Teams, and acknowledgement is recorded in a Dataverse ledger so escalation stops the instant someone responds. Why it matters: A sleeping engineer may sleep through an SMS. A phone call that demands a keypress to acknowledge keeps escalating until a human actually responds.
Use Case
An operations / SRE team needs guaranteed escalation for SEV1 incidents: SMS-first, voice-call-with-acknowledgement second, automatic move to the next responder third, and a manager email as the final safety net — with full status visibility in Teams.
Flow Architecture
When a critical alert is received (Escalation)
Request (HTTP)Accepts alertId, severity, message and source from the monitoring system.
Initialize correlation id + config
Initialize VariableMint @guid() correlation id; capture severity/message/alertId; parse the escalation chain and first responder; set Teams group/channel id and ack digit.
Create Alert Record
Compose + Microsoft Dataverse — CreateRecordWhole-object compose then create the ledger row at status SMS-Sent, acknowledged=false.
Send Initial SMS Page
Twilio — SendMessageSMS the first responder, then post Alert Raised to Teams.
Wait + re-read for SMS ack
Delay + Microsoft Dataverse — ListRecords + ConditionWait the SMS ack window, re-read the ledger, and branch if still unacknowledged.
Place Voice Call
Compose TwiML + HTTP POST /Calls.jsonCompose inline TwiML and place the Twilio voice call via built-in HTTP (no connector voice op); update ledger to Voice-Placed with call SID and post to Teams.
Escalate to next responder
Twilio — SendMessage + HTTP + Microsoft Dataverse — UpdateRecord + Office 365 Outlook — SendEmailV2After the voice window, if still unacknowledged page the next responder (SMS + voice), mark Escalated, and email the ops manager as final fallback.
When Twilio posts a keypress (Receiver)
Request (HTTP)Twilio posts form-encoded Digits with cid in the query string.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_TwilioFromNumber | String | +15551234567 | Verified Twilio sender number (reused). |
| flowlibs_TwilioAccountSid | String | <configure> | Twilio Account SID (voice REST Basic auth). |
| flowlibs_TwilioAuthToken | String | REPLACE_WITH_TWILIO_AUTH_TOKEN | Twilio Auth Token (voice REST Basic auth). |
| flowlibs_TwilioApiBase | String | https://api.twilio.com | Twilio REST base URL. |
| flowlibs_EscalationChain | String | ["+15551230001","+15551230002"] | Ordered JSON list of responder numbers. |
| flowlibs_AckThresholdMinutes | String | 3 | SMS ack window before calling. |
| flowlibs_VoiceAckThresholdMinutes | String | 2 | Voice ack window before escalating. |
| flowlibs_OpsManagerEmail | String | alerts@yourcompany.com | Final-fallback email recipient. |
| flowlibs_AckWebhookUrl | String | https://REPLACE_WITH_ACK_FLOW_TRIGGER_URL | Flow 2 trigger URL for the Gather callback. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Twilio | shared_twilio | SendMessage |
| Microsoft Teams | shared_teams | PostMessageToConversation |
| Office 365 Outlook | shared_office365 | SendEmailV2 |
| Microsoft Dataverse | shared_commondataserviceforapps | CreateRecord UpdateRecord |
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- PagerDuty hand-off
- For complex escalation policies, hand off to PagerDuty instead of the in-flow chain.
- Repeat calls
- Add a loop to re-call after N minutes if still unacknowledged.
- Conference bridge
- For majors, use TwiML <Dial><Conference> to bridge multiple responders.
- More tiers
- Extend EscalationChain and replace the hard-coded [1] next-responder index with a loop over escalationindex.
- Acknowledge by SMS
- Wire Twilio inbound-SMS to the receiver flow so a text reply also acknowledges.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01First responder
Responder 0 from the escalation chain.
EXPR.02Next responder
The second responder in the chain.
EXPR.03Unacked gate
True when the ledger still shows the alert unacknowledged.
EXPR.04Twilio Basic auth
Build the Basic auth header for the Twilio voice REST call.
EXPR.05Voice call body
Form-encoded body for POST /Calls.json with inline TwiML.
EXPR.06Pressed digit (receiver)
Read the keypress Twilio posts to the receiver flow.
Customize & download
Generate a ready-to-import copy of this solution with your environment-variable values baked in — available on Base, Pro, or Team.
Upgrade to customize
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.