Memory

Elevenlabs Twilio Memory Bridge

Inject persistent caller memory and current context into ElevenLabs agents handling Twilio calls.

What it does

Give ElevenLabs voice agents on Twilio caller-specific context through a FastAPI webhook invoked once per inbound call. It loads hashed caller history, long-term facts, and daily notes from local JSON, combines them with a personality template, then returns system-prompt and first-message overrides. Twilio and ElevenLabs continue to handle audio directly.

When to use it

  • Personalized greetings for repeat callers
  • Persistent caller facts across inbound calls
  • Daily or caller-scoped context injection
  • File-backed voice-agent memory without audio proxying

The skill document

elevenlabs-twilio-memory-bridge

Personalization webhook service for ElevenLabs + Twilio voice agents with persistent caller memory.

What It Does

When a call arrives on your Twilio number, ElevenLabs' native integration triggers this webhook. The bridge looks up the caller's history, loads long-term memory facts and daily context notes, combines them with a customizable soul/personality template, and returns everything as a system prompt override so your agent greets each caller with full context.

Architecture

  • No audio proxying — ElevenLabs and Twilio handle media directly
  • Webhook only — called once per inbound call to inject context
  • File-based persistence — JSON files in ./data/, zero external dependencies
  • OpenClaw compatible — works with any OpenAI-compatible LLM endpoint

Endpoints

EndpointMethodPurpose
/webhook/personalizePOSTElevenLabs calls this on inbound call
/webhook/post-callPOSTOptional post-call cleanup
/api/memory/{phone_hash}POSTAdd long-term fact about a caller
/api/notesPOSTAdd global or caller-scoped context note
/healthGETHealth check

Setup

  1. Clone repo, pip install -r requirements.txt
  2. Copy .env.example to .env, fill in secrets
  3. Configure ElevenLabs agent with Custom LLM pointing to your OpenClaw instance
  4. Enable system prompt + first message overrides in agent Security settings
  5. Add webhook URL https://your-domain/webhook/personalize in ElevenLabs settings
  6. Import Twilio number in ElevenLabs dashboard
  7. Run: uvicorn app:app --host 0.0.0.0 --port 8000

Required Environment Variables

  • ELEVENLABS_API_KEY — scoped ElevenLabs key
  • ELEVENLABS_AGENT_ID — your agent ID
  • OPENCLAW_API_BASE_URL — your OpenClaw instance URL
  • PUBLIC_BASE_URL — publicly reachable URL of this service
  • ADMIN_API_KEY — secret for admin endpoint auth
  • PHONE_HASH_SALT — salt for phone number hashing. Generate with openssl rand -base64 32. Changing this invalidates all existing caller data.
  • WEBHOOK_SECRET — shared secret for HMAC webhook verification. Must be set in production.

Optional Environment Variables

VariableDefaultPurpose
DATA_ENCRYPTION_KEY(unset)Fernet key for encrypting memories and notes at rest. Generate with python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())". When unset, data is stored as plain JSON.
SOUL_TEMPLATE_PATH./soul_template.mdPath to personality template file
DATA_DIR./dataDirectory for JSON persistence
ALLOWED_ORIGINS(unset)Comma-separated CORS origins
HOST0.0.0.0Bind address for uvicorn
PORT8000Listen port
LOG_LEVELINFOPython logging level

Security

  • Deterministic phone hashing — Phone numbers are hashed with HMAC-SHA256 using PHONE_HASH_SALT as the key before storage. Changing the salt invalidates existing caller data.
  • Encryption at rest — Memories and notes are encrypted with Fernet when DATA_ENCRYPTION_KEY is set. Data is stored as plain JSON when the key is not configured.
  • Mandatory webhook verificationWEBHOOK_SECRET is required in production. Webhooks are rejected when the secret is not set (fail-closed).
  • Rate limiting — Admin endpoints (/api/memory, /api/notes) are limited to 30 requests per minute. Webhook endpoints are limited to 60 per minute.
  • File locking — JSON reads and writes use POSIX advisory locks (fcntl) to prevent race conditions under concurrent access.
  • Restrictive permissions — Data directory (DATA_DIR) is created with 0o700 permissions. JSON files are written with 0o600.
  • Secrets from env vars only — No hardcoded credentials in source.
  • Safe for public GitHub repos — All sensitive config is loaded from environment variables.

Migration from v1.1.x to v1.2.x

v1.2.0 introduces breaking security changes:

  1. PHONE_HASH_SALT is now required — Previously, phone numbers were hashed with unsalted SHA-256. Now HMAC-SHA256 with a salt is required. Existing caller data will be unreachable after upgrading because the hash keys change. You must accept data loss and start fresh (v1.2.0 uses a different hashing algorithm).

  2. WEBHOOK_SECRET is now required — Previously optional for development. Now mandatory in all environments. Webhooks without a valid secret are rejected.

  3. DATA_ENCRYPTION_KEY is optional but recommended — When set, all new memories and notes are encrypted at rest. Existing unencrypted data remains readable.

Migration checklist

  1. Generate a salt: openssl rand -base64 32
  2. Generate a webhook secret: openssl rand -hex 32
  3. Generate an encryption key (optional): python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
  4. Add all to .env
  5. Review CORS settings — ALLOWED_ORIGINS now defaults to disabled
  6. Update ElevenLabs webhook settings with the new WEBHOOK_SECRET
  7. Note: v1.2.0 requires fresh data — existing caller sessions will be recreated on first call

Questions people ask

Does it proxy Twilio call audio?
No. It is a webhook-only service called once per inbound call; ElevenLabs and Twilio handle media directly.
How are caller memories stored and protected?
Memories and notes use JSON files in `./data` by default, with POSIX file locking and restrictive permissions. Phone numbers are keyed with salted HMAC-SHA256, and setting `DATA_ENCRYPTION_KEY` enables Fernet encryption at rest; otherwise data remains plain JSON.
What must I configure before running it?
Set the required ElevenLabs, OpenClaw, public URL, admin key, phone-hash salt, and webhook-secret environment variables. Enable system-prompt and first-message overrides in ElevenLabs, register `/webhook/personalize`, import the Twilio number, and run the FastAPI app with uvicorn.

Related skills

Turn written replies into concise, normalized text that TTS engines can read naturally.

58 installs2 stars

Generate narration, cloned voices, sound effects, and music from text prompts.

225 installs4 stars

Operate Slack messages, channels, users, and conversations through managed OAuth and API calls.

249 installs7 stars

Send messages to configured AI agents and maintain separate multi-turn sessions from the command line.

121 installs6 stars

Manage Instantly campaigns, leads, sending accounts, inbox email, and analytics through API v2.

68 installs4 stars