Build a production voice AI agent in 5 minutes. Powered by the fastest TTS on the market - swap the system prompt to build anything from customer support to language tutors.
- 55ms model latency - fastest production TTS
- 130ms time-to-first-audio across 10+ global regions
- $0.01/1000 characters - up to 10x cheaper than alternatives
- 150+ voices across 35+ languages
- 99.38% pronunciation accuracy
flowchart LR
A[ποΈ User speaks] -->|audio| B[Deepgram STT]
B -->|text| C[LLM]
C -->|response text| D[Murf Falcon TTS]
D -->|audio| E[LiveKit]
E -->|stream| F[π User hears]
style A fill:#444441,stroke:#888780,color:#fff
style B fill:#185FA5,stroke:#85B7EB,color:#fff
style C fill:#534AB7,stroke:#AFA9EC,color:#fff
style D fill:#0F6E56,stroke:#5DCAA5,color:#fff
style E fill:#D85A30,stroke:#F0997B,color:#fff
style F fill:#444441,stroke:#888780,color:#fff
- Python 3.10+
- uv - fast Python package manager
# macOS/Linux curl -LsSf https://astral.sh/uv/install.sh | sh # Windows (PowerShell) powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
- Node.js 18+
- pnpm β fast Node package manager
npm install -g pnpm
- A LiveKit project (free tier available)
git clone https://github.com/murf-ai/murf-livekit-starter.git
cd murf-livekit-starterCreate .env.local in both backend/ and frontend/ (copy from .env.example in each). You need:
| Variable | Where to get it | Required |
|---|---|---|
LIVEKIT_URL |
LiveKit Cloud dashboard | Yes |
LIVEKIT_API_KEY |
LiveKit Cloud dashboard | Yes |
LIVEKIT_API_SECRET |
LiveKit Cloud dashboard | Yes |
MURF_API_KEY |
murf.ai/api/dashboard | Yes |
DEEPGRAM_API_KEY |
deepgram.com | Yes |
GOOGLE_API_KEY (or OPENAI_API_KEY) |
Depends on LLM choice | Yes |
cd backend
uv sync
uv run python src/agent.py download-filescd frontend
pnpm installOption A - All-in-one (from repo root):
# macOS/Linux
chmod +x start_app.sh
./start_app.sh
# Windows (PowerShell)
.\start_app.ps1Option B - Separate terminals:
# Terminal 1 β LiveKit Server
livekit-server --dev
# Terminal 2 β Backend agent
cd backend && uv run python src/agent.py dev
# Terminal 3 β Frontend
cd frontend && pnpm devThen open http://localhost:3000 in your browser.
You should now see the voice agent UI. Click Start talking, allow microphone access, and speak β the agent will respond with Murf Falcon TTS. Ensure your backend and (if using Option B) LiveKit server are running.
Want to deploy this beyond localhost? You'll need to deploy two services: the backend agent and the frontend. Both must use the same LiveKit project.
This is a two-service app β the backend agent and the frontend UI deploy separately. You'll need both running and connected to the same LiveKit project.
Set these environment variables in Railway:
MURF_API_KEYDEEPGRAM_API_KEYGOOGLE_API_KEYorOPENAI_API_KEYLIVEKIT_URLLIVEKIT_API_KEYLIVEKIT_API_SECRET
The backend runs as a long-lived Python process that connects to LiveKit as an agent. Railway handles this well.
Set these environment variables in Vercel:
LIVEKIT_URLLIVEKIT_API_KEYLIVEKIT_API_SECRETAGENT_NAME(optional β for explicit agent dispatch)
The frontend is a standard Next.js app. Point it at the same LiveKit instance your backend agent is connected to.
The frontend and backend don't call each other directly β they both connect to LiveKit, which handles the real-time audio transport.
- Use the same
LIVEKIT_URL,LIVEKIT_API_KEY, andLIVEKIT_API_SECRETon both Railway and Vercel - Set
AGENT_NAME=my-agenton Vercel β this matches theagent_name="my-agent"registered inbackend/src/agent.py - Verify: Railway logs should show the agent connected to LiveKit. Open your Vercel URL, click Start talking β the agent should respond
If the agent doesn't connect, double-check that both services point to the same LiveKit project and that the backend is running (check Railway logs).
The default system prompt makes this a customer support agent. You can change the agentβs behavior by editing the prompt.
Where the prompt lives: backend/src/agent.py- the SYSTEM_PROMPT constant (near the top of the file, after the imports). Change that string to change what your voice agent does.
The "Aarogya Sahayak" agent includes a find_health_facilities voice tool: ask "Is there a PHC in Ranchi?" or "Find a government hospital near me" and the agent looks up real facilities and speaks them naturally.
- Data source: the public OpenStreetMap Overpass API β live at query time, no API key required.
- Data origin: community-maintained OpenStreetMap data (including government health facilities imported from data.gov.in). It is not government-verified and may be incomplete or outdated β the agent always says when the data was last refreshed.
- Failure behavior: service unavailable, timeouts, and invalid responses produce a graceful spoken fallback; the agent never invents facilities, names, phones, or addresses.
- Optional tuning:
HEALTH_FACILITIES_TIMEOUT_Sinbackend/.env.local(default 10s per request).
The same "Aarogya Sahayak" agent can place an outbound healthcare follow-up call (appointment or medication reminder). A dialing utility (backend/src/telephony/outbound.py) creates a dedicated room, dials the destination through your LiveKit Cloud outbound SIP trunk (LIVEKIT_SIP_OUTBOUND_TRUNK_ID), dispatches the existing my-agent into the call, monitors it, and cleans the room up.
- One call per run only β no auto-redialing is implemented. The utility reports clear success/failure (no answer, busy, unavailable, rejected, immediate hang-up) and refuses invalid/missing numbers and configuration before dialing anything.
- The agent's outbound opening always states who is calling, why (scheduled follow-up/reminder), and how to end the call (say "end the call"/"stop" or hang up) β see
OUTBOUND_OPENINGinbackend/src/prompt.py. - All credentials and the trunk ID are read from
backend/.env.localand never printed (the CLI's--dry-runprints onlyset/MISSING). - One manual test call: start the agent (
uv run python src/agent.py dev), then in another terminal:cd backend uv run python -m telephony.outbound '+919876543210' # dial your own test number
- Run
uv run python -m telephony.outbound --dry-runfirst to verify configuration without dialing. - Safety/consent: only dial numbers you are authorised to call; the callee must be told who is calling and why, and opt-out ("don't call me again") must be honoured instantly. See
backend/README.mdβ "Outbound Calling (Day 6)" for the full matrix and setup.
Customer Support (default):
You are a friendly and efficient customer support agent for a tech company. Help users with account issues, billing questions, and product troubleshooting. Be concise, empathetic, and solution-oriented. If you don't know something, say so honestly and offer to escalate.
Language Tutor:
You are a patient and encouraging language tutor helping the user practice conversational Spanish. Speak primarily in Spanish but switch to English to explain grammar or vocabulary when needed. Correct mistakes gently and suggest better phrasing. Keep conversations natural and fun.
AI Receptionist:
You are a professional receptionist for a medical clinic. Help callers schedule appointments, answer questions about office hours and services, and take messages for doctors. Be warm but efficient. Ask for the caller's name and reason for calling upfront.
See the Configuration section below for voice, STT, and LLM options.
Edit the tts=murf.TTS(...) call in backend/src/agent.py. Set the voice argument to any Murf voice ID. Examples:
Anishaβ Indian English (female, default in this starter)Poojaβ Indian English (female)Samarβ Indian English (male)Amaraβ US English (female)Gordonβ US English (male)Hazelβ UK English (female)Bertieβ UK English (male)
Browse all voices: Murf Voice Library.
STT is configured in backend/src/agent.py in the AgentSession(stt=...) call. The default is Deepgram (deepgram.STT(model="nova-3")). You can swap to another LiveKit-compatible STT plugin if needed.
- Gemini (default): Set
GOOGLE_API_KEYand usellm=google.LLM(model="gemini-3.5-flash-lite")inagent.py. - OpenAI: Set
OPENAI_API_KEY, add the OpenAI plugin, and use the correspondingllm=openai.LLM(...)inagent.py.
Murf Falcon and LiveKit handle audio format internally. For advanced options, see Murf API docs and LiveKit docs.
murf-livekit-starter/
βββ backend/ # Python voice agent (LiveKit Agents + Murf Falcon)
β βββ src/
β β βββ agent.py # Agent entrypoint, pipeline (STT/LLM/TTS), system prompt
β β βββ prompt.py # Aarogya Sahayak prompt + Day 6 outbound opening
β β βββ memory.py # Day 4: caller memory store
β β βββ health_facilities.py # Day 5: facility lookup
β β βββ telephony/
β β βββ outbound.py # Day 6: outbound dialing utility + CLI
β βββ tests/ # Agent tests (Days 4-6)
β βββ .env.example # Backend env template
β βββ pyproject.toml # Python deps (uv)
β βββ railway.toml # Railway deploy config
βββ frontend/ # Next.js UI for voice sessions
β βββ app/
β β βββ page.tsx # Main page
β β βββ api/token/ # LiveKit token endpoint (dev)
β βββ components/ # UI (agents-ui, app config, theme)
β βββ app-config.ts # Branding, title, button text, accent
β βββ .env.example # Frontend env template
β βββ package.json # Node deps (pnpm)
βββ start_app.sh # Start LiveKit + backend + frontend (macOS/Linux)
βββ start_app.ps1 # Start LiveKit + backend + frontend (Windows)
βββ README.md # This file
For deeper documentation on each part, see:
- Backend Documentation β agent pipeline, voice/LLM/STT configuration, testing, deployment
- Frontend Documentation β UI customization, visualizers, theming, component architecture
- Murf API Docs
- Murf Voice Library
- LiveKit Docs
- Deepgram Docs
- Murf Falcon Benchmarks
- TTS Latency Benchmarker β run your own p50/p95 tests across providers
- Murf Discord
- Murf Startup Incubator β 50M free characters for startups
MIT