← Back to Blog

How to Build an IVR System with Python and a Voice API

Learn how to build an IVR (Interactive Voice Response) system in Python using LAML/XML. Includes multi-level menus, digit collection, call routing and recording.

An IVR (Interactive Voice Response) system is the technology behind 'Press 1 for sales, press 2 for support.' Building one used to require expensive hardware. Today, you can build a fully featured IVR with Python and a voice API in an afternoon.

What we will build

  • A greeting menu with 3 department options
  • Routing based on caller input
  • Graceful handling of invalid input
  • Call recording for quality assurance

Setup

pip install wirexaapi flask

1. Originate the call

call = client.calls.create(
    to="+15551234567",
    from_="+15559876543",
    url="https://your-backend.com/ivr",
    record=True,
)

2. Main menu

@app.route('/ivr', methods=['POST'])
def ivr_main():
    xml = '''<Response>
  <Gather numDigits="1" timeout="8" action="/ivr/route">
    <Say language="en-US" voice="polly.Joanna">
      Thank you for calling. Press 1 for Sales.
      Press 2 for Support. Press 3 for Billing.
    </Say>
  </Gather>
  <Redirect>/ivr</Redirect>
</Response>'''
    return Response(xml, mimetype='text/xml')

3. Route by digit

@app.route('/ivr/route', methods=['POST'])
def ivr_route():
    digit = request.form.get('Digits', '')
    routes = {
        '1': ('Sales', '/ivr/sales'),
        '2': ('Support', '/ivr/support'),
        '3': ('Billing', '/ivr/billing'),
    }
    if digit in routes:
        name, path = routes[digit]
        xml = f'<Response><Say>Connecting to {name}.</Say><Redirect>{path}</Redirect></Response>'
    else:
        xml = '<Response><Say>Invalid option.</Say><Redirect>/ivr</Redirect></Response>'
    return Response(xml, mimetype='text/xml')

Tips for production IVRs

  • Keep menus to 4 options or fewer — callers forget longer lists
  • Always offer a way to repeat and to reach a human agent
  • Use short, clear Say text — avoid complex sentences
  • Enable call recording from day one for QA and compliance
  • Log Digits from every Gather to analyze drop-off points

Next steps

This IVR runs entirely from Python + Flask with no special hardware. You can extend it with database lookups, CRM integrations, or real-time agent transfers.

Read the full API reference or contact us to set up your account.

Ready to build with Wirexa API?

Get your API credentials and make your first call in minutes.

Request access →