Phone Voice Integration
Connect ElevenLabs Agents to your OpenClaw via phone with Twilio. Includes caller ID auth, voice PIN security, call screening, memory injection, and cost tracking.
Connect ElevenLabs Agents to your OpenClaw via phone with Twilio. Includes caller ID auth, voice PIN security, call screening, memory injection, and cost tracking.
Real data. Real impact.
Emerging
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
Turn your OpenClaw into a phone-callable assistant with ElevenLabs Agents + Twilio.
What you get:
Phone → Twilio → ElevenLabs Agent → Your Bridge → Anthropic Claude → OpenClaw Tools ↓ Memory Context (MEMORY.md, USER.md)
Flow:
Not needed for this skill — the bridge bypasses OpenClaw and calls Claude directly. This gives you more control over memory injection and cost tracking.
The bridge is a FastAPI server that:
/v1/chat/completions requests from ElevenLabsKey files:
server.py — FastAPI app with /v1/chat/completions endpointfred_prompt.py — System prompt builder (loads memory files).env — Secrets (API keys, tokens, whitelist)contacts.json — Caller whitelist for screeningPermanent, secure alternative to ngrok:
# Install cloudflared brew install cloudflare/cloudflare/cloudflaredLogin and configure
cloudflared tunnel login cloudflared tunnel create <tunnel-name>
Run the tunnel
cloudflared tunnel --url http://localhost:8013 run <tunnel-name>
Add a CNAME in Cloudflare DNS:
voice.yourdomain.com → <tunnel-id>.cfargotunnel.com
Or use ngrok (temporary):
ngrok http 8013
https://voice.yourdomain.com/v1/chat/completionsAuthorization: Bearer <YOUR_BRIDGE_TOKEN># Step 1: Store your bridge auth token as a secret curl -X POST https://api.elevenlabs.io/v1/convai/secrets \ -H "xi-api-key: YOUR_ELEVENLABS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "new", "name": "bridge_auth_token", "value": "YOUR_BRIDGE_AUTH_TOKEN" }'Response: {"secret_id": "abc123..."}
Step 2: Create the agent
curl -X POST https://api.elevenlabs.io/v1/convai/agents/create
-H "xi-api-key: YOUR_ELEVENLABS_API_KEY"
-H "Content-Type: application/json"
-d '{ "conversation_config": { "agent": { "language": "en", "prompt": { "llm": "custom-llm", "prompt": "You are a helpful voice assistant.", "custom_llm": { "url": "https://voice.yourdomain.com/v1/chat/completions", "api_key": {"secret_id": "abc123..."} } } } } }'
In ElevenLabs agent settings:
Done! Your bot now answers that phone number.
Recognizes whitelisted numbers automatically:
// contacts.json { "+12505551234": { "name": "Alice", "role": "family" } }
For unknown callers or high-security actions:
VOICE_PIN = "banana" # Set in .env
Caller must say the PIN to proceed.
Unknown numbers get a receptionist prompt:
"This is Fred's assistant. I can take a message or help with general questions."
Configurable per-hour limits:
RATE_LIMIT_PER_HOUR = 10
Prevents abuse and runaway costs.
The bridge auto-loads context before each call:
Files read:
MEMORY.md — Long-term facts about user, projects, preferencesUSER.md — User profile (name, location, timezone)Live data injection:
All injected into the system prompt before Claude sees the conversation.
Every call logs to
memory/voice-calls/costs.jsonl:
{ "call_sid": "CA123...", "timestamp": "2026-02-03T10:30:00", "caller": "+12505551234", "duration_sec": 45, "total_cost_usd": 0.12, "breakdown": { "twilio": 0.02, "elevenlabs": 0.08, "anthropic": 0.02 } }
Run analytics on the JSONL to track monthly spend.
Call your bot:
Outbound calling (optional):
curl -X POST https://voice.yourdomain.com/call/outbound \ -H "Authorization: Bearer <BRIDGE_TOKEN>" \ -d '{"to": "+12505551234", "message": "Reminder: dentist at 3pm"}'
Environment variables (.env):
ANTHROPIC_API_KEY=sk-ant-... ELEVENLABS_API_KEY=sk_... ELEVENLABS_AGENT_ID=agent_... TWILIO_ACCOUNT_SID=AC... TWILIO_AUTH_TOKEN=... TWILIO_NUMBER=+1... LLM_BRIDGE_TOKEN=<random-secure-token> VOICE_PIN=<your-secret-word> CLAWD_DIR=/path/to/clawd
Whitelist (contacts.json):
{ "+12505551234": {"name": "Alice", "role": "family"}, "+12505555678": {"name": "Bob", "role": "friend"} }
Restrict calls to business hours:
# In server.py OFFICE_HOURS = { "enabled": True, "timezone": "America/Vancouver", "weekdays": {"start": "09:00", "end": "17:00"}, "weekends": False }
Outside hours → voicemail prompt.
Test the bridge directly:
curl -X POST https://voice.yourdomain.com/v1/chat/completions \ -H "Authorization: Bearer <BRIDGE_TOKEN>" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4", "messages": [{"role": "user", "content": "Hello!"}], "stream": false }'
Check logs:
tail -f ~/clawd/memory/voice-calls/bridge.log
Verify Twilio webhook:
Per-minute breakdown:
Use rate limiting and call screening to control costs.
ElevenLabs official tutorial:
This skill (Phone Voice v2.0):
MIT — use freely, credit appreciated.
Built by Fred (@FredMolty) — running on OpenClaw since 2026.
No automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.