Eedesy
Book Demo
HomeProductsContact
AI Voice Agent
  • Introduction
  • Quick Start
  • Architecture
  • Core Concepts
  • Configuration
  • Creating an Agent
  • Using Templates
  • System Prompt Configuration
  • Language Selection
  • Settings Reference
  • Overview
  • Upload Files (PDF, DOCX)
  • Web Crawling (URLs & Sitemaps)
  • Document Processing
  • RAG Integration
  • Troubleshooting
  • Creating a Campaign
  • CSV Upload & Variables
  • Scheduling & Retry Logic
  • Campaign Analytics
  • Contact Management
  • Uploading Contacts
  • Managing Contacts
  • Call History Enrichment
  • Trial Numbers
  • Purchasing Numbers
  • BYOP Setup
  • Exotel Setup
  • Telephony Providers Guide
  • Credits System
  • Provider Costs Breakdown
  • Usage Analytics
  • Credit Packs
  • Overview
  • Finding Your Workspace ID
  • Common Issues
  • Audio Quality
  • Latency Optimization
  • Error Codes
  • Overview
  • Twilio
  • Exotel
  • Plivo
  • Telnyx
  • WhatsApp
  • WebRTC Browser
  • Overview
  • Deepgram
  • Google Chirp
  • Azure Speech
  • ElevenLabs Scribe
  • AssemblyAI
  • OpenAI Whisper
  • Overview
  • Cartesia
  • ElevenLabs
  • Google TTS
  • Azure Neural
  • OpenAI TTS
  • Deepgram Aura
  • Sarvam Bulbul
  • HeyPixa Luna
  • Overview
  • OpenAI GPT-4o
  • Gemini 2.0/2.5 Flash
  • Gemini Live (Native Audio)
  • OpenAI Realtime
  • Anthropic Claude
  • Azure OpenAI
  • Overview
  • VAD (Voice Activity Detection)
  • Interruption Handling
  • Turn Detection
  • Audio Processing
  • Function Calling
  • Call Transfer
  • DTMF Handling
  • Call Recording
  • Exporting Recordings
  • Transcripts
  • Webhooks
  • Variables & Templates
  • Multi-Language Support
  • Hindi
  • Tamil
  • Assamese
  • Other Indian Languages
  • Latency Optimization
  • Scaling & Performance
  • Error Handling
  • Monitoring & Logging
  • Security Best Practices
  • Trigger Call via API
  • REST API
  • WebSocket Protocol
  • Webhooks
  • Webhook Subscriptions
  • SDKs
  • Overview
  • Financial Services
  • E-commerce
  • Logistics
  • Hyperlocal
  • Healthcare
  • Education
  • Overview
  • Customer Support
  • Sales & Lead Conversion
  • Marketing Campaigns
  • Debt Collection
  • Overview
  • Customer Support Bot
  • Order Status IVR
  • Appointment Booking
  • Lead Qualification
  • Outbound Sales
  • Recruitment Screening
  • Overview
  • Migrate from Vapi
  • Migrate from Retell AI
  • Migrate from Traditional IVR

Related Products

  • AI Voice Agent
  • AI Voice Assistant
  • Try Free
AI Voice Agent
  • Introduction
  • Quick Start
  • Architecture
  • Core Concepts
  • Configuration
  • Creating an Agent
  • Using Templates
  • System Prompt Configuration
  • Language Selection
  • Settings Reference
  • Overview
  • Upload Files (PDF, DOCX)
  • Web Crawling (URLs & Sitemaps)
  • Document Processing
  • RAG Integration
  • Troubleshooting
  • Creating a Campaign
  • CSV Upload & Variables
  • Scheduling & Retry Logic
  • Campaign Analytics
  • Contact Management
  • Uploading Contacts
  • Managing Contacts
  • Call History Enrichment
  • Trial Numbers
  • Purchasing Numbers
  • BYOP Setup
  • Exotel Setup
  • Telephony Providers Guide
  • Credits System
  • Provider Costs Breakdown
  • Usage Analytics
  • Credit Packs
  • Overview
  • Finding Your Workspace ID
  • Common Issues
  • Audio Quality
  • Latency Optimization
  • Error Codes
  • Overview
  • Twilio
  • Exotel
  • Plivo
  • Telnyx
  • WhatsApp
  • WebRTC Browser
  • Overview
  • Deepgram
  • Google Chirp
  • Azure Speech
  • ElevenLabs Scribe
  • AssemblyAI
  • OpenAI Whisper
  • Overview
  • Cartesia
  • ElevenLabs
  • Google TTS
  • Azure Neural
  • OpenAI TTS
  • Deepgram Aura
  • Sarvam Bulbul
  • HeyPixa Luna
  • Overview
  • OpenAI GPT-4o
  • Gemini 2.0/2.5 Flash
  • Gemini Live (Native Audio)
  • OpenAI Realtime
  • Anthropic Claude
  • Azure OpenAI
  • Overview
  • VAD (Voice Activity Detection)
  • Interruption Handling
  • Turn Detection
  • Audio Processing
  • Function Calling
  • Call Transfer
  • DTMF Handling
  • Call Recording
  • Exporting Recordings
  • Transcripts
  • Webhooks
  • Variables & Templates
  • Multi-Language Support
  • Hindi
  • Tamil
  • Assamese
  • Other Indian Languages
  • Latency Optimization
  • Scaling & Performance
  • Error Handling
  • Monitoring & Logging
  • Security Best Practices
  • Trigger Call via API
  • REST API
  • WebSocket Protocol
  • Webhooks
  • Webhook Subscriptions
  • SDKs
  • Overview
  • Financial Services
  • E-commerce
  • Logistics
  • Hyperlocal
  • Healthcare
  • Education
  • Overview
  • Customer Support
  • Sales & Lead Conversion
  • Marketing Campaigns
  • Debt Collection
  • Overview
  • Customer Support Bot
  • Order Status IVR
  • Appointment Booking
  • Lead Qualification
  • Outbound Sales
  • Recruitment Screening
  • Overview
  • Migrate from Vapi
  • Migrate from Retell AI
  • Migrate from Traditional IVR
  1. Docs
  2. AI Voice Agent
  3. Industries
  4. Healthcare

