Python SDK
Install, initialize, and use the ConvoMem Python SDK.
The ConvoMem Python SDK supports Python 3.9+ with both sync and async clients.
Install
pip install convomem
# or with uv
uv add convomemInitialize
import os
from convomem import ConvoMem
client = ConvoMem(api_key=os.environ["CONVOMEM_API_KEY"])Optional configuration:
client = ConvoMem(
api_key=os.environ["CONVOMEM_API_KEY"],
timeout=10.0, # seconds (default 10)
max_retries=3, # retries on 429 / 5xx
)Never expose an API key in client-side code. All ConvoMem calls should originate from your backend. For browser widgets, use embed tokens.
Identity
Every method accepts a CustomerIdentity that tells ConvoMem which customer to
read or write. If customer_id is set, the SDK routes to the direct
/customers/:id/… endpoint. Otherwise the server resolves the customer from
email, phone, or external_id.
from convomem import CustomerIdentity
# By known ID — most direct
identity = CustomerIdentity(customer_id="cust_uuid_123")
# By email — server resolves the customer
identity = CustomerIdentity(email="[email protected]")
# By phone (E.164 format recommended)
identity = CustomerIdentity(phone="+14155550100")
# By external system ID
identity = CustomerIdentity(external_id="crm-456")Capture
Send conversation turns for background memory extraction. Fire-and-forget — memories become searchable within seconds.
client.capture(
messages=[
{"role": "user", "content": "I need help with my order"},
{"role": "assistant", "content": "Of course, let me look that up."},
],
CustomerIdentity(email="[email protected]"),
channel="CHAT",
)Look up context
Recall semantically relevant memories before generating a reply.
ctx = client.lookup(
"order and shipping preferences",
CustomerIdentity(email="[email protected]"),
)
print(ctx.context) # prompt-ready context string
for mem in ctx.memories:
print(f" - {mem.content}")Agent loop pattern
from convomem import ConvoMem, CustomerIdentity
client = ConvoMem(api_key="sk-org-…")
def handle_message(user_msg: str, email: str, conv_id: str | None = None):
identity = CustomerIdentity(email=email)
# 1. Recall context
ctx = client.lookup("customer support", identity)
# 2. Build prompt + call your LLM
reply = call_llm(ctx.context, user_msg)
# 3. Capture the turns
result = client.capture(
messages=[
{"role": "user", "content": user_msg},
{"role": "assistant", "content": reply},
],
identity,
channel="CHAT",
)
return reply, result.conversation_idMemories
from convomem import CustomerIdentity
identity = CustomerIdentity(customer_id="cust_uuid_123")
# List all memories
result = client.list_memories(identity, page=1, limit=20)
for mem in result.memories:
print(f"- {mem.content}")
# Add manually
memory = client.add_memory(
"Prefers email contact",
identity,
category="preference",
)
# Update (requires customer_id)
client.update_memory(
"mem_uuid_456",
identity,
content="Prefers email and text contact",
)
# Delete (requires customer_id)
client.delete_memory("mem_uuid_456", identity)Customers
from convomem import CustomerIdentity
# Create
customer = client.create_customer(
name="Alice",
email="[email protected]",
)
# Get by any identity
customer = client.get_customer(CustomerIdentity(email="[email protected]"))
print(f"Customer ID: {customer.id}")
# Update — by ID (direct) or by identity (server resolves)
updated = client.update_customer(
CustomerIdentity(customer_id="cust_uuid_123"),
name="Alice Smith",
)
# List
result = client.list_customers(page=1, limit=20)
print(f"{len(result.customers)} of {result.total}")
# Stats
stats = client.get_stats()
print(f"Total customers: {stats.total_customers}")
print(f"Total memories: {stats.total_memories}")
# Delete
client.delete_customer(CustomerIdentity(customer_id="cust_uuid_123"))Conversations
from convomem import CustomerIdentity
identity = CustomerIdentity(customer_id="cust_uuid_123")
# Start
conversation = client.start_conversation(identity, "CHAT")
print(f"Conversation: {conversation.id}")
# List
result = client.list_conversations(identity, page=1, limit=20)
# End — path-based when both IDs are known
client.end_conversation(
"conv_uuid_456",
identity,
outcome="Resolved billing issue",
)
# End — flat route when only identity is known
client.end_conversation(
None,
CustomerIdentity(email="[email protected]"),
outcome="Resolved",
)
# Escalate
client.escalate_conversation(
"conv_uuid_456",
identity,
reason="Complex billing dispute",
)Handoff
Generate a briefing for the human agent taking over the conversation.
handoff = client.get_handoff(CustomerIdentity(email="[email protected]"))
print(f"Narrative: {handoff.narrative}")
for mem in handoff.key_memories:
print(f" - {mem.content}")Embed tokens
result = client.create_embed_token(
CustomerIdentity(customer_id="cust_uuid_123"),
ttl_seconds=3600,
)
print(f"Token: {result.token}")
print(f"Expires in: {result.expires_in}s")Error handling
from convomem import ConvoMemApiError
try:
customer = client.get_customer(CustomerIdentity(customer_id="cust_uuid_123"))
except ConvoMemApiError as e:
print(f"Status: {e.status}")
print(f"Body: {e.body}")Async client
import asyncio
import os
from convomem import AsyncConvoMem, CustomerIdentity
async def main():
async with AsyncConvoMem(api_key=os.environ["CONVOMEM_API_KEY"]) as client:
ctx = await client.lookup(
"billing question",
CustomerIdentity(email="[email protected]"),
)
print(ctx.context)
await client.capture(
messages=[{"role": "user", "content": "What's my invoice?"}],
identity=CustomerIdentity(email="[email protected]"),
channel="CHAT",
)
asyncio.run(main())Low-level resource client
For advanced use cases (webhook integrations, raw resource access) you can use
ConvoMemClient directly:
from convomem import ConvoMemClient, CaptureRequest, Message
client = ConvoMemClient(api_key="sk-org-…")
result = client.capture(CaptureRequest(
messages=[Message(role="user", content="Hello")],
email="[email protected]",
))