---
title: "AI Agent for Prescription Refill Management: Automated Refill Requests and Pharmacy Coordination"
description: "Build an AI agent that detects when patients need medication refills, routes approval requests to providers, coordinates with pharmacies via NCPDP SCRIPT, and tracks prescription fulfillment end to end."
canonical: https://callsphere.ai/blog/ai-agent-prescription-refill-management-automated-pharmacy-coordination
category: "Learn Agentic AI"
tags: ["Prescription Refill", "Pharmacy Integration", "Healthcare AI", "NCPDP SCRIPT", "Python"]
author: "CallSphere Team"
published: 2026-03-17T00:00:00.000Z
updated: 2026-05-06T01:02:44.386Z
---

# AI Agent for Prescription Refill Management: Automated Refill Requests and Pharmacy Coordination

> Build an AI agent that detects when patients need medication refills, routes approval requests to providers, coordinates with pharmacies via NCPDP SCRIPT, and tracks prescription fulfillment end to end.

## Why Prescription Refills Need Automation

Prescription refill requests account for a significant portion of inbound calls to medical practices. Each request triggers a multi-step workflow: verify the prescription, check remaining refills, get provider approval, and notify the pharmacy. When done manually, refill requests take 5 to 10 minutes each and are prone to communication delays.

An AI refill management agent handles this entire chain — from detecting that a patient needs a refill to confirming that the pharmacy has processed it.

## Prescription Data Model

Start by modeling the prescription lifecycle, including refill counts, authorization status, and pharmacy details.

```mermaid
sequenceDiagram
    autonumber
    participant Caller as Caller
    participant Agent as CallSphere Agent
    participant API as CRM API
    participant DB as CRM Database
    participant Webhook as Webhook Listener
    Caller->>Agent: Inbound call begins
    Agent->>Agent: STT plus intent detection
    Agent->>API: Lookup contact by phone
    API->>DB: Read contact record
    DB-->>API: Contact and history
    API-->>Agent: Personalized context
    Agent->>API: Create call activity
    Agent->>API: Update deal stage
    API->>Webhook: Outbound webhook fires
    Webhook-->>Agent: Confirmed
    Agent->>Caller: Spoken confirmation
```

```python
from dataclasses import dataclass, field
from datetime import date, datetime, timedelta
from typing import Optional
from enum import Enum
import uuid

class PrescriptionStatus(Enum):
    ACTIVE = "active"
    EXPIRED = "expired"
    DISCONTINUED = "discontinued"
    ON_HOLD = "on_hold"

class RefillRequestStatus(Enum):
    PENDING = "pending"
    APPROVED = "approved"
    DENIED = "denied"
    SENT_TO_PHARMACY = "sent_to_pharmacy"
    FILLED = "filled"
    PICKED_UP = "picked_up"

@dataclass
class Prescription:
    id: str
    patient_id: str
    provider_id: str
    medication_name: str
    dosage: str
    frequency: str
    quantity: int
    refills_authorized: int
    refills_remaining: int
    prescribed_date: date
    expiration_date: date
    pharmacy_id: str
    status: PrescriptionStatus = PrescriptionStatus.ACTIVE
    last_filled: Optional[date] = None
    days_supply: int = 30

@dataclass
class RefillRequest:
    id: str = field(
        default_factory=lambda: str(uuid.uuid4())
    )
    prescription_id: str = ""
    patient_id: str = ""
    requested_at: datetime = field(
        default_factory=datetime.utcnow
    )
    status: RefillRequestStatus = RefillRequestStatus.PENDING
    provider_approved: bool = False
    approved_by: Optional[str] = None
    approved_at: Optional[datetime] = None
    pharmacy_confirmation: Optional[str] = None
    notes: str = ""
```

## Refill Detection Engine

The agent proactively identifies patients who are running low on medication based on their fill history and days supply. This enables outreach before the patient runs out.

```python
class RefillDetector:
    def __init__(self, db):
        self.db = db

    async def find_patients_needing_refills(
        self, lookahead_days: int = 7,
    ) -> list[dict]:
        cutoff = date.today() + timedelta(days=lookahead_days)

        rows = await self.db.fetch("""
            SELECT
                rx.id AS prescription_id,
                rx.patient_id,
                p.first_name || ' ' || p.last_name AS name,
                p.phone, p.email,
                rx.medication_name, rx.dosage,
                rx.refills_remaining,
                rx.last_filled,
                rx.days_supply,
                (rx.last_filled + rx.days_supply) AS runs_out,
                rx.pharmacy_id
            FROM prescriptions rx
            JOIN patients p ON p.id = rx.patient_id
            WHERE rx.status = 'active'
              AND rx.refills_remaining > 0
              AND (rx.last_filled + rx.days_supply)  dict:
        rx = await self.db.fetchrow("""
            SELECT * FROM prescriptions
            WHERE id = $1
        """, prescription_id)

        if not rx:
            return {"eligible": False, "reason": "not_found"}
        if rx["status"] != "active":
            return {
                "eligible": False,
                "reason": f"prescription_{rx['status']}",
            }
        if rx["refills_remaining"]  RefillRequest:
        auto_approve = (
            not requires_review
            and prescription.refills_remaining > 0
            and prescription.expiration_date > date.today()
        )

        if auto_approve:
            refill_request.status = RefillRequestStatus.APPROVED
            refill_request.provider_approved = True
            refill_request.approved_by = "auto"
            refill_request.approved_at = datetime.utcnow()
        else:
            refill_request.status = RefillRequestStatus.PENDING
            await self.notify.send_to_provider(
                provider_id=prescription.provider_id,
                message=(
                    f"Refill request for "
                    f"{prescription.medication_name} "
                    f"{prescription.dosage} - "
                    f"Patient {refill_request.patient_id}. "
                    f"Refills remaining: "
                    f"{prescription.refills_remaining}"
                ),
                action_url=(
                    f"/refills/{refill_request.id}/review"
                ),
            )

        await self.db.execute("""
            INSERT INTO refill_requests
                (id, prescription_id, patient_id, status,
                 provider_approved, approved_by, approved_at)
            VALUES ($1, $2, $3, $4, $5, $6, $7)
        """, refill_request.id, refill_request.prescription_id,
             refill_request.patient_id,
             refill_request.status.value,
             refill_request.provider_approved,
             refill_request.approved_by,
             refill_request.approved_at)

        return refill_request

    async def process_provider_decision(
        self, request_id: str, approved: bool,
        provider_id: str, notes: str = "",
    ):
        status = (
            RefillRequestStatus.APPROVED if approved
            else RefillRequestStatus.DENIED
        )
        await self.db.execute("""
            UPDATE refill_requests
            SET status = $2, provider_approved = $3,
                approved_by = $4, approved_at = $5, notes = $6
            WHERE id = $1
        """, request_id, status.value, approved,
             provider_id, datetime.utcnow(), notes)
```

