A production-ready VoiceAI agent for handling inbound insurance claims support calls. Built using Deepgram Agent API for real-time speech-to-text, text-to-speech, and LLM orchestration, with Supabase for data storage and OpenAI for post-call analysis.
Deployed on Render:
- Phone Number: +1 319 669 8891
- Health Check: https://insurance-claims-agent.onrender.com/health
- Metrics: https://insurance-claims-agent.onrender.com/metrics
Call the number above to test the voice agent. Check the endpoints to see real-time metrics and system health.
This voice agent handles customer service calls for insurance claim status inquiries. When customers call in, the AI agent:
- Authenticates callers by phone number and name verification
- Retrieves their claim status from the database (approved, pending, or requires documentation)
- Answers common FAQ questions (office hours, address, claims process)
- Handles escalation requests and emergency situations
- Logs every call with summaries and sentiment analysis to the database
The agent uses natural conversation to guide callers through the process, automatically handles errors gracefully, and logs all interactions for analytics and quality monitoring.
- Real-time Voice Conversations: Powered by Deepgram Agent API (STT + TTS + LLM)
- Caller Authentication: Phone number lookup with name verification
- Claim Status Retrieval: Real-time queries from Supabase database
- FAQ Support: Answers questions about office hours, addresses, and claims process
- Escalation Handling: Graceful handling of human rep requests and emergency situations
- Post-Call Logging: Automatic summary generation, sentiment analysis, and database logging
- Production Features: Retry logic, circuit breakers, rate limiting, structured logging, metrics, and health checks
┌─────────────┐
│ Twilio │ (Telephony)
└──────┬──────┘
│ WebSocket
▼
┌─────────────────┐
│ main.py │ (WebSocket Server)
│ - Call State │
│ - Logging │
└──────┬──────────┘
│
▼
┌─────────────────┐
│ Deepgram Agent │ (STT/TTS/LLM)
│ API │
└──────┬──────────┘
│
├─────────► OpenAI (Post-call: Summary/Sentiment)
│
▼
┌─────────────────┐
│ insurance_ │
│ functions.py │
└──────┬──────────┘
│
▼
┌─────────────────┐
│ Supabase │ (PostgreSQL Database)
│ - customers │
│ - claims │
│ - interactions │
└─────────────────┘
Technology Stack:
- STT/TTS: Deepgram Nova-3 (STT) and Aura-2-Thalia (TTS)
- LLM: OpenAI GPT-4o-mini (via Deepgram Agent API)
- Database: Supabase (PostgreSQL)
- Telephony: Twilio Media Streams
- Language: Python 3.11+
Before setting up, ensure you have:
- Python 3.11+ installed
- Deepgram API key (Get one here)
- OpenAI API key (Get one here)
- Supabase account (Sign up here)
- Twilio account with a phone number and Media Streams enabled (Sign up here)
cd insurance-claims-agent
pip install -r requirements.txtOr use a virtual environment (recommended):
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txtCreate a .env file in the project root:
cp .env.example .envEdit .env and add your API keys:
# Required
DEEPGRAM_API_KEY=your_deepgram_api_key_here
OPENAI_API_KEY=your_openai_api_key_here
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key_here
# Optional (defaults shown in comments)
# PORT=5000
# LOG_LEVEL=INFO
# MAX_RETRIES=3Where to find credentials:
- Deepgram: https://console.deepgram.com/signup
- OpenAI: https://platform.openai.com/api-keys
- Supabase: Project Settings → API → Project URL and Service Role Key
- Go to your Supabase project: https://supabase.com/dashboard
- Navigate to SQL Editor
- Open
supabase/schema.sqlfrom this project - Copy the entire contents and paste into the SQL Editor
- Click Run to execute
This creates three tables:
customers- Customer phone numbers and namesclaims- Insurance claims linked to customersinteractions- Call logs with summaries and sentiment
The schema includes sample test data for development.
- Log into Twilio Console
- Go to Phone Numbers → Manage → Active numbers
- Click your phone number
- Scroll to Media Streams section
- Enable Media Streams
- Set WebSocket URL to your server URL:
- For local development: Use ngrok WebSocket URL (e.g.,
wss://abc123.ngrok.io) - see "Running Locally" below - For production (Render):
wss://your-app-name.onrender.com(no/twiliopath needed)
- For local development: Use ngrok WebSocket URL (e.g.,
- Ensure format is set to audio/mulaw
- Save
Note: The server handles WebSocket connections at the root path (/), so use just the base URL without any path suffix.
The application is deployed and live on Render:
- Service URL: https://insurance-claims-agent.onrender.com
- Health Check: https://insurance-claims-agent.onrender.com/health
- Metrics: https://insurance-claims-agent.onrender.com/metrics
- Phone Number: +1 319 669 8891
Deployment Details:
- Platform: Render (Free tier - spins down after 15 min inactivity, ~30 sec wake time)
- Auto-deploy: Enabled (automatically deploys on git push to main branch)
- Environment variables: Set in Render dashboard
For deployment instructions, see DEPLOYMENT_RENDER.md.
Note: The server uses a unified HTTP/WebSocket server on a single port (Render's PORT env var), making it compatible with platforms like Render that require all traffic on one port.
For local testing and development, you need to expose your server to the internet so Twilio can connect:
Terminal 1 - Start the server:
python main.pyThe server starts on localhost:5000 by default (configurable via PORT env var).
Terminal 2 - Expose with ngrok:
ngrok http 5000Copy the WebSocket URL from ngrok output (e.g., wss://abc123.ngrok.io) and use it in your Twilio Media Streams configuration (see "Configure Twilio Media Streams" above).
When to use ngrok:
- Local development and testing
- Testing changes before deploying to production
- Debugging issues locally
When not needed:
- Production deployment (use Render URL directly)
- Testing the live deployed version (use +1 319 669 8891)
The server is a standard Python WebSocket application. Deploy to any platform that supports WebSocket connections:
- Railway: Connect your GitHub repo, set environment variables
- Fly.io: Use
fly launchand configure env vars - AWS/GCP/Azure: Deploy as a containerized service
Ensure the platform:
- Supports WebSocket connections
- Allows inbound connections on your configured port
- Has environment variables configured
- Can run Python 3.11+
The server provides two HTTP endpoints for monitoring (on the same port as WebSocket):
Production (Render):
- Health Check: https://insurance-claims-agent.onrender.com/health
- Metrics: https://insurance-claims-agent.onrender.com/metrics
Local Development:
curl http://localhost:5000/health
curl http://localhost:5000/metricsHealth Check returns:
- System health status (healthy/degraded/error)
- Service connectivity (Supabase, OpenAI, Deepgram)
- Basic metrics (active calls, total calls, total interactions)
- Version information
Metrics returns:
- Detailed counters (calls, function calls, API requests, errors)
- Timing statistics (call duration, database queries, API latencies)
- Performance percentiles (p50, p95, p99)
These endpoints are publicly accessible and can be used for monitoring and debugging.
Call the deployed number: +1 319 669 8891
The agent is live and ready to handle calls. Check the metrics endpoint after calling to see real-time statistics.
The schema includes sample test data. Use these phone numbers when the agent asks during a call:
- John Doe:
+15551234567(or555-123-4567) - Sarah Miller:
+15551234568 - Bob Johnson:
+15234567368 - Alice Williams:
+15351145161
- Call +1 319 669 8891
- Agent greets you and asks for your phone number
- Provide:
+15551234567(John Doe) - When asked for your name, say:
John Doe - Agent retrieves and communicates claim status
- Call ends and logs to Supabase
- Check https://insurance-claims-agent.onrender.com/metrics to see the call metrics
- Call +1 319 669 8891
- Agent asks for phone number
- Provide an invalid phone number:
+15559999999 - Agent should handle gracefully and offer human follow-up
- Call ends and logs to Supabase (even failed authentications are logged)
For local testing, you need ngrok running (see "Local Development with ngrok" above):
- Start server:
python main.py - Start ngrok:
ngrok http 5000 - Update Twilio WebSocket URL to ngrok URL:
wss://abc123.ngrok.io - Call your Twilio number
- Test with the same phone numbers listed above
After a call, verify it was logged:
Option 1: Check Metrics Endpoint Visit https://insurance-claims-agent.onrender.com/metrics and look for:
interactions.logged: Should increment after each completed calltotal_interactions: Total number of calls logged
Option 2: Check Supabase Database
Query the interactions table directly:
SELECT * FROM interactions
ORDER BY created_at DESC
LIMIT 5;You should see:
call_id: Unique call identifiercaller_name: Name if authenticated (NULL if not)phone_number: Phone number usedsummary: Generated conversation summary (2-3 sentences from OpenAI)sentiment: positive/neutral/negative (analyzed by OpenAI)transcript: Full conversation transcriptcreated_at: Timestamp
Note: Metrics reset when the server restarts (they're in-memory), but Supabase data is permanent.
insurance-claims-agent/
├── main.py # Main WebSocket server
├── insurance_functions.py # Supabase integration functions
├── config.json # Deepgram Agent API configuration
├── requirements.txt # Python dependencies
├── .env.example # Environment variable template
├── .env # Your environment variables (not in git)
├── README.md # This file
├── utils/ # Utility modules
│ ├── config.py # Configuration management
│ ├── logging.py # Structured logging
│ ├── metrics.py # Metrics collection
│ ├── retry.py # Retry logic with backoff
│ ├── circuit_breaker.py # Circuit breaker pattern
│ └── rate_limiter.py # Rate limiting
└── supabase/
└── schema.sql # Database schema and sample data
- Greeting: Agent greets caller and asks for phone number
- Authentication: Lookup by phone → Verify name → Confirm identity
- Claim Status: Retrieve claim from database → Communicate status clearly
- FAQ/Escalation: Handle questions or requests for human representative
- Call End: Generate summary → Analyze sentiment → Log to database
The agent uses these functions (defined in insurance_functions.py):
lookup_caller_by_phone(phone_number): Lookup customer in Supabaseget_claim_status(phone_number): Retrieve claim status for authenticated callerlog_interaction(...): Log call summary and sentiment (called automatically)
After each call ends:
- Summary Generation: Uses OpenAI to create a 2-3 sentence summary of the conversation
- Sentiment Analysis: Uses OpenAI to determine overall sentiment (positive/neutral/negative)
- Database Logging: Stores all data in Supabase
interactionstable
All configuration is done via environment variables. See .env.example for all available options.
Required:
DEEPGRAM_API_KEY: Deepgram API key for voice AIOPENAI_API_KEY: OpenAI API key for summaries/sentimentSUPABASE_URL: Your Supabase project URLSUPABASE_SERVICE_ROLE_KEY: Supabase service role key
Optional (with defaults):
PORT: Server port (default:5000, Render sets this automatically)HOST: Server host (default:0.0.0.0)LOG_LEVEL: Logging level (default:INFO)MAX_RETRIES: Retry attempts for failed operations (default:3)
Note: When deploying to Render, the PORT environment variable is automatically set by Render - you don't need to configure it manually.
The agent's behavior and prompts are configured in config.json. This file contains:
- Audio settings (encoding, sample rate)
- LLM model and prompts
- Function definitions
- Greeting message
This project includes production-ready features:
- Structured Logging: JSON-formatted logs for easy parsing and aggregation
- Retry Logic: Automatic retries with exponential backoff for transient failures
- Circuit Breaker: Prevents cascading failures when external services are down
- Rate Limiting: Protects against API rate limit violations
- Connection Pooling: Efficient database connection management
- Metrics Collection: Real-time performance and usage metrics
- Health Checks: HTTP endpoints for monitoring and deployment platforms
If port 5000 is in use:
PORT=5001 python main.py- Verify
SUPABASE_URLandSUPABASE_SERVICE_ROLE_KEYin.env - Ensure schema has been run in Supabase SQL Editor
- Check Supabase project is active
Ensure all dependencies are installed:
pip install -r requirements.txtThe server validates required environment variables on startup. If missing, you'll see an error listing what's required.
MIT License
Built for the Observe.AI Take-Home Assessment. Uses patterns and inspiration from:
- Deepgram Voice Agent examples
- Insurance call center AI implementations