Healthcare Voice Agents

Build HIPAA-compliant AI voice agents for healthcare - appointment scheduling, prescription refills, lab results, patient follow-ups, and EHR integration.

Healthcare Voice Agents

Build intelligent, HIPAA-compliant voice agents for healthcare organizations that handle appointment scheduling, prescription refills, lab results notifications, and patient follow-ups with seamless EHR integration.

Use Cases

Use Case Description Automation Rate
Appointment Scheduling Book, reschedule, cancel appointments 70-85%
Appointment Reminders Outbound confirmation calls 90%+
Prescription Refills Process refill requests 60-75%
Lab Results Notification Notify patients when results are ready 85%+
Patient Follow-ups Post-visit check-ins and care instructions 75-85%
Insurance Verification Verify coverage before appointments 50-65%
Bill Payment Payment reminders and processing 65-80%

Architecture Overview

Patient Call → Telephony (Twilio/Exotel)
                      ↓
           ┌──────────────────────┐
           │   Voice Pipeline     │
           │                      │
           │  STT → LLM → TTS     │
           │         ↓            │
           │   Tool Executor      │
           └──────────┬───────────┘
                      ↓
    ┌─────────────────┼─────────────────┐
    ↓                 ↓                 ↓
┌────────┐    ┌────────────┐    ┌────────────┐
│  EHR   │    │ Scheduling │    │  Patient   │
│ System │    │   System   │    │  Portal    │
│(Epic,  │    │(Calendly,  │    │(MyChart,   │
│ Cerner)│    │ Nexmo)     │    │ Athena)    │
└────────┘    └────────────┘    └────────────┘

Agent Configuration

HIPAA-Compliant Configuration

{
  "agent": {
    "name": "MedAssist",
    "language": "en-US",

    "llmProvider": "gemini-2.5",
    "llmModel": "gemini-2.5-flash-lite",
    "llmTemperature": 0.3,

    "sttProvider": "deepgram",
    "sttModel": "nova-3-medical",
    "sttConfig": {
      "model": "nova-3-medical",
      "endpointing": 400,
      "interimResults": true,
      "smartFormat": true,
      "keywords": [
        "prescription:2",
        "refill:2",
        "appointment:2",
        "doctor:2",
        "medication:2"
      ]
    },

    "ttsProvider": "azure",
    "ttsVoice": "en-US-JennyNeural",
    "ttsConfig": {
      "speakingRate": 0.95,
      "pitch": "default"
    },

    "greetingMessage": "Hello, thank you for calling City Medical Center. This is an automated assistant. How may I help you today?",

    "allowInterruptions": true,

    "prompt": "...",

    "tools": [],

    "webhooks": {
      "url": "https://your-hipaa-server.com/webhooks/voice",
      "events": ["call.ended", "appointment.booked", "refill.requested"],
      "headers": {
        "X-HIPAA-Audit": "enabled"
      }
    },

    "security": {
      "piiRedaction": true,
      "transcriptEncryption": true,
      "recordingEnabled": false,
      "auditLogging": true,
      "dataRetentionDays": 90
    }
  }
}

Multi-Language Healthcare Configuration (Spanish)

{
  "agent": {
    "name": "MedAssist Espanol",
    "language": "es-US",

    "llmProvider": "gemini-2.5",
    "llmModel": "gemini-2.5-flash-lite",

    "sttProvider": "deepgram",
    "sttModel": "nova-3",
    "sttConfig": {
      "language": "es",
      "model": "nova-3"
    },

    "ttsProvider": "azure",
    "ttsVoice": "es-US-AlonsoNeural",

    "greetingMessage": "Hola, gracias por llamar al Centro Medico de la Ciudad. Soy un asistente automatizado. Como puedo ayudarle hoy?"
  }
}

System Prompt

You are a medical receptionist AI for City Medical Center. You handle patient calls professionally, empathetically, and efficiently while maintaining strict HIPAA compliance.

## Your Role
- Schedule, reschedule, and cancel patient appointments
- Process prescription refill requests
- Provide general clinic information
- Notify patients about lab results availability
- Conduct post-visit follow-up calls
- Transfer to human staff for clinical questions

## HIPAA Compliance Requirements

### Identity Verification (REQUIRED before disclosing ANY patient information)
Before providing appointment details, lab results, or any PHI:
1. Ask for patient's full name
2. Ask for date of birth
3. Verify phone number matches records

Script: "For your privacy and security, I need to verify your identity. Could you please provide your full name and date of birth?"

### Information You CAN Share (after verification)
- Appointment dates and times
- Prescription refill status (ready/not ready)
- Lab results availability (NOT the actual results)
- General clinic hours and location
- Provider names and specialties

### Information You CANNOT Share
- Actual lab results or test values
- Diagnoses or medical conditions
- Treatment details
- Information about other patients
- Information to unverified callers

### Safe Responses for Sensitive Topics
- Lab results content: "Your lab results are ready. Please log into MyChart or speak with your provider to review them."
- Medical advice: "I'm not able to provide medical advice. Would you like me to schedule an appointment or transfer you to a nurse?"
- Prescriptions issues: "I'll send a message to the pharmacy team. They'll call you back within 2 hours."

## Guidelines

### Appointment Scheduling Flow
1. Verify patient identity (name + DOB)
2. Ask what type of appointment they need
3. Ask for preferred provider (if any)
4. Check availability using the tool
5. Offer 2-3 available time slots
6. Confirm selection and provide instructions
7. Offer to add to calendar or send SMS confirmation

### Prescription Refill Flow
1. Verify patient identity
2. Ask for medication name and pharmacy
3. Check refill eligibility
4. Submit request or explain why it cannot be processed
5. Provide expected timeline

### Speaking Style
- Warm but professional
- Use simple, clear language
- Spell out medical terms if needed
- Speak at a measured pace
- Show empathy for health concerns

### Date/Time Handling
- Always confirm: "That's Monday, January 15th at 2:30 PM, is that correct?"
- Use 12-hour format with AM/PM
- Mention day of week AND date

### Escalation Triggers - Transfer to Human Staff
- Medical symptoms or emergencies
- Billing disputes
- Insurance questions
- Complaints
- Patient requests human
- Prescription questions requiring clinical judgment
- Mental health crises

