Telecom

Asterisk IVR: Looping IVR menu (Latest Versions)

MYLINEHUB Team • 2026-02-10 • 9 min

Updated guide for modern Asterisk (PJSIP era): looping ivr menu with real configs, common mistakes, and troubleshooting steps.

Asterisk IVR: Looping IVR menu (Latest Versions)

A looping IVR menu is a common requirement in real business phone systems. If the caller does not press any key, or presses an invalid key, the IVR should repeat the menu instead of disconnecting immediately.

But looping must be done carefully: infinite loops frustrate callers and can overload queues and trunks. A production IVR needs controlled looping with limits and a fallback path.

This guide shows how to build a clean looping IVR menu in modern Asterisk (PJSIP) using safe retry counters, proper handling of i and t, and a final fallback to operator/queue/voicemail.

What Does “Looping IVR” Mean?

Looping IVR means:

  • Caller hears menu prompt
  • If no input → replay menu
  • If invalid input → replay menu
  • After N attempts → route to fallback (operator/queue/voicemail)

This improves the customer experience because callers are guided, not dropped.

Why Looping Needs Limits

An IVR without limits causes problems:

  • Callers get trapped and hang up
  • Inbound trunks stay occupied longer
  • Queues get overloaded with “stuck” calls
  • Agent availability becomes harder to manage

Best practice: loop only 2–3 times, then route to help.

Core Dialplan Events: i and t

  • i → invalid input (caller pressed wrong key)
  • t → timeout (caller pressed nothing)

These two extensions are the key to looping behavior.

Production-Safe Looping IVR Template

This template loops a maximum of 3 times and then routes to fallback.

[main-ivr]
exten => s,1,Answer()
 same => n,Set(TIMEOUT(digit)=3)
 same => n,Set(TIMEOUT(response)=6)

 ; Initialize / increment loop counter
 same => n,Set(IVR_TRIES=${IF($["${IVR_TRIES}"=""]?1:$[${IVR_TRIES}+1])})
 same => n,NoOp(IVR_TRIES=${IVR_TRIES})

 ; If exceeded max tries, go to fallback
 same => n,GotoIf($[${IVR_TRIES} > 3]?fallback,1)

 ; Play menu and wait for digits
 same => n,Background(custom/ivr/main-menu)
 same => n,WaitExten(6)

; Valid options
exten => 1,1,Playback(custom/ivr/connecting-sales)
 same => n,Queue(sales,tT)
 same => n,Hangup()

exten => 2,1,Playback(custom/ivr/connecting-support)
 same => n,Queue(support,tT)
 same => n,Hangup()

exten => 0,1,Goto(fallback,1)

; Invalid input → replay menu
exten => i,1,Playback(custom/ivr/invalid)
 same => n,Goto(main-ivr,s,1)

; No input → replay menu
exten => t,1,Playback(custom/ivr/no-input)
 same => n,Goto(main-ivr,s,1)

; Final fallback after too many loops
exten => fallback,1,Playback(custom/ivr/please-hold-operator)
 same => n,Dial(PJSIP/1000,20)
 same => n,Voicemail(1000@default,u)
 same => n,Hangup()

Why Background() + WaitExten() Is Used

  • Background() plays the menu prompt
  • It listens for DTMF while audio plays
  • WaitExten() waits after prompt ends

This combination ensures callers can press keys at any time.

Alternative Looping Style: Use a Separate “menu” Extension

Some dialplans are cleaner when menu playback is isolated.

[main-ivr]
exten => s,1,Answer()
 same => n,Goto(menu,1)

exten => menu,1,Set(IVR_TRIES=${IF($["${IVR_TRIES}"=""]?1:$[${IVR_TRIES}+1])})
 same => n,GotoIf($[${IVR_TRIES} > 3]?fallback,1)
 same => n,Background(custom/ivr/main-menu)
 same => n,WaitExten(6)

exten => i,1,Playback(custom/ivr/invalid)
 same => n,Goto(menu,1)

exten => t,1,Playback(custom/ivr/no-input)
 same => n,Goto(menu,1)

This keeps the loop logic in one place.

Common Looping IVR Problems and Fixes

IVR Loops Forever

  • No IVR_TRIES counter
  • Counter resets incorrectly
  • Fix: Set counter once per call and increment safely

Caller Cannot Press Keys During Prompt

  • Using Playback() instead of Background()
  • DTMF mode mismatch on trunk

Looping Works Internally But Not From Provider

  • External DTMF not reaching Asterisk (RFC4733/INFO/inband issue)
  • Codec mismatch affecting inband DTMF

Best Practices for Looping IVRs

  • Loop max 2–3 times, then route to help
  • Always include i and t handlers
  • Provide operator/queue fallback after max tries
  • Keep prompts short to reduce call duration
  • Test from external numbers, not only internal phones

A looping IVR should guide callers, not trap them.

Key Takeaway

A safe looping IVR in Asterisk is built using: Background(), WaitExten(), and controlled routing from i (invalid) and t (timeout).

Always limit loops using a counter like IVR_TRIES, and provide a final fallback path so every caller reaches a helpful destination.

Try it

Want to see API-driven CRM + Telecom workflows in action? Try the WhatsApp bot or explore the demos.

💬 Try WhatsApp Bot ▶️ Watch CRM YouTube Demos
Tip: Comment “Try the bot” on our YouTube videos to see automation in action.
M
MYLINEHUB Team
Published: 2026-02-10
Quick feedback
Was this helpful? (Yes 0 • No 0)
Reaction

Comments (0)

Be the first to comment.