DEV Community

anusha
anusha

Posted on

I Built a Voice AI Assistant for Prescription Refill Intake

Prescription refill calls are one of those workflows that sound simple until you look at the operational details.

The caller needs to explain which medication they are calling about. The pharmacy or clinic may need the preferred pharmacy, the callback number, how soon the refill is needed, and whether the request needs manual review.

But there is also a hard boundary: the AI should not approve a prescription, deny a refill, change dosage instructions, diagnose anything, or make clinical decisions.

So I built the workflow as an intake assistant, not a decision-maker.

The Telnyx code example is here:

https://github.com/team-telnyx/telnyx-code-examples/tree/main/ai-prescription-refill-intake-voice-assistant-python

It uses Telnyx AI Assistants with a small Python + Flask backend.

The Flow

The caller dials a Telnyx phone number. Telnyx sends a call.initiated webhook to the Flask app.

The app does two things:

  1. Answers the call
  2. Starts the configured Telnyx AI Assistant with ai_assistant_start

After that, the assistant owns the live conversation. It gives an emergency reminder, then asks one question at a time.

The assistant has three backend tools:

  • create_refill_request
  • flag_manual_review
  • queue_callback

When the assistant has enough information, it calls create_refill_request. If the request mentions a controlled substance, dosage change, side effects, urgent access issue, or similar follow-up trigger, it calls flag_manual_review. If the caller wants a callback, it calls queue_callback.

The Part I Care About

The AI is not the system of record.

The AI is not approving the refill.

The AI is collecting enough information for staff to do the next step.

That distinction matters a lot in healthcare voice AI. A useful assistant should reduce the intake burden without pretending to replace a pharmacist, clinician, or compliance process.

The backend is where the workflow is enforced. It stores the request, masks caller identifiers, checks the assistant tool secret, and exposes a review endpoint for staff.

Why Use Telnyx AI Assistants Here

You could build this as a manual voice state machine with gather and speak commands. That works, but the code gets focused on conversation plumbing.

With Telnyx AI Assistants, the shape is cleaner:

Call Control answers the phone
AI Assistant handles the conversation
assistant tools call the Flask backend
backend stores refill workflow state
staff reviews the request
Enter fullscreen mode Exit fullscreen mode

The assistant prompt is also provisioned from code in provision_assistant.py, which means someone can recreate the assistant from the repo instead of manually copying settings from a portal screenshot.

Run It Locally

git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/ai-prescription-refill-intake-voice-assistant-python
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
Enter fullscreen mode Exit fullscreen mode

Set the required environment variables:

TELNYX_API_KEY=KEY...
PUBLIC_BASE_URL=https://your-ngrok-url.ngrok-free.app
TOOL_SECRET=replace_with_a_random_shared_secret
TELNYX_PHONE_NUMBER=+18005551234
TELNYX_PUBLIC_KEY=your_telnyx_public_key_here
Enter fullscreen mode Exit fullscreen mode

Start the app:

python app.py
Enter fullscreen mode Exit fullscreen mode

Expose it:

ngrok http 5000
Enter fullscreen mode Exit fullscreen mode

Provision the assistant:

python provision_assistant.py
Enter fullscreen mode Exit fullscreen mode

Then set your Call Control Application webhook URL to:

https://<your-ngrok-domain>/webhooks/voice
Enter fullscreen mode Exit fullscreen mode

Call the Telnyx number and ask for a prescription refill.

What To Watch In The Code

The main app is app.py.

The inbound webhook answers the call and starts the assistant:

requests.post(
    f"{TELNYX_API_BASE}/calls/{call_control_id}/actions/ai_assistant_start",
    headers=telnyx_headers(),
    json={"assistant_id": TELNYX_ASSISTANT_ID},
    timeout=10,
)
Enter fullscreen mode Exit fullscreen mode

The assistant setup is in provision_assistant.py. That file creates or updates the assistant, sets the model, adds the prompt, configures dynamic variables, and registers the webhook tools.

The tool endpoints are intentionally narrow. They accept structured data and return workflow state. That makes the assistant useful without letting it become the approval layer.

Production Notes

The sample keeps state in memory because it is designed to be easy to run locally.

For production, I would add encrypted database storage, staff authentication, audit logging, retention policies, monitoring, stricter PHI controls, and a full compliance review.

I would also keep the assistant instructions conservative:

collect intake
route to staff
do not approve or deny
do not change medication instructions
do not diagnose
send emergency callers to 9-1-1
Enter fullscreen mode Exit fullscreen mode

That is the useful shape for this kind of healthcare AI workflow.

Resources

Top comments (0)