## Clinic Information
- Name: City Medical Center
- Hours: Monday-Friday 8 AM - 6 PM, Saturday 9 AM - 1 PM
- Address: 100 Healthcare Drive, Suite 200
- Phone: (555) 123-4567
- Patient Portal: mychart.citymedical.com
- Pharmacy: On-site, open same hours

## Appointment Types
| Type | Duration | Providers |
|------|----------|-----------|
| New Patient | 45 min | All providers |
| Follow-up | 15 min | All providers |
| Annual Physical | 60 min | Dr. Smith, Dr. Johnson |
| Sick Visit | 20 min | All providers |
| Telehealth | 15 min | All providers |

## Example Conversations

**Appointment Scheduling:**
Patient: "I need to schedule a checkup"
You: "I'd be happy to help you schedule a checkup. For your security, could you please provide your full name and date of birth?"
Patient: "John Smith, March 15, 1980"
You: "Thank you, Mr. Smith. I've verified your information. Do you have a preferred provider, or would you like the next available appointment?"

**Prescription Refill:**
Patient: "I need to refill my blood pressure medication"
You: "I can help with that. First, for your security, may I have your full name and date of birth?"
Patient: "Mary Johnson, July 22, 1965"
You: "Thank you, Mrs. Johnson. What's the name of the medication you need refilled, and which pharmacy should we send it to?"

**Lab Results (Proper Handling):**
Patient: "Are my lab results back?"
You: "Let me check for you. For your security, could you please provide your full name and date of birth?"
Patient: "Robert Williams, November 3, 1975"
You: "Thank you, Mr. Williams. Yes, your lab results are now available. For detailed results, please log into MyChart at mychart.citymedical.com, or your provider will discuss them at your next appointment. Would you like to schedule a follow-up?"

Tools

Patient Identity Verification

{
  "type": "function",
  "function": {
    "name": "verify_patient_identity",
    "description": "Verify patient identity using name and date of birth. MUST be called before accessing any patient information.",
    "parameters": {
      "type": "object",
      "properties": {
        "full_name": {
          "type": "string",
          "description": "Patient's full name"
        },
        "date_of_birth": {
          "type": "string",
          "description": "Patient's date of birth (YYYY-MM-DD)"
        },
        "phone_number": {
          "type": "string",
          "description": "Caller's phone number for verification"
        }
      },
      "required": ["full_name", "date_of_birth"]
    }
  }
}

Check Appointment Availability

{
  "type": "function",
  "function": {
    "name": "check_availability",
    "description": "Check available appointment slots for a specific provider or appointment type",
    "parameters": {
      "type": "object",
      "properties": {
        "appointment_type": {
          "type": "string",
          "enum": ["new_patient", "follow_up", "annual_physical", "sick_visit", "telehealth"],
          "description": "Type of appointment"
        },
        "provider_id": {
          "type": "string",
          "description": "Specific provider ID (optional)"
        },
        "preferred_date": {
          "type": "string",
          "description": "Preferred date (YYYY-MM-DD)"
        },
        "time_preference": {
          "type": "string",
          "enum": ["morning", "afternoon", "any"],
          "description": "Time of day preference"
        }
      },
      "required": ["appointment_type"]
    }
  }
}

Book Appointment

{
  "type": "function",
  "function": {
    "name": "book_appointment",
    "description": "Book an appointment for a verified patient",
    "parameters": {
      "type": "object",
      "properties": {
        "patient_id": {
          "type": "string",
          "description": "Verified patient ID from identity check"
        },
        "provider_id": {
          "type": "string",
          "description": "Provider ID"
        },
        "appointment_type": {
          "type": "string",
          "description": "Type of appointment"
        },
        "datetime": {
          "type": "string",
          "description": "Appointment datetime (ISO 8601)"
        },
        "reason": {
          "type": "string",
          "description": "Reason for visit"
        },
        "send_confirmation": {
          "type": "boolean",
          "description": "Send SMS/email confirmation",
          "default": true
        }
      },
      "required": ["patient_id", "provider_id", "appointment_type", "datetime"]
    }
  }
}

Request Prescription Refill

{
  "type": "function",
  "function": {
    "name": "request_prescription_refill",
    "description": "Submit a prescription refill request",
    "parameters": {
      "type": "object",
      "properties": {
        "patient_id": {
          "type": "string",
          "description": "Verified patient ID"
        },
        "medication_name": {
          "type": "string",
          "description": "Name of medication"
        },
        "pharmacy_name": {
          "type": "string",
          "description": "Preferred pharmacy"
        },
        "pharmacy_phone": {
          "type": "string",
          "description": "Pharmacy phone number"
        },
        "urgency": {
          "type": "string",
          "enum": ["routine", "urgent"],
          "description": "Urgency level"
        }
      },
      "required": ["patient_id", "medication_name"]
    }
  }
}

Check Lab Results Status

{
  "type": "function",
  "function": {
    "name": "check_lab_results_status",
    "description": "Check if lab results are available (does NOT return actual results)",
    "parameters": {
      "type": "object",
      "properties": {
        "patient_id": {
          "type": "string",
          "description": "Verified patient ID"
        }
      },
      "required": ["patient_id"]
    }
  }
}

Transfer to Clinical Staff

{
  "type": "function",
  "function": {
    "name": "transfer_to_staff",
    "description": "Transfer call to appropriate clinical or administrative staff",
    "parameters": {
      "type": "object",
      "properties": {
        "department": {
          "type": "string",
          "enum": ["nursing", "billing", "records", "pharmacy", "front_desk", "urgent"],
          "description": "Department to transfer to"
        },
        "reason": {
          "type": "string",
          "description": "Reason for transfer"
        },
        "patient_id": {
          "type": "string",
          "description": "Patient ID for context"
        },
        "priority": {
          "type": "string",
          "enum": ["normal", "high", "urgent"],
          "description": "Call priority"
        }
      },
      "required": ["department", "reason"]
    }
  }
}

Tool Handlers

Patient Verification Handler

