This is a Vercel-hosted voice agent API that provides Miami theater showtimes to ElevenLabs voice agents, with automated data ingestion from Agile WebSales and a Twilio-powered voicemail system for customer messages. The application uses Redis for caching showtime data and storing voicemails, with a staff dashboard for managing customer recordings.
- Serverless Architecture: Built on Vercel Functions for automatic scaling
- Automated Data Ingestion: Fetches theater data every 30 minutes via scheduled cron job
- Voice-Optimized API: Responses formatted for natural text-to-speech integration
- Multiple Query Types: Support for date, movie title, and time-based searches
- Voicemail System: AI-powered voicemail with Twilio recording and transcription
- Email Notifications: Automatic staff notifications via Resend with recording links and transcriptions
- Staff Dashboard: Beautiful web interface for managing voicemails
- High-Performance Caching: Upstash Redis for sub-second response times
- Cross-Origin Ready: CORS enabled for voice agent platform integration
- Production Ready: Environment-based configuration with secure authentication
Query theater showtimes with various filters.
Query Parameters:
date- Specific date (YYYY-MM-DD format)movie_title- Movie name search (partial matching)day_type- 'weekend', 'today', 'tomorrow'time_preference- 'evening', 'afternoon', 'night'
Example Requests:
# Get today's showtimes
curl "https://your-domain.vercel.app/api/showtimes?day_type=today"
# Search for a specific movie
curl "https://your-domain.vercel.app/api/showtimes?movie_title=spider"
# Get weekend evening shows
curl "https://your-domain.vercel.app/api/showtimes?day_type=weekend&time_preference=evening"Response Format:
{
"success": true,
"data": [
{
"movie_title": "Spider-Man",
"date": "2024-01-15",
"time": "7:30 PM",
"theater": "O Cinema South Beach",
"rating": "PG-13",
"runtime": 148,
"summary": "Spider-Man is showing on Monday, January 15 at 7:30 PM in O Cinema South Beach"
}
],
"last_updated": "2024-01-15T10:00:00.000Z",
"query_info": {
"results_count": 1
}
}Automated endpoint for data ingestion (secured with bearer token).
Twilio webhook endpoint that returns TwiML for voicemail recording. Called by ElevenLabs Leave-Voicemail tool.
Features:
- Records up to 3 minutes of audio
- Automatic transcription via Twilio
- Caller can press
*to finish recording - Returns TwiML response for Twilio
Handles completed voicemail recordings from Twilio.
Actions:
- Stores voicemail metadata in Redis
- Sends email notification to staff
- Returns TwiML confirmation message
Processes transcription results from Twilio.
Actions:
- Updates voicemail record with transcription text
- Sends follow-up email with transcription
Password-protected web dashboard for staff to view and manage voicemails.
Features:
- Beautiful gradient UI with voicemail cards
- Auto-refresh every 30 seconds
- Session-based authentication
- Listen to recordings, view transcriptions, download MP3s
- Delete voicemails with confirmation dialog
- Responsive design for mobile/desktop
Access:
# Open in browser and enter password when prompted
open https://your-domain.vercel.app/api/voicemail/dashboardAPI/HTML endpoint for voicemail data (requires bearer token authentication).
Authentication:
Authorization: Bearer YOUR_STAFF_DASHBOARD_SECRET
Query Parameters:
limit- Number of voicemails to return (default: 50)offset- Pagination offset (default: 0)unlistened_only- Filter to unlistened messages (true/false)
Response Format:
Accept: text/html- Returns styled HTML dashboardAccept: application/json- Returns JSON array of voicemail objects
Example:
# Get JSON data (requires authentication)
curl -H "Authorization: Bearer YOUR_SECRET" \
"https://your-domain.vercel.app/api/voicemail/list"
# Get HTML dashboard (requires authentication)
curl -H "Authorization: Bearer YOUR_SECRET" \
-H "Accept: text/html" \
"https://your-domain.vercel.app/api/voicemail/list"
# Filter unlistened only
curl -H "Authorization: Bearer YOUR_SECRET" \
"https://your-domain.vercel.app/api/voicemail/list?unlistened_only=true"Delete a voicemail from the system (requires bearer token authentication).
Authentication:
Authorization: Bearer YOUR_STAFF_DASHBOARD_SECRET
Query Parameters:
id- Voicemail ID (RecordingSid) to delete (required)
Actions:
- Removes voicemail from Redis sorted set index
- Deletes individual voicemail record
- Returns success confirmation
Response Format:
{
"success": true,
"message": "Voicemail deleted successfully",
"id": "RE1234567890abcdef"
}Example:
# Delete a specific voicemail
curl -X DELETE \
-H "Authorization: Bearer YOUR_SECRET" \
"https://your-domain.vercel.app/api/voicemail/delete?id=RE1234567890"Error Responses:
400- Missing voicemail ID401- Invalid or missing authentication token404- Voicemail not found500- Server error during deletion
This API is optimized for ElevenLabs Conversational AI, enabling natural voice queries about Miami theater showtimes.
-
Install Dependencies
# Python pip install elevenlabs>=1.0.0 # Or Node.js npm install elevenlabs dotenv
-
Configure Environment
# Add to your .env file ELEVENLABS_API_KEY=sk-your-elevenlabs-api-key VERCEL_APP_URL=https://your-app.vercel.app -
Run Setup Script
cd elevenlabs python setup_agent.py # or: node setup_agent.js
Showtime Queries: Users can ask natural questions like:
- "What movies are playing tonight?" → Today's evening showtimes
- "When is The Substance showing?" → All showtimes for that movie
- "Any afternoon shows tomorrow?" → Tomorrow's 12-5 PM showtimes
- "What's playing this weekend?" → Friday-Sunday showtimes
Voicemail System: Callers can also:
- "I'd like to speak to someone" → Agent transfers to voicemail
- "Can I leave a message?" → Agent initiates voicemail recording
- "I have a question about tickets" → Agent offers to take a message
The API returns voice-optimized responses with conversational summaries for natural text-to-speech.
- Tool creation failed: Verify
ELEVENLABS_API_KEYis correct - Agent can't reach API: Ensure
VERCEL_APP_URLpoints to deployed app - Test directly:
curl "your-app.vercel.app/api/showtimes?day_type=today"
- Node.js 18+ (with npm)
- Vercel account for deployment
- Upstash Redis serverless database instance
- Agile WebSales API access credentials
Create a .env.local file for local development:
# Agile WebSales API
AGILE_GUID=your-agile-guid-here
# Redis Configuration (choose ONE option)
# Option 1: Direct Upstash Redis
UPSTASH_REDIS_REST_URL=https://your-region.upstash.io
UPSTASH_REDIS_REST_TOKEN=your-redis-rest-token
# Option 2: Vercel KV (powered by Upstash)
# KV_REST_API_URL=https://your-region.kv.vercel-storage.com
# KV_REST_API_TOKEN=your-vercel-kv-token
# Cron Job Security
CRON_SECRET=your-secure-random-string
# Voicemail System (optional - required for voicemail functionality)
TWILIO_ACCOUNT_SID=your-twilio-account-sid
TWILIO_AUTH_TOKEN=your-twilio-auth-token
RESEND_API_KEY=your-resend-api-key
OCINEMA_EMAIL=info@o-cinema.org # Primary email (fallback: STAFF_EMAIL)
FROM_EMAIL=O Cinema Voicemail <noreply@ocinema.org>
# Staff Dashboard Authentication (required for voicemail dashboard access)
STAFF_DASHBOARD_SECRET=your-secure-random-string-at-least-32-chars
# Base URL for TwiML callbacks (required for production)
BASE_URL=https://miami-theater-voice-agent.vercel.appRedis Setup Options (choose one):
- Direct Upstash: Set
UPSTASH_REDIS_REST_URLandUPSTASH_REDIS_REST_TOKEN - Vercel KV: Set
KV_REST_API_URLandKV_REST_API_TOKEN(automatically provisioned in Vercel dashboard) - The application automatically detects which credentials are available
# Clone the repository
git clone <repository-url>
cd miami-theater-voice-agent
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env.local
# Edit .env.local with your credentials
# Start Vercel development server
vercel dev
# Test the API endpoints
curl "http://localhost:3000/api/showtimes?day_type=today"
curl "http://localhost:3000/api/showtimes?movie_title=spider"# Deploy to Vercel (first time)
vercel
# Set required environment variables
vercel env add AGILE_GUID
vercel env add CRON_SECRET
# Add Redis credentials (choose one option)
# For direct Upstash:
vercel env add UPSTASH_REDIS_REST_URL
vercel env add UPSTASH_REDIS_REST_TOKEN
# For Vercel KV (alternative - provision via Vercel dashboard instead)
# Add voicemail system credentials (if using voicemail feature)
# IMPORTANT: Use printf (not echo) to avoid newline characters
printf "your-account-sid" | vercel env add TWILIO_ACCOUNT_SID
printf "your-auth-token" | vercel env add TWILIO_AUTH_TOKEN
printf "your-resend-key" | vercel env add RESEND_API_KEY
printf "info@o-cinema.org" | vercel env add OCINEMA_EMAIL
printf "O Cinema <noreply@ocinema.org>" | vercel env add FROM_EMAIL
printf "your-secure-token" | vercel env add STAFF_DASHBOARD_SECRET # REQUIRED for security
printf "https://your-app.vercel.app" | vercel env add BASE_URL # REQUIRED for callbacks
# Deploy updates
vercel --prodAutomatic Features on Vercel:
- Serverless functions auto-deploy from
/apidirectory - Cron jobs automatically scheduled via
vercel.json - Environment variables securely managed in dashboard
- Auto-scaling based on traffic demand
1. Configure Twilio:
- Sign up for Twilio account
- Copy Account SID and Auth Token to environment variables
- Note: You don't need a Twilio phone number for this setup (ElevenLabs handles the call)
2. Configure Email (Resend):
- Sign up for Resend account (100 emails/day free)
- Create an API key from the dashboard
- Verify your sender email address or domain
- Add credentials to environment variables
- Note: Use format
Name <email@domain.com>for FROM_EMAIL
3. Configure ElevenLabs Agent:
- Upload
elevenlabs/voicemail-tool-config.jsonas a new webhook tool - Update the URL to point to your deployed Vercel app
- Add the tool to your conversational AI agent
- The agent will now offer voicemail when appropriate
4. Configure Security (Required):
Before deploying to production, you must configure authentication to secure the voicemail system:
Generate Staff Dashboard Secret:
# Generate a secure random string (32+ characters)
openssl rand -base64 32Add to Vercel Environment Variables:
# Via Vercel CLI
vercel env add STAFF_DASHBOARD_SECRET
# Or add via Vercel Dashboard:
# Settings → Environment Variables → Add New
# Name: STAFF_DASHBOARD_SECRET
# Value: [paste generated token]Important Security Notes:
STAFF_DASHBOARD_SECRETis required for dashboard accessTWILIO_AUTH_TOKENvalidates webhook authenticity (prevents forged requests)- All Twilio webhooks are protected with signature validation
- Staff dashboard requires bearer token authentication
Test Security Implementation:
# Dashboard should reject requests without auth token (returns 401)
curl https://your-app.vercel.app/api/voicemail/list
# Access with valid token (returns voicemail list)
curl -H "Authorization: Bearer YOUR_STAFF_DASHBOARD_SECRET" \
https://your-app.vercel.app/api/voicemail/list5. Access Staff Dashboard:
Web Dashboard (Recommended for Staff):
- Navigate to
https://your-app.vercel.app/api/voicemail/dashboard - Enter your
STAFF_DASHBOARD_SECRETpassword when prompted - Beautiful UI with auto-refresh, listen to recordings, view transcriptions
- Session persists until logout
API Access (For Developers):
# JSON API with bearer token
curl -H "Authorization: Bearer YOUR_STAFF_DASHBOARD_SECRET" \
https://your-app.vercel.app/api/voicemail/listTroubleshooting:
If you encounter issues, see TROUBLESHOOTING.md for detailed debugging steps including:
- Twilio debugger usage
- Environment variable validation
- Common error codes and solutions
- Testing workflows
Built on Vercel's serverless platform with automatic scaling:
- API Routes: Deploy as individual Vercel Functions in
/apidirectory - Scheduled Tasks: Cron jobs defined in
vercel.jsonconfiguration - Edge Network: Global CDN distribution for low latency
- Auto-scaling: Functions scale up/down based on demand
Showtimes System:
- Scheduled Ingestion: Vercel Cron triggers
/api/cron/ingest-showtimesevery 30 minutes - Data Fetching: Serverless function pulls fresh data from Agile WebSales API
- Data Processing: Raw theater data transformed into voice-optimized structures
- Redis Caching: Processed data stored in Upstash Redis with 2-hour TTL
- API Serving:
/api/showtimesfunction serves cached data to voice agents
Voicemail System:
- Call Initiation: Caller asks ElevenLabs agent to leave a message
- Tool Invocation: Agent calls Leave-Voicemail webhook tool
- TwiML Generation:
/api/twilio/voicemailreturns recording instructions - Recording: Twilio records caller's message (up to 3 minutes)
- Transcription: Twilio generates automatic transcription
- Storage: Voicemail stored in Redis with timestamp indexing
- Notification: Staff receives email via Resend with recording link
- Dashboard Access: Staff can review voicemails at
/api/voicemail/list
Upstash Redis Integration:
import { Redis } from '@upstash/redis';
const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL || process.env.KV_REST_API_URL,
token: process.env.UPSTASH_REDIS_REST_TOKEN || process.env.KV_REST_API_TOKEN,
});Optimized data structures for fast queries:
Showtimes:
showtimes:current- Complete processed dataset with 2-hour TTLmovies- Array of all available movies with showtimesby_date- Hash map for date-based lookupsweekend- Pre-filtered Friday/Saturday/Sunday showtimesupcoming- Next 7 days of showtimesshowtimes:last_updated- Timestamp for cache freshness tracking
Voicemails:
voicemails:index- Sorted set of voicemail IDs by timestampvoicemail:{RecordingSid}- Individual voicemail records with:- Recording URL and duration
- Caller phone number
- Transcription text
- Timestamps and status
Optimized for ElevenLabs and voice AI platforms:
// Example Vercel Function for voice optimization
export default async function handler(req, res) {
// CORS headers for voice agent integration
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (req.method === 'OPTIONS') {
return res.status(200).end();
}
// Voice-optimized response format
return res.json({
summary: "Spider-Man is showing on Monday, January 15th at 7:30 PM",
// ... additional structured data
});
}Voice-Specific Features:
- Human-readable response summaries for natural TTS
- Date/time formatting optimized for voice pronunciation
- Structured data with conversational context
- Cross-origin request support for web-based voice agents
Currently configured for Miami theater locations:
- Primary: O Cinema South Beach (1130 Washington Ave, Miami Beach, FL)
- Data Source: Agile WebSales ticketing system
- Coverage: Real-time showtimes and movie information
- Update Frequency: Every 30 minutes via automated ingestion
Production Security Features:
- Cron Protection: Bearer token authentication for
/api/cron/*endpoints - Environment Isolation: Sensitive credentials stored in Vercel environment variables
- CORS Configuration: Cross-origin controls for voice agent integration
- Input Validation: Query parameter sanitization and validation
- Serverless Isolation: Each function runs in isolated containers
- HTTPS Only: All API endpoints served over encrypted connections
Built-in Monitoring:
- Vercel Analytics: Function execution metrics and performance
- Console Logging: Structured logging for cron job execution
- Error Tracking: HTTP status codes and error handling
- Cache Monitoring: Redis TTL and last updated timestamps
- Uptime Tracking: Automatic function health monitoring
Development Debugging:
# View function logs
vercel logs
# Monitor cron job execution
vercel logs --filter="/api/cron"- Fork the repository
- Create a feature branch
- Make your changes
- Test locally with
vercel dev - Test ElevenLabs integration if applicable
- Submit a pull request
ISC