Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.vobiz.ai/llms.txt

Use this file to discover all available pages before exploring further.

Phone-based two-factor authentication - generate a 6-digit OTP, call the user, and read it digit by digit. XML elements used: <Speak>, <Gather inputType=dtmf numDigits=1>, <Redirect>, <Hangup>

View on GitHub

Clone and run the full working example

Getting started

git clone https://github.com/vobiz-ai/Vobiz-OTP-call-XML-Python.git
cd Vobiz-OTP-call-XML-Python
cp .env.example .env
pip install -r requirements.txt
python server.py

Overview

Your app calls POST /send-otp with a phone number. The server generates a 6-digit OTP with a 5-minute TTL, triggers an outbound Vobiz call, and reads the code aloud one digit at a time with 1-second pauses. The user can press 1 to hear the code again. Your app then calls POST /verify-otp to check the code.

Call flow

Your app
  └── POST /send-otp {"phone": "+91XXXXXXXXXX"}
        └── OTP generated (6 digits, 5-min TTL)
        └── Vobiz outbound call triggered
              └── /answer  → "Your verification code is: 6. 1. 0. 3. 8. 9."
                              "Press 1 to hear it again."
                    ├── 1 → /otp-choice  → Repeat OTP
                    └── (hangup) → /hangup  → OTP marked as delivered

  └── POST /verify-otp {"phone": "+91...", "otp": "610389"}
        └── 200 OK {"valid": true} or 400 {"valid": false}

Vobiz webhooks

Set /answer as the Answer URL in your Vobiz application.
MethodPathDescription
POST/answerReads OTP digit by digit
POST/otp-choiceHandles press 1 to repeat
POST/hangupMarks OTP as delivered, cleanup

App API

MethodPathDescription
POST/send-otpGenerate OTP + trigger outbound call
POST/verify-otpVerify OTP entered by user
GET/otp-status/{phone}Check delivery status

Environment variables

VariableRequiredDescription
VOBIZ_AUTH_IDYesVobiz account auth ID
VOBIZ_AUTH_TOKENYesVobiz account auth token
FROM_NUMBERYesYour Vobiz DID (outbound caller ID)
HTTP_PORTNoServer port (default: 8000)
PUBLIC_URLNoProduction URL - skips ngrok if set
NGROK_AUTH_TOKENNongrok auth token for local dev