func handleVerifyPatientIdentity(params map[string]any) (string, error) {
    fullName := params["full_name"].(string)
    dob := params["date_of_birth"].(string)
    callerPhone := params["phone_number"].(string)

    // Query EHR system
    patient, err := ehrClient.FindPatient(fullName, dob)
    if err != nil {
        logSecurityEvent("verification_failed", fullName, callerPhone)
        return "I couldn't verify that information. Please check and try again, or I can transfer you to our front desk.", nil
    }

    // Verify phone matches (optional additional security)
    if callerPhone != "" && !matchesPatientPhone(patient, callerPhone) {
        logSecurityEvent("phone_mismatch", fullName, callerPhone)
        // Continue but flag for review
    }

    // Store verified patient ID in session
    session.Set("verified_patient_id", patient.ID)
    session.Set("patient_name", patient.FirstName)

    logAudit("patient_verified", patient.ID, callerPhone)

    return fmt.Sprintf("Thank you, %s. I've verified your information. How can I help you today?",
        patient.FirstName), nil
}

Appointment Booking Handler

func handleBookAppointment(params map[string]any) (string, error) {
    patientID := params["patient_id"].(string)
    providerID := params["provider_id"].(string)
    aptType := params["appointment_type"].(string)
    datetime := params["datetime"].(string)

    // Parse datetime
    aptTime, err := time.Parse(time.RFC3339, datetime)
    if err != nil {
        return "I'm having trouble with that date and time. Could you please confirm?", nil
    }

    // Book in scheduling system
    appointment, err := schedulingClient.BookAppointment(BookingRequest{
        PatientID:      patientID,
        ProviderID:     providerID,
        Type:           aptType,
        DateTime:       aptTime,
        Duration:       getAppointmentDuration(aptType),
        ConfirmationSMS: true,
    })

    if err != nil {
        if errors.Is(err, ErrSlotTaken) {
            return "I'm sorry, that slot was just taken. Let me find another option.", nil
        }
        return "I'm having trouble booking that appointment. Let me transfer you to our scheduling team.", nil
    }

    // Log to EHR
    ehrClient.LogAppointment(appointment)

    // Audit log
    logAudit("appointment_booked", patientID, appointment.ID)

    return fmt.Sprintf(
        "I've scheduled your %s appointment with %s for %s at %s. "+
        "You'll receive a confirmation text shortly. "+
        "Please arrive 15 minutes early with your insurance card. Is there anything else I can help with?",
        aptType,
        appointment.ProviderName,
        aptTime.Format("Monday, January 2nd"),
        aptTime.Format("3:04 PM"),
    ), nil
}

Prescription Refill Handler

func handlePrescriptionRefill(params map[string]any) (string, error) {
    patientID := params["patient_id"].(string)
    medicationName := params["medication_name"].(string)
    pharmacyName := params["pharmacy_name"].(string)
    urgency := params["urgency"].(string)

    // Check refill eligibility
    eligibility, err := ehrClient.CheckRefillEligibility(patientID, medicationName)
    if err != nil {
        return "I'm having trouble checking that prescription. Let me transfer you to our pharmacy team.", nil
    }

    if !eligibility.Eligible {
        switch eligibility.Reason {
        case "no_refills":
            return "That prescription has no refills remaining. I'll send a message to your provider to request a new prescription. They'll review it within 24-48 hours.", nil
        case "too_early":
            return fmt.Sprintf("That prescription isn't due for a refill until %s. Would you like me to set a reminder?",
                eligibility.NextRefillDate.Format("January 2")), nil
        case "controlled_substance":
            return "For this medication, please speak with your provider directly. Would you like to schedule an appointment?", nil
        }
    }

    // Submit refill request
    refillRequest, err := pharmacyClient.SubmitRefillRequest(RefillRequest{
        PatientID:     patientID,
        Medication:    medicationName,
        Pharmacy:      pharmacyName,
        Urgency:       urgency,
    })

    if err != nil {
        return "I couldn't submit that refill request. Let me transfer you to our pharmacy team.", nil
    }

    logAudit("refill_requested", patientID, refillRequest.ID)

    timeline := "24-48 hours"
    if urgency == "urgent" {
        timeline = "4-6 hours"
    }

    return fmt.Sprintf(
        "I've submitted your refill request for %s to %s. "+
        "It should be ready within %s. "+
        "The pharmacy will text you when it's ready. Is there anything else?",
        medicationName, pharmacyName, timeline,
    ), nil
}

EHR Integration

Epic Integration

type EpicClient struct {
    baseURL     string
    clientID    string
    privateKey  *rsa.PrivateKey
    accessToken string
    httpClient  *http.Client
}

func (c *EpicClient) GetPatientAppointments(patientID string) ([]Appointment, error) {
    // FHIR R4 Appointment search
    url := fmt.Sprintf("%s/api/FHIR/R4/Appointment?patient=%s&status=booked",
        c.baseURL, patientID)

    req, _ := http.NewRequest("GET", url, nil)
    req.Header.Set("Authorization", "Bearer "+c.accessToken)
    req.Header.Set("Accept", "application/fhir+json")

    resp, err := c.httpClient.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    var bundle FHIRBundle
    json.NewDecoder(resp.Body).Decode(&bundle)

    return parseAppointments(bundle), nil
}

func (c *EpicClient) CreateAppointment(apt Appointment) (*Appointment, error) {
    fhirApt := toFHIRAppointment(apt)

    body, _ := json.Marshal(fhirApt)
    req, _ := http.NewRequest("POST", c.baseURL+"/api/FHIR/R4/Appointment", bytes.NewReader(body))
    req.Header.Set("Authorization", "Bearer "+c.accessToken)
    req.Header.Set("Content-Type", "application/fhir+json")

    resp, err := c.httpClient.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    if resp.StatusCode != 201 {
        return nil, fmt.Errorf("failed to create appointment: %s", resp.Status)
    }

    var created FHIRAppointment
    json.NewDecoder(resp.Body).Decode(&created)

    return fromFHIRAppointment(created), nil
}

Cerner Integration

type CernerClient struct {
    baseURL     string
    credentials OAuthCredentials
}

