Never miss a call
Voicemail, missed-call SMS and forwarding with a fallback.
Text back missed calls
Rings your whole team at once; if nobody picks up, callers on a mobile get an instant SMS saying you will call back, and your team gets the caller's number by SMS and email.
How it works
- Someone calls your number and all your team phones ring at the same time.
- The first person to pick up takes the call.
- If nobody answers, a caller on a mobile gets a text saying you will call them back, then hears a short apology.
- Your team gets the caller's number by SMS and email, even if the caller hung up while it was ringing.
- Optionally, the missed call is also sent to your CRM or app.
Starts on: inbound-call
Actions used: dial@v2, answer@v1, sms@v1, play@v3, hangup@v1, email@v1, fetch@v3
Guide: Send SMS within a Call Flow
# Missed call text-back.
# Every inbound call rings your team at the same time.
# If nobody picks up, callers on a mobile get an SMS saying you will call
# them back, and your team gets the caller's number by SMS and email.
#
# What to edit: the MODIFIABLE VARIABLES below (team numbers, text-back
# message, alert recipients, optional webhook).
# Needs: SMS credit. The optional webhook must accept requests from the
# Callr IP ranges: https://docs.callr.com/docs/ip-subnets
# Build Mode: calls and SMS only go to your Testing Numbers.
# Docs: https://docs.callr.com/docs/send-sms-in-a-call-flow
description: "Text back missed calls"
compat:
version: "2025-09-01"
defaults:
# The caller hears ringing until someone answers
autoAnswer: false
language: en-US
voice: en-US-Olivia:MAI-Voice-2
variables:
$dial: null
# MODIFIABLE VARIABLES BELOW
$targets: # team phones, all ringing at the same time
- number: "+15550100001"
timeout: 25
- number: "+15550100002"
timeout: 25
$textBack: Hi, you just called us and we could not pick up. We will call you back as soon as possible. # SMS sent to mobile callers
$teamSms: # numbers alerted by SMS on a missed call
- "+15550100001"
$teamEmail: # addresses alerted by email on a missed call
- [email protected]
$webhookUrl: null # e.g. https://api.example.com/missed-call to log missed calls in your CRM
branches:
inbound-call:
actions:
# Ring every team phone, the first to answer takes the call
- action: dial@v2
params:
targets: ${{ $targets }}
parallel: true
result: $dial
- if: "!$dial?.ok"
goto:
branch: missed
missed:
actions:
- action: answer@v1
# Text the caller back, only on numbers that can receive SMS (mobiles)
- if: /MOBILE/.test(call.fromType ?? '') && call.fromNumber
action: sms@v1
params:
to:
- ${{ call.fromNumber }}
body: ${{ $textBack }}
nature: ALERTING
# Approved sender ID or one of your Callr numbers
# from: MyCompany
- action: play@v3
params:
tts:
text: Sorry we missed your call. We will call you back as soon as possible.
- action: hangup@v1
# Runs when the call ends, also when the caller hangs up while it rings
hangup:
actions:
- if: "!$dial?.ok"
then:
- if: $teamSms?.length
action: sms@v1
params:
to: ${{ $teamSms }}
body: Missed call from ${{ call.fromNumber ?? '(hidden number)' }} to ${{ call.toNumber }}.
nature: ALERTING
- if: $teamEmail?.length
action: email@v1
params:
to: ${{ $teamEmail }}
subject: Missed call from ${{ call.fromNumber ?? '(hidden number)' }}
text: |
Hello,
You missed a call from ${{ call.fromNumber ?? '(hidden number)' }} to ${{ call.toNumber }}.
Time (UTC): ${{ new Date(now).toISOString().slice(0, 16).replace('T', ' ') }}
Line type: ${{ call.fromType ?? 'unknown' }}
Please call them back.
- if: $webhookUrl
action: fetch@v3
params:
url: ${{ $webhookUrl }}
method: POST
headers:
Content-Type: application/json
body: |
{
"event": "missed-call",
"from": ${{ JSON.stringify(call.fromNumber ?? null) }},
"to": ${{ JSON.stringify(call.toNumber) }},
"fromType": ${{ JSON.stringify(call.fromType ?? null) }},
"time": ${{ JSON.stringify(new Date(now).toISOString()) }},
"dialStatus": ${{ JSON.stringify($dial?.status ?? null) }}
}Forwarding with voicemail
Rings your number with a whisper; if nobody answers, the caller gets a text-back and leaves a message that is transcribed and sent to you by SMS and email.
How it works
- Someone calls: they hear a short greeting, then your number rings.
- When you pick up, you hear who the call is for, then you are connected to the caller.
- If nobody answers, or your own mobile voicemail picks up, a caller on a mobile gets a text saying you will call back.
- The caller leaves a message, can listen to it and record it again.
- You get the transcribed message by SMS and email, or a missed-call alert if they hung up without a message, even while your number was still ringing.
Starts on: inbound-call
Actions used: ringing@v1, wait@v1, answer@v1, play@v3, dial@v2, amd@v3, hangup@v1, bridge@v3, sms@v1, record@v1, gather@v4, playRecordingFile@v1, javascript@v1, saveRecordingFile@v1, email@v1
Guide: Send SMS within a Call Flow
# Forwards inbound calls to your number with a whisper ("This is a call from...").
# If nobody answers (or the target's own voicemail picks up), the caller gets
# a text-back SMS and can leave a message. The message is transcribed and sent
# to you by SMS and email. Missed calls without a message are notified too.
#
# What to edit: the variables below the MODIFIABLE VARIABLES line, and the
# whisper and greeting texts.
# Needs: a number to forward to, a mobile for the SMS alerts, an email address.
# Build Mode: calls and SMS only reach your Testing Numbers.
# Docs: https://docs.callr.com/docs/send-sms-in-a-call-flow
description: "Forwarding with voicemail"
compat:
version: "2025-09-01"
defaults:
language: en-US
voice: en-US-Ethan:MAI-Voice-2
# The call keeps ringing until answer@v1 below
autoAnswer: false
variables:
$dial: null
$amd: null
$dtmf: null
$voicemail: null # temporary file of the message
$tries: 0 # menu attempts
# MODIFIABLE VARIABLES BELOW
# Number to forward the calls to, international format
$callTarget: "+15550100001"
# Ring duration in seconds, keep it short so the target's mobile voicemail does not pick up first
$callTimeout: 18
# Mobile that receives the missed-call SMS (null to disable)
$smsTarget: "+15550100001"
# Email address that receives the missed-call emails (null to disable)
$email: [email protected]
# Detect the target's own voicemail and take the message here instead
$detectVoicemailOnTarget: true
branches:
# The 'inbound-call' branch defines the actions for incoming calls
inbound-call:
actions:
- action: ringing@v1
- action: wait@v1
params:
seconds: 2
- action: answer@v1
# Greeting message
- action: play@v3
params:
tts:
text: Hello! Please wait while we connect you.
# Call forwarding to the target number
- if: $callTarget
action: dial@v2
params:
targets:
- number: ${{ $callTarget }}
timeout: ${{ $callTimeout }}
answerOnBranch: targetAnswered
result: $dial
# If the target does not answer in time, go to voicemail
- if: "!$dial?.ok"
goto:
branch: voicemail
# The custom 'targetAnswered' branch defines actions when the target answers
# These actions are played only for the recipient
targetAnswered:
actions:
- if: $detectVoicemailOnTarget
then:
# Is the target on voicemail?
# Automatic answering machine detection
- action: amd@v3
params:
timeout: 6
minWords: 4 # if more than minWords are said => voicemail
yesHints:
# these words are often heard in voicemails
- voicemail
- message
- tone
noHints:
# these words are often heard in human conversations
- "yes"
result: $amd
# If the target is on voicemail, hang up the outgoing call.
# The caller will be redirected to our own voicemail.
- if: $amd?.detected == 'machine'
action: hangup@v1
# Whisper to the target about the call.
# The caller keeps hearing the ringing tone.
- action: play@v3
params:
tts:
text: This is a call from (your brand).
# Bridge the caller and the target
- action: bridge@v3
- action: hangup@v1
# The 'voicemail' branch is used when the target number is not reachable
voicemail:
actions:
# Text the caller back if they call from a mobile
- if: call.fromType == 'MOBILE'
action: sms@v1
params:
to:
- ${{ call.fromNumber }}
nature: ALERTING
body: >
Hello! You have tried to reach us.
We will get back to you ASAP.
# Sent from your account's default sender. To show an approved
# sender ID or one of your SMS-capable Callr numbers:
# from: MyCompany
# We are not available.
- action: play@v3
params:
tts:
text: Sorry, we are not available at the moment.
- label: record
action: play@v3
params:
tts:
text: Leave us a message after the tone and we will call you back.
# The 'record@v1' action records the caller
# A temporary file is created, and its name is stored in the variable $voicemail
- action: record@v1
params:
maxLength: 120 # seconds
result: $voicemail
# Gather will wait for a DTMF
- label: menu
action: gather@v4
params:
maxDigits: 1
timeout: 15
tts:
# You can use multi-line YAML strings
text: |
To listen to your message, press 1.
To send your message, press 2.
To record your message again, press 3.
result: $dtmf
- if: $dtmf?.input == '1'
then:
- action: playRecordingFile@v1
params:
file: ${{ $voicemail }}
- goto:
label: menu
- if: $dtmf?.input == '3'
then:
- action: javascript@v1
params:
code: $voicemail = null # reset the variable $voicemail
- goto:
label: record
# Press 2, or no valid choice after 3 attempts: send the message
- if: $dtmf?.input == '2' || $tries >= 2
then:
- action: play@v3
params:
tts:
text: We have received your message, thank you!
- action: hangup@v1
- action: javascript@v1
params:
code: $tries++
- action: play@v3
params:
tts:
text: Sorry, I did not get that.
- goto:
label: menu
# Runs when the call ends, also when the caller hangs up while your number rings
hangup:
actions:
# Notify only missed calls: nothing to do if the target took the call
- if: "!$dial?.ok"
then:
- if: $voicemail
then:
# Save the recording for processing.
- action: saveRecordingFile@v1
params:
file: ${{ $voicemail }}
events:
# When the file has been processed, you can execute actions on it
ready:
# Notify the target via SMS of the missed call
- if: $smsTarget
action: sms@v1
params:
nature: ALERTING
body: |
You have a missed call from ${{ call.fromNumber ?? '(hidden number)' }}.
« ${{ transcription_leg_a }} »
to:
- ${{ $smsTarget }}
# Also send email notification
- if: $email
action: email@v1
params:
subject: Missed call from ${{ call.fromNumber ?? '(hidden number)' }}
text: |
Hello,
You have a missed call from: ${{ call.fromNumber ?? '(hidden number)' }}.
Number called: ${{ call.toNumber }} (${{ scenario.name }}).
« ${{ transcription_leg_a }} »
You can download the message here: ${{ recording.url }}
to:
- ${{ $email }}
- if: "!$voicemail"
then:
# SMS notification for a missed call without a message
- if: $smsTarget
action: sms@v1
params:
nature: ALERTING
body: >
Missed call from ${{ call.fromNumber ?? '(hidden number)' }}.
No voicemail left by the caller.
to:
- ${{ $smsTarget }}
# Also send email notification
- if: $email
action: email@v1
params:
subject: Missed call from ${{ call.fromNumber ?? '(hidden number)' }}
text: |
Hello,
You have missed a call from: ${{ call.fromNumber ?? '(hidden number)' }}.
Number called: ${{ call.toNumber }} (${{ scenario.name }}).
The caller did not leave a message.
to:
- ${{ $email }}Voicemail with transcription
The number goes straight to voicemail; callers can listen back and re-record, and the transcript is sent to you by email, SMS and to your webhook.
How it works
- Someone calls: they hear that you are not available and are asked to leave a message.
- After the tone, they record their message.
- They can listen to it, record it again, or send it.
- Once the message is transcribed, you get it by email and SMS, and your server receives it if you set a webhook.
Starts on: inbound-call
Actions used: wait@v1, play@v3, record@v1, gather@v4, playRecordingFile@v1, javascript@v1, hangup@v1, saveRecordingFile@v1, sms@v1, email@v1, fetch@v3
Guide: Send Emails within a Call Flow
# The number goes straight to voicemail: it never forwards the call.
# Callers can listen back to their message and record it again. Once the
# message is transcribed, it is sent to you by email and SMS, and to your
# webhook if you set one.
#
# What to edit: the variables below the MODIFIABLE VARIABLES line.
# Needs: an email address, a mobile for the SMS, optionally a webhook URL.
# Build Mode: SMS only reach your Testing Numbers.
# Docs: https://docs.callr.com/docs/send-an-email-within-a-call-flow
# Webhook: allow Callr's IP ranges, see https://docs.callr.com/docs/ip-subnets
description: "Voicemail with transcription"
compat:
version: "2025-09-01"
defaults:
# define a default voice for Speech
voice: en-US-Olivia:MAI-Voice-2
language: en-US
variables:
$dtmf: null
$file: null # temporary file of the message
$tries: 0 # menu attempts
# MODIFIABLE VARIABLES BELOW
# Email addresses that receive the voicemail (empty list to disable)
$emailTargets:
- [email protected]
- [email protected]
# Mobile that receives the voicemail by SMS (null to disable)
$smsTarget: "+15550100001"
# Your server receives the voicemail as JSON (null to disable), e.g. https://api.example.com/voicemail
$webhookUrl: null
# Sender name shown in the email
$companyName: My Company
branches:
# The 'inbound-call' branch defines the actions for incoming calls
inbound-call:
actions:
- action: wait@v1
params:
seconds: 2
# Let's say we cannot take this call
- action: play@v3
params:
tts:
text: Sorry, we are not available at the moment.
# Continue to another branch
- goto:
branch: voicemail
voicemail:
actions:
- label: start
action: play@v3
params:
tts:
text: Please leave a message after the tone.
# The 'record@v1' action records the caller
# A temporary file is created and stored in the $file variable
- action: record@v1
params:
maxLength: 120 # seconds
result: $file
# Gather will wait for a DTMF
- label: menu
action: gather@v4
params:
maxDigits: 1
timeout: 15
tts:
# You can leverage YAML multi line strings
text: |
To listen to your message, press 1.
To send this message, press 2.
To re-record this message, press 3.
result: $dtmf
- if: $dtmf?.input == '1'
then:
- action: playRecordingFile@v1
params:
file: ${{ $file }}
- goto:
label: menu
- if: $dtmf?.input == '3'
then:
- action: javascript@v1
params:
code: $file = null # reset the $file variable
- goto:
label: start
# Press 2, or no valid choice after 3 attempts: send the message
- if: $dtmf?.input == '2' || $tries >= 2
then:
- action: play@v3
params:
tts:
text: Your message has been delivered. Thank you!
# Now we can hangup. The processing will continue in special branch "hangup".
- action: hangup@v1
- action: javascript@v1
params:
code: $tries++
- action: play@v3
params:
tts:
text: Sorry, I did not get that.
- goto:
label: menu
hangup:
actions:
- if: $file
then:
# saveRecordingFile will transcribe the recording by default
- action: saveRecordingFile@v1
params:
file: ${{ $file }}
events:
# When the file is ready, define some actions
ready:
# Send an SMS to the voicemail owner
- if: $smsTarget
action: sms@v1
params:
nature: ALERTING
body: >
You have a new voicemail from ${{ call.fromNumber ?? '(hidden number)' }}.
Transcription: "${{ transcription_leg_a }}"
to:
- ${{ $smsTarget }}
# Send an email
- if: $emailTargets?.length
action: email@v1
params:
fromName: ${{ $companyName }}
subject: You have a new voicemail from ${{ call.fromNumber ?? '(hidden number)' }}
text: |
Hello there!
You have a new voicemail from ${{ call.fromNumber ?? '(hidden number)' }}. Duration: ${{ recording.duration }}s.
"${{ transcription_leg_a }}".
You can download the file here: ${{ recording.url }}.
to: ${{ $emailTargets }}
# Push the voicemail to your own server
- if: $webhookUrl
action: fetch@v3
params:
url: ${{ $webhookUrl }}
method: POST
body: |
{
"type": "voicemail",
"call": ${{ JSON.stringify(call) }},
"recording": ${{ JSON.stringify(recording) }},
"transcription": ${{ JSON.stringify(transcription_leg_a) }}
}
headers:
Content-Type: application/json
# If your server requires a header
# Authorization: Bearer your-tokenUpdated about 3 hours ago
