Skip to content

ElevenLabs

Connect Suprflo to ElevenLabs Conversational AI over webhooks.

Install

bash
pip install suprflo

No extra, and no ElevenLabs SDK: this module maps webhook payloads — plain dicts in, plain dicts out.

Read this first: it is not a plugin

ElevenLabs hosts the agent. The LLM turn runs on ElevenLabs' infrastructure, not in your process, so there is no in-process hook to inject memories through — unlike LangChain, LiveKit or Pipecat. The SDK's Conversation class exposes only fire-and-forget observers (callback_user_transcript, callback_agent_response) that return None, receive no context object, and fire when the turn is already underway.

So this integration is narrower than the others by necessity. It is honest about that rather than wrapping a hook that cannot work.

What you get

  • persist_transcript(client, payload, user_id=...) — turn a post-call webhook transcript into memories.
  • recall_dynamic_variables(client, query, user_id=...) — build the dynamic_variables for a conversation-initiation webhook response, so recalled memories reach the agent through its prompt at conversation start.
  • build_search_server_tool(api_key, user_id, base_url=...) — build the server-tool registration payload that lets an agent query Suprflo mid-conversation over HTTP.

Recall at conversation start

Respond to the conversation-initiation webhook with memories for the prompt. recall_dynamic_variables returns the whole response body, so return it as-is:

python
from suprflo import MemoryClient
from suprflo.integrations.elevenlabs import recall_dynamic_variables

client = MemoryClient(api_key="YOUR_API_KEY")

def on_conversation_initiation(payload):
    return recall_dynamic_variables(
        client, query="preferences", user_id=payload["user_id"]
    )
    # → {"type": "conversation_initiation_client_data",
    #    "dynamic_variables": {"suprflo_memories": "- likes tea\n- lives in Berlin"}}

Reference in the agent's system prompt to place the recalled text. The variable is always defined — an empty string when nothing matched — because ElevenLabs errors on a prompt variable it cannot resolve.

Search mid-conversation

Register a server tool so the agent can query Suprflo during the call:

python
from suprflo.integrations.elevenlabs import build_search_server_tool

tool = build_search_server_tool(api_key="YOUR_API_KEY", user_id="alice")
# register `tool` on your agent via the ElevenLabs dashboard or API

The payload embeds your API key in the request headers — build it server-side and never ship it to a browser.

Persist after the call

python
from suprflo.integrations.elevenlabs import persist_transcript

def on_post_call(payload):
    persist_transcript(client, payload, user_id=payload["user_id"])

ElevenLabs names the assistant side of a transcript agent; Suprflo (like OpenAI) calls it assistant. The adapter translates this.

Notes and limits

  • Every function is synchronous, matching MemoryClient. That suits a sync webhook handler (Flask/WSGI). From an async handler (FastAPI async def) wrap the call in asyncio.to_thread, or it blocks the event loop.
  • The webhook payload shapes are written from the documented API and are unverified against live ElevenLabs traffic; the tests prove the mapping logic and nothing about ElevenLabs itself.
  • For a genuine in-process pre-LLM hook, ElevenLabs' Speech Engine inverts the architecture (they do ASR/TTS/turn-taking, you own the LLM call), and their Custom LLM is the out-of-process equivalent. Neither is wrapped here: a wrapper guessed at would be worse than none.

The memory layer for AI agents.