func (c *CernerClient) FindPatient(name, dob string) (*Patient, error) {
    // FHIR R4 Patient search
    url := fmt.Sprintf("%s/Patient?name=%s&birthdate=%s",
        c.baseURL,
        url.QueryEscape(name),
        dob,
    )

    req, _ := http.NewRequest("GET", url, nil)
    req.Header.Set("Authorization", "Bearer "+c.credentials.AccessToken)

    resp, err := c.httpClient.Do(req)
    if err != nil {
        return nil, err
    }

    var bundle FHIRBundle
    json.NewDecoder(resp.Body).Decode(&bundle)

    if len(bundle.Entry) == 0 {
        return nil, ErrPatientNotFound
    }

    return parsePatient(bundle.Entry[0]), nil
}

HL7 FHIR Webhook Handler

type FHIRWebhookHandler struct {
    voiceClient *VoiceAgentClient
}

func (h *FHIRWebhookHandler) HandleLabResult(w http.ResponseWriter, r *http.Request) {
    var observation FHIRObservation
    json.NewDecoder(r.Body).Decode(&observation)

    patientID := extractPatientID(observation.Subject)

    patient, _ := h.ehrClient.GetPatient(patientID)
    if patient.NotificationPreference == "phone" {
        // Trigger outbound call
        h.voiceClient.InitiateCall(CallRequest{
            AgentID: "lab_notification",
            To:      patient.Phone,
            Variables: map[string]string{
                "patientName": patient.FirstName,
                "testType":    observation.Code.Display,
            },
        })
    }

    w.WriteHeader(http.StatusOK)
}

HIPAA Compliance

PHI Handling

type HIPAACompliantSession struct {
    callID           string
    verifiedPatient  *Patient
    accessLog        []AccessLogEntry
    piiRedactor      *PIIRedactor
    encryptionKey    []byte
}

func (s *HIPAACompliantSession) LogPHIAccess(dataType, action string) {
    entry := AccessLogEntry{
        Timestamp:  time.Now(),
        CallID:     s.callID,
        PatientID:  s.verifiedPatient.ID,
        DataType:   dataType,
        Action:     action,
        AccessedBy: "voice_agent",
    }

    s.accessLog = append(s.accessLog, entry)

    // Write to HIPAA audit log
    hipaaAuditLog.Write(entry)
}

func (s *HIPAACompliantSession) GetTranscript() string {
    rawTranscript := s.conversation.GetTranscript()

    // Redact PHI before storage
    return s.piiRedactor.RedactPHI(rawTranscript)
}

PHI Redaction

type HealthcarePIIRedactor struct {
    patterns map[string]*regexp.Regexp
}

func NewHealthcarePIIRedactor() *HealthcarePIIRedactor {
    return &HealthcarePIIRedactor{
        patterns: map[string]*regexp.Regexp{
            // Standard PII
            "ssn":         regexp.MustCompile(`\b\d{3}-\d{2}-\d{4}\b`),
            "phone":       regexp.MustCompile(`\b\d{3}[-.]?\d{3}[-.]?\d{4}\b`),
            "email":       regexp.MustCompile(`\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b`),

            // Healthcare-specific
            "mrn":         regexp.MustCompile(`\b[A-Z]?\d{6,10}\b`), // Medical Record Number
            "dob":         regexp.MustCompile(`\b\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b`),
            "insurance_id": regexp.MustCompile(`\b[A-Z]{3}\d{9}\b`),
            "npi":         regexp.MustCompile(`\b\d{10}\b`), // National Provider ID

            // Drug/Prescription info (context-dependent)
            "dosage":      regexp.MustCompile(`\b\d+\s*(mg|mcg|ml|units?)\b`),
        },
    }
}

func (r *HealthcarePIIRedactor) RedactPHI(text string) string {
    redacted := text

    replacements := map[string]string{
        "ssn":         "[SSN_REDACTED]",
        "phone":       "[PHONE_REDACTED]",
        "mrn":         "[MRN_REDACTED]",
        "dob":         "[DOB_REDACTED]",
        "insurance_id": "[INSURANCE_REDACTED]",
    }

    for name, pattern := range r.patterns {
        if replacement, ok := replacements[name]; ok {
            redacted = pattern.ReplaceAllString(redacted, replacement)
        }
    }

    return redacted
}

Audit Logging

type HIPAAAuditLogger struct {
    storage    AuditStorage
    encryption *EncryptionService
}

type AuditEntry struct {
    ID            string    `json:"id"`
    Timestamp     time.Time `json:"timestamp"`
    EventType     string    `json:"event_type"`
    UserType      string    `json:"user_type"` // patient, staff, system
    UserID        string    `json:"user_id"`
    PatientID     string    `json:"patient_id"`
    Resource      string    `json:"resource"` // appointment, prescription, lab_result
    Action        string    `json:"action"`   // create, read, update, delete
    Outcome       string    `json:"outcome"`  // success, failure
    IPAddress     string    `json:"ip_address"`
    CallID        string    `json:"call_id,omitempty"`
    Details       string    `json:"details,omitempty"`
}

func (l *HIPAAAuditLogger) LogAccess(entry AuditEntry) error {
    entry.ID = uuid.New().String()
    entry.Timestamp = time.Now().UTC()

    // Encrypt sensitive fields
    if entry.Details != "" {
        encrypted, _ := l.encryption.Encrypt([]byte(entry.Details))
        entry.Details = base64.StdEncoding.EncodeToString(encrypted)
    }

    // Store with retention policy (6 years for HIPAA)
    return l.storage.Store(entry, 6*365*24*time.Hour)
}

func (l *HIPAAAuditLogger) LogVoiceAccess(callID, patientID, dataAccessed string) {
    l.LogAccess(AuditEntry{
        EventType: "phi_access",
        UserType:  "system",
        UserID:    "voice_agent",
        PatientID: patientID,
        Resource:  dataAccessed,
        Action:    "read",
        Outcome:   "success",
        CallID:    callID,
    })
}

Data Encryption

type HIPAAEncryption struct {
    kms        KeyManagementService
    dataKey    []byte
    keyVersion string
}

