Install
openclaw skills install phone-voiceClawHub Security found sensitive or high-impact capabilities. Review the scan results before using.
Connect ElevenLabs Agents to your OpenClaw via phone with Twilio. Includes caller ID auth, voice PIN security, call screening, memory injection, and cost tracking.
openclaw skills install phone-voiceTurn 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/cloudflared
# Login 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.