## Pharmacy Notification via NCPDP SCRIPT

Once approved, the agent sends the refill authorization to the pharmacy using the NCPDP SCRIPT standard, the electronic prescribing protocol used across US pharmacies.

```python
class PharmacyNotifier:
    def __init__(self, escript_client):
        self.client = escript_client

    async def send_refill_authorization(
        self, prescription: Prescription,
        refill_request: RefillRequest,
        db,
    ) -> str:
        message = {
            "message_type": "REFRES",  # refill response
            "pharmacy_ncpdp": prescription.pharmacy_id,
            "prescriber_npi": await self._get_npi(
                prescription.provider_id, db
            ),
            "medication": {
                "drug_description": (
                    prescription.medication_name
                ),
                "strength": prescription.dosage,
                "quantity": prescription.quantity,
                "days_supply": prescription.days_supply,
                "refills_authorized": 1,
            },
            "patient_id": prescription.patient_id,
        }

        confirmation = await self.client.send(message)

        await db.execute("""
            UPDATE refill_requests
            SET status = 'sent_to_pharmacy',
                pharmacy_confirmation = $2
            WHERE id = $1
        """, refill_request.id, confirmation["tracking_id"])

        await db.execute("""
            UPDATE prescriptions
            SET refills_remaining = refills_remaining - 1,
                last_filled = CURRENT_DATE
            WHERE id = $1
        """, prescription.id)

        return confirmation["tracking_id"]

    async def _get_npi(self, provider_id, db):
        row = await db.fetchrow(
            "SELECT npi FROM providers WHERE id = $1",
            provider_id,
        )
        return row["npi"]
```

## End-to-End Refill Tracking

The agent monitors the complete refill lifecycle and notifies the patient at each stage.

```python
class RefillTracker:
    def __init__(self, db, sms_client):
        self.db = db
        self.sms = sms_client

    async def check_and_notify(self, request_id: str):
        req = await self.db.fetchrow("""
            SELECT rr.*, p.phone, p.first_name,
                   rx.medication_name
            FROM refill_requests rr
            JOIN patients p ON p.id = rr.patient_id
            JOIN prescriptions rx
                ON rx.id = rr.prescription_id
            WHERE rr.id = $1
        """, request_id)

        status = req["status"]
        messages = {
            "approved": (
                f"Hi {req['first_name']}, your refill for "
                f"{req['medication_name']} has been approved "
                f"and sent to your pharmacy."
            ),
            "denied": (
                f"Hi {req['first_name']}, your provider "
                f"needs to discuss your "
                f"{req['medication_name']} refill with you. "
                f"Please call the office."
            ),
            "filled": (
                f"Hi {req['first_name']}, your "
                f"{req['medication_name']} is ready for "
                f"pickup at your pharmacy."
            ),
        }

        if status in messages:
            await self.sms.send(req["phone"], messages[status])
```

## FAQ

### How does the agent handle controlled substance prescriptions differently?

Controlled substances (Schedule II-V) always require explicit provider review — the auto-approval path is disabled. The agent flags these requests with the DEA schedule classification and presents additional verification fields to the provider, including the patient's prescription drug monitoring program (PDMP) report. Schedule II medications cannot be refilled at all and require a new prescription.

### What happens when a patient requests a refill but has zero refills remaining?

The agent informs the patient that no refills are available and offers to send a new prescription request to their provider. It creates a "renewal request" instead of a refill request, which goes through the full provider review workflow. The provider can then issue a new prescription with a fresh refill count if clinically appropriate.

### How does the agent coordinate with multiple pharmacies if a patient switches?

The agent maintains the patient's current preferred pharmacy and allows pharmacy changes at refill time. When a pharmacy change is detected, the agent sends a cancellation to the old pharmacy and routes the new fill to the updated pharmacy, ensuring no duplicate dispensing occurs.

---

#PrescriptionRefill #PharmacyIntegration #HealthcareAI #NCPDPSCRIPT #Python #AgenticAI #LearnAI #AIEngineering

---

Source: https://callsphere.ai/blog/ai-agent-prescription-refill-management-automated-pharmacy-coordination