func (e *HIPAAEncryption) EncryptPHI(data []byte) ([]byte, error) {
    block, _ := aes.NewCipher(e.dataKey)
    gcm, _ := cipher.NewGCM(block)

    nonce := make([]byte, gcm.NonceSize())
    io.ReadFull(rand.Reader, nonce)

    ciphertext := gcm.Seal(nonce, nonce, data, nil)

    // Prepend key version for key rotation support
    return append([]byte(e.keyVersion+":"), ciphertext...), nil
}

func (e *HIPAAEncryption) EncryptTranscript(transcript string) (string, error) {
    encrypted, err := e.EncryptPHI([]byte(transcript))
    if err != nil {
        return "", err
    }
    return base64.StdEncoding.EncodeToString(encrypted), nil
}

Outbound Campaigns

Appointment Reminders

type AppointmentReminderCampaign struct {
    voiceClient   *VoiceAgentClient
    ehrClient     *EHRClient
    agentID       string
}

func (c *AppointmentReminderCampaign) SendReminders() {
    // Get tomorrow's appointments
    tomorrow := time.Now().Add(24 * time.Hour)
    appointments, _ := c.ehrClient.GetAppointmentsForDate(tomorrow)

    for _, apt := range appointments {
        // Check patient notification preferences
        patient, _ := c.ehrClient.GetPatient(apt.PatientID)

        if patient.PreferredContact == "phone" {
            c.initiateReminderCall(patient, apt)
        }
    }
}

func (c *AppointmentReminderCampaign) initiateReminderCall(patient *Patient, apt Appointment) {
    c.voiceClient.InitiateCall(CallRequest{
        AgentID: c.agentID,
        To:      patient.Phone,
        Variables: map[string]string{
            "patientName":     patient.FirstName,
            "appointmentTime": apt.DateTime.Format("3:04 PM"),
            "appointmentDate": apt.DateTime.Format("January 2"),
            "providerName":    apt.ProviderName,
            "appointmentType": apt.Type,
            "location":        apt.Location,
        },
        Webhook: "https://api.clinic.com/webhooks/reminder-outcome",
    })
}

Reminder Agent Prompt:

You are calling to remind a patient about their upcoming appointment.

Greeting: "Hello, this is City Medical Center calling for {{patientName}}. I'm calling to remind you about your {{appointmentType}} appointment tomorrow, {{appointmentDate}} at {{appointmentTime}} with {{providerName}}."

## If Patient Confirms
"Wonderful! Please remember to arrive 15 minutes early and bring your insurance card and photo ID. We look forward to seeing you!"

## If Patient Needs to Reschedule
Use the reschedule_appointment tool to find a new time.
"I'd be happy to help you reschedule. Do you have a preference for morning or afternoon?"

## If Patient Cancels
"I understand. I've canceled your appointment. Would you like to schedule a new appointment for a later date?"
Document the cancellation reason.

## If Voicemail
"Hello {{patientName}}, this is City Medical Center reminding you of your appointment tomorrow, {{appointmentDate}} at {{appointmentTime}}. Please call us at 555-123-4567 if you need to reschedule. Thank you."

## Important
- Speak clearly and at a moderate pace
- Do not leave PHI in voicemails beyond appointment time
- If patient has questions, offer to transfer to staff

Post-Visit Follow-up

func (c *FollowUpCampaign) SendFollowUps() {
    // Get visits from 24-48 hours ago
    visits, _ := c.ehrClient.GetRecentVisits(24*time.Hour, 48*time.Hour)

    for _, visit := range visits {
        // Skip if patient opted out
        if visit.Patient.OptedOutFollowUp {
            continue
        }

        c.initiateFollowUpCall(visit)
    }
}

Follow-up Agent Prompt:

You are calling to check on a patient after their recent visit.

Greeting: "Hello, this is City Medical Center calling for {{patientName}}. I'm calling to check in after your visit on {{visitDate}}. Do you have a few minutes?"

## If Yes
"How are you feeling since your visit? Any questions or concerns about your care plan?"

Listen for:
- Medication side effects → Offer to connect to pharmacy/nursing
- Worsening symptoms → Recommend appropriate action or transfer to clinical staff
- Questions about instructions → Answer if within scope, otherwise transfer
- Positive feedback → Document and thank them

## If Concerns Raised
"I'm sorry to hear that. Let me connect you with our nursing staff who can help."
Use transfer_to_staff with department="nursing".

## If All is Well
"That's great to hear! Remember, you can always reach us at 555-123-4567 or through MyChart if anything comes up. Take care!"

## Key Points
- Be empathetic and caring
- Don't provide medical advice
- Document any concerns raised
- Escalate clinical concerns immediately

Metrics and Analytics

Healthcare-Specific KPIs

type HealthcareMetrics struct {
    // Efficiency
    TotalCalls              int
    AutomatedResolutionRate float64  // Target: 70%+
    AverageHandleTime       time.Duration
    TransferRate            float64

    // Appointment Management
    AppointmentsBooked      int
    AppointmentsRescheduled int
    AppointmentsCanceled    int
    NoShowRate              float64  // Target: <10%

    // Patient Satisfaction
    CSAT                    float64  // Target: 4.5+/5
    FCR                     float64  // First Call Resolution

    // Clinical
    RefillRequestsProcessed int
    LabNotificationsSent    int
    UrgentTransfers         int

    // Compliance
    VerificationSuccessRate float64
    PHIAccessAttempts       int
    FailedVerifications     int
}

func trackHealthcareCall(call *Call) {
    metrics.Increment("healthcare.calls.total")
    metrics.Gauge("healthcare.handle_time", call.Duration.Seconds())

    switch call.Outcome {
    case "appointment_booked":
        metrics.Increment("healthcare.appointments.booked")
    case "refill_requested":
        metrics.Increment("healthcare.refills.requested")
    case "transferred":
        metrics.Increment("healthcare.calls.transferred")
        if call.TransferReason == "clinical" {
            metrics.Increment("healthcare.transfers.clinical")
        }
    }

    if call.VerificationAttempted {
        if call.VerificationSucceeded {
            metrics.Increment("healthcare.verification.success")
        } else {
            metrics.Increment("healthcare.verification.failed")
        }
    }
}

No-Show Reduction Tracking

type NoShowAnalytics struct {
    db *Database
}

