Outbound reminder call with confirm / reschedule / cancel - all outcomes stored per appointment.
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-Appointment-reminder-XML-Python.git
cd -Vobiz-Appointment-reminder-XML-Python
cp .env.example .env
pip install -r requirements.txt
python server.py
Overview
A CRM or booking system triggers outbound reminder calls before appointments. The callee presses 1 to confirm, 2 to request a reschedule, or 3 to cancel (with a double-confirm step). All outcomes are stored and queryable via API with bulk scheduling support.
Status lifecycle: pending → calling → confirmed / reschedule_requested / cancelled / no_answer. Cancel via API before the call fires: aborted.
Call flow
Your CRM
└── POST /appointments {"phone":"+91...", "name":"John", "date":"Apr 5", "time":"3 PM"}
└── AppointmentStore.create() → status: pending
└── Trigger Vobiz outbound call → status: calling
└── /answer
"Hello John! Reminder: appointment on Apr 5 at 3 PM."
Gather: 1=Confirm 2=Reschedule 3=Cancel 9=Repeat
├── 1 → "Confirmed. See you soon!" → Hangup (status: confirmed)
├── 2 → "Please call us to reschedule." → Hangup (status: reschedule_requested)
├── 3 → "Are you sure?" → Gather 1=Yes / 2=No
│ ├── 1 → "Cancelled." → Hangup (status: cancelled)
│ └── 2 → Back to reminder
└── (no input) → Hangup (status: no_answer)
Vobiz webhooks
Set /answer as the Answer URL in your Vobiz application.
Method Path Description POST /answerReads reminder, collects DTMF POST /appt-choiceRoutes 1=confirm / 2=reschedule / 3=cancel POST /appt-cancel-confirmDouble confirms cancellation POST /hangupMarks no_answer if no digit was pressed
App API
Method Path Description POST /appointmentsSchedule a single reminder call POST /appointments/bulkSchedule multiple at once (JSON array) GET /appointmentsList all with outcomes (?status= to filter) GET /appointments/{id}Single appointment status PATCH /appointments/{id}/cancelCancel before call is made GET /appointments/statsOutcome breakdown by status
Environment variables
Variable Required Description VOBIZ_AUTH_IDYes Vobiz account auth ID VOBIZ_AUTH_TOKENYes Vobiz account auth token FROM_NUMBERYes Your Vobiz DID HTTP_PORTNo Server port (default: 8000) PUBLIC_URLNo Production URL - skips ngrok if set NGROK_AUTH_TOKENNo ngrok auth token for local dev