func (a *NoShowAnalytics) CalculateNoShowReduction() NoShowReport {
    // Get no-show rates before and after voice agent
    beforeRate := a.getNoShowRate(time.Now().AddDate(0, -6, 0), time.Now().AddDate(0, -3, 0))
    afterRate := a.getNoShowRate(time.Now().AddDate(0, -3, 0), time.Now())

    reduction := ((beforeRate - afterRate) / beforeRate) * 100

    // Calculate cost savings
    avgAppointmentValue := 150.0 // USD
    appointmentsPerMonth := 1000
    savedAppointments := int(float64(appointmentsPerMonth) * (reduction / 100))
    monthlySavings := float64(savedAppointments) * avgAppointmentValue

    return NoShowReport{
        PreviousNoShowRate: beforeRate,
        CurrentNoShowRate:  afterRate,
        ReductionPercent:   reduction,
        MonthlySavings:     monthlySavings,
    }
}

Dashboard Metrics

type HealthcareDashboard struct {
    metrics MetricsClient
}

func (d *HealthcareDashboard) GetDailyStats() DailyStats {
    today := time.Now().Format("2006-01-02")

    return DailyStats{
        TotalCalls:         d.metrics.Count("healthcare.calls.total", today),
        AppointmentsBooked: d.metrics.Count("healthcare.appointments.booked", today),
        RefillsProcessed:   d.metrics.Count("healthcare.refills.requested", today),
        AutomationRate:     d.metrics.Ratio("healthcare.calls.resolved", "healthcare.calls.total", today),
        AvgHandleTime:      d.metrics.Average("healthcare.handle_time", today),
        PatientSatisfaction: d.metrics.Average("healthcare.csat", today),
    }
}

Best Practices

1. Always Verify Identity First

func (p *Pipeline) processHealthcareRequest(ctx context.Context, request string) {
    session := GetSession(ctx)

    if !session.IsPatientVerified() {
        // Force verification before any PHI access
        response := "For your privacy and security, I need to verify your identity first. " +
                   "Could you please provide your full name and date of birth?"
        p.speak(response)
        return
    }

    // Proceed with request
    p.handleVerifiedRequest(ctx, request)
}

2. Never Provide Clinical Advice

var clinicalKeywords = []string{
    "should I take", "is it safe", "what dose", "side effect",
    "symptoms", "diagnosis", "treatment", "medicine for",
}

func containsClinicalQuestion(text string) bool {
    lower := strings.ToLower(text)
    for _, keyword := range clinicalKeywords {
        if strings.Contains(lower, keyword) {
            return true
        }
    }
    return false
}

func (p *Pipeline) handleMessage(text string) {
    if containsClinicalQuestion(text) {
        p.speak("I'm not able to provide medical advice. Would you like me to " +
               "schedule an appointment with your provider, or transfer you to our nursing staff?")
        return
    }
    // Continue normal processing
}

3. Handle Emergencies Appropriately

var emergencyKeywords = []string{
    "chest pain", "can't breathe", "heart attack", "stroke",
    "unconscious", "bleeding heavily", "severe pain", "suicide",
    "overdose", "emergency",
}

func (p *Pipeline) checkForEmergency(text string) bool {
    lower := strings.ToLower(text)
    for _, keyword := range emergencyKeywords {
        if strings.Contains(lower, keyword) {
            p.handleEmergency()
            return true
        }
    }
    return false
}

func (p *Pipeline) handleEmergency() {
    p.speak("This sounds like a medical emergency. Please hang up and call 911 immediately. " +
           "If you're unable to call, stay on the line and I'll transfer you to emergency services.")

    // Log and alert
    alertOps("Emergency keyword detected", p.session.CallID)

    // Transfer to emergency queue
    p.transferCall("emergency", "Medical emergency detected")
}

4. Maintain Empathetic Tone

var empathyPhrases = map[string][]string{
    "appointment_canceled": {
        "I understand things come up. Let's find a time that works better for you.",
        "No problem at all. When would be a better time for you?",
    },
    "long_wait": {
        "I appreciate your patience. Let me help you right away.",
        "Thank you for waiting. How can I assist you today?",
    },
    "prescription_issue": {
        "I understand how important your medication is. Let me look into this.",
        "I'm sorry for the inconvenience. Let me help resolve this.",
    },
    "test_anxiety": {
        "I understand waiting for results can be stressful. Let me check on that for you.",
    },
}

func getEmpathyPhrase(situation string) string {
    phrases, ok := empathyPhrases[situation]
    if !ok {
        return "I understand. Let me help you with that."
    }
    return phrases[rand.Intn(len(phrases))]
}

5. Secure Call Recording

type HIPAARecorder struct {
    encryption *HIPAAEncryption
    storage    SecureStorage
}

func (r *HIPAARecorder) RecordCall(callID string, audio []byte, transcript string) error {
    // Encrypt audio
    encryptedAudio, err := r.encryption.EncryptPHI(audio)
    if err != nil {
        return err
    }

    // Redact and encrypt transcript
    redactedTranscript := redactPHI(transcript)
    encryptedTranscript, err := r.encryption.EncryptTranscript(redactedTranscript)
    if err != nil {
        return err
    }

    // Store with access controls
    return r.storage.Store(Recording{
        CallID:              callID,
        EncryptedAudio:      encryptedAudio,
        EncryptedTranscript: encryptedTranscript,
        CreatedAt:           time.Now(),
        RetentionUntil:      time.Now().AddDate(6, 0, 0), // 6 year HIPAA retention
        AccessLevel:         "phi_authorized",
    })
}

Security Checklist

HIPAA Technical Safeguards

  • All PHI encrypted at rest (AES-256)
  • All data in transit uses TLS 1.2+
  • Unique user identification for audit trails
  • Automatic logoff after inactivity
  • Audit controls and logging enabled
  • PHI access logged with timestamp, user, action
  • Data integrity controls in place
  • Emergency access procedures documented

Voice Agent Specific

  • Patient identity verification before PHI access
  • PII/PHI redaction in transcripts and logs
  • Clinical questions routed to staff
  • Emergency detection and routing
  • Call recordings encrypted and access-controlled
  • Audit logging for all PHI access
  • BAA in place with all voice/cloud providers
  • Regular security assessments

Vendor Compliance

  • STT provider is HIPAA compliant (BAA signed)
  • TTS provider is HIPAA compliant (BAA signed)
  • LLM provider is HIPAA compliant (BAA signed)
  • Telephony provider is HIPAA compliant (BAA signed)
  • Cloud hosting is HIPAA compliant
  • All subprocessors documented

Next Steps

  • Appointment Booking Example - Generic appointment scheduling
  • Function Calling - Tool integration
  • Security - General security practices
  • Webhooks - EHR integration webhooks
Previous
Hyperlocal
Next
Education

On this page

  • Use Cases
  • Architecture Overview
  • Agent Configuration
  • HIPAA-Compliant Configuration
  • Multi-Language Healthcare Configuration (Spanish)
  • System Prompt
  • Your Role
  • HIPAA Compliance Requirements
  • Identity Verification (REQUIRED before disclosing ANY patient information)
  • Information You CAN Share (after verification)
  • Information You CANNOT Share
  • Safe Responses for Sensitive Topics
  • Guidelines
  • Appointment Scheduling Flow
  • Prescription Refill Flow
  • Speaking Style
  • Date/Time Handling
  • Escalation Triggers - Transfer to Human Staff
  • Clinic Information
  • Appointment Types
  • Example Conversations
  • Tools
  • Patient Identity Verification
  • Check Appointment Availability
  • Book Appointment
  • Request Prescription Refill
  • Check Lab Results Status
  • Transfer to Clinical Staff
  • Tool Handlers
  • Patient Verification Handler
  • Appointment Booking Handler
  • Prescription Refill Handler
  • EHR Integration
  • Epic Integration
  • Cerner Integration
  • HL7 FHIR Webhook Handler
  • HIPAA Compliance
  • PHI Handling
  • PHI Redaction
  • Audit Logging
  • Data Encryption
  • Outbound Campaigns
  • Appointment Reminders
  • If Patient Confirms
  • If Patient Needs to Reschedule
  • If Patient Cancels
  • If Voicemail
  • Important
  • Post-Visit Follow-up
  • If Yes
  • If Concerns Raised
  • If All is Well
  • Key Points
  • Metrics and Analytics
  • Healthcare-Specific KPIs
  • No-Show Reduction Tracking
  • Dashboard Metrics
  • Best Practices
  • 1. Always Verify Identity First
  • 2. Never Provide Clinical Advice
  • 3. Handle Emergencies Appropriately
  • 4. Maintain Empathetic Tone
  • 5. Secure Call Recording
  • Security Checklist
  • HIPAA Technical Safeguards
  • Voice Agent Specific
  • Vendor Compliance
  • Next Steps

Stay Updated

Get the latest updates on AI voice technology, product releases, and exclusive resources.

Get Started

Try our products for free
AI Voice Agent
Build voice AI for calls
WhatsApp AI Bot
Automate WhatsApp chats
Website Chatbot
AI chat for websites
Edesy CRM
Manage leads & customers
Book a DemoCall UsEmail Us
Eedesy

Your all-in-one platform for digital innovation. We build AI-powered solutions that transform how businesses operate.

[email protected]+91 95475 31359

Products

  • AI Voice Assistant
  • WhatsApp Voice AI
  • WhatsApp Bot Builder
  • AI Website Chatbot
  • AI-SDR
  • Number Masking
  • Shopify Apps
  • View All Products

Solutions

  • For E-commerce
  • For Healthcare
  • For Real Estate
  • For Restaurants
  • For Appointments
  • View All Use Cases

Services

  • AI Chatbot Development
  • Voice AI Development
  • Shopify Development
  • SaaS Development
  • WhatsApp API Integration
  • View All Services

Resources

  • Documentation
  • Voice Agent Docs
  • API Reference
  • Number Masking API Docs
  • Blog
  • Changelog
  • Book a Demo

Company

  • About Us
  • Contact
  • Careers
  • Privacy Policy
  • Terms of Service

Products

  • AI Voice Assistant
  • WhatsApp Voice AI
  • WhatsApp Bot Builder
  • AI Website Chatbot
  • AI-SDR
  • Number Masking
  • Shopify Apps
  • View All Products

Solutions

  • For E-commerce
  • For Healthcare
  • For Real Estate
  • For Restaurants
  • For Appointments
  • View All Use Cases

Services

  • AI Chatbot Development
  • Voice AI Development
  • Shopify Development
  • SaaS Development
  • WhatsApp API Integration
  • View All Services

Resources

  • Documentation
  • Voice Agent Docs
  • API Reference
  • Number Masking API Docs
  • Blog
  • Changelog
  • Book a Demo

Company

  • About Us
  • Contact
  • Careers
  • Privacy Policy
  • Terms of Service
  • AI Voice Assistant
  • WhatsApp Voice AI
  • WhatsApp Bot Builder
  • AI Website Chatbot
  • AI-SDR
  • Number Masking
  • Shopify Apps
  • View All Products
  • For E-commerce
  • For Healthcare
  • For Real Estate
  • For Restaurants
  • For Appointments
  • View All Use Cases
  • AI Chatbot Development
  • Voice AI Development
  • Shopify Development
  • SaaS Development
  • WhatsApp API Integration
  • View All Services
  • Documentation
  • Voice Agent Docs
  • API Reference
  • Number Masking API Docs
  • Blog
  • Changelog
  • Book a Demo
  • About Us
  • Contact
  • Careers
  • Privacy Policy
  • Terms of Service

Popular Free Tools

Compress PDFMerge PDFPDF to WordGST CalculatorEMI CalculatorSIP CalculatorJSON FormatterBase64 EncoderImage CompressorQR Code GeneratorVoice AI ROI CalculatorAmazon FBA CalculatorAI Email WriterVideo to GIFPrivacy Policy GeneratorCRM ROI CalculatorMeeting Cost Calculator
Categories:PDF ToolsDeveloper ToolsFinance CalculatorsImage ToolsVideo ToolsAI Writing ToolsAudio ToolsWhatsApp ToolsDocument GeneratorsVoice AI ToolsE-commerce ToolsView All Tools

© 2026 Edesy Technology Labs Pvt Ltd

SSL Secured
99.9% Uptime