Claude-skill-registry Letta Conversations API
Guide for using the Letta Conversations API to manage isolated message threads on agents. Use when building multi-user chat applications, session management, or any scenario requiring separate conversation contexts on a single agent.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/conversations" ~/.claude/skills/majiayu000-claude-skill-registry-letta-conversations-api && rm -rf "$T"
manifest:
skills/data/conversations/SKILL.mdsource content
Letta Conversations API
The Conversations API allows multiple isolated message threads on a single agent. Each conversation maintains its own message history while sharing the agent's memory blocks and tools.
When to Use This Skill
- Building multi-user chat applications (each user gets their own conversation)
- Implementing session management with separate contexts
- A/B testing agent responses across isolated conversations
- Any scenario where you need multiple independent chat threads with one agent
Key Concepts
| Concept | Description |
|---|---|
| Conversation | An isolated message thread on an agent ( ID) |
| Isolation | Each conversation has separate message history |
| Shared State | Memory blocks and tools are shared across conversations |
| In-Context Messages | Messages currently in the conversation's context window |
Python SDK Usage
Setup
from letta_client import Letta client = Letta(base_url="https://api.letta.com", api_key="your-key")
Create a Conversation
conversation = client.conversations.create(agent_id="agent-xxx") # conversation.id -> "conv-xxx"
Send Messages (Streaming)
stream = client.conversations.messages.create( conversation_id=conversation.id, messages=[{"role": "user", "content": "Hello!"}], ) for msg in stream: if hasattr(msg, "message_type") and msg.message_type == "assistant_message": print(msg.content)
List Messages in a Conversation
messages = client.conversations.messages.list( conversation_id=conversation.id, limit=50, # Optional: default 100 after="message-xxx", # Optional: cursor for pagination before="message-yyy", # Optional: cursor for pagination )
List All Conversations for an Agent
conversations = client.conversations.list( agent_id="agent-xxx", limit=50, # Optional after="conv-xxx", # Optional: cursor for pagination )
Retrieve a Specific Conversation
conv = client.conversations.retrieve(conversation_id="conv-xxx") # conv.in_context_message_ids -> list of message IDs in context window
REST API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| | Create a conversation |
| | List conversations |
| | Get a conversation |
| | List messages |
| | Send message (streams response) |
| | Resume a background stream |
REST Example: Create and Send Message
# Create conversation curl -X POST "https://api.letta.com/v1/conversations?agent_id=agent-xxx" \ -H "Authorization: Bearer $LETTA_API_KEY" \ -H "Content-Type: application/json" # Send message (streaming response) curl -X POST "https://api.letta.com/v1/conversations/conv-xxx/messages" \ -H "Authorization: Bearer $LETTA_API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: text/event-stream" \ -d '{"messages": [{"role": "user", "content": "Hello!"}]}'
Conversation Schema
class Conversation: id: str # "conv-xxx" agent_id: str # Associated agent ID created_at: datetime # Creation timestamp summary: Optional[str] # Optional conversation summary in_context_message_ids: List[str] # Message IDs in context window
Common Patterns
Multi-User Chat Application
# Each user gets their own conversation user_conversations = {} def get_or_create_conversation(user_id: str, agent_id: str) -> str: if user_id not in user_conversations: conv = client.conversations.create(agent_id=agent_id) user_conversations[user_id] = conv.id return user_conversations[user_id] def send_user_message(user_id: str, agent_id: str, message: str): conv_id = get_or_create_conversation(user_id, agent_id) return client.conversations.messages.create( conversation_id=conv_id, messages=[{"role": "user", "content": message}], )
Paginating Through Message History
def get_all_messages(conversation_id: str): all_messages = [] after = None while True: batch = client.conversations.messages.list( conversation_id=conversation_id, limit=100, after=after, ) if not batch: break all_messages.extend(batch) after = batch[-1].id return all_messages
Important Notes
- Streaming by default: The
endpoint always streams responsesmessages.create - Shared memory: Memory block updates in one conversation are visible in all conversations for that agent
- Message isolation: Conversation message history is completely isolated between conversations
- Pagination: Use
/after
cursors for efficient pagination, not offsetsbefore
Example Scripts
This skill includes two example scripts in the
scripts/ directory:
-
- Comprehensive demo showing all API featuresconversations_demo.py- Basic conversation flow
- Conversation isolation testing
- Listing and retrieving conversations
- Pagination examples
- Shared memory demonstration
-
- Interactive TUI for managing conversationsconversations_cli.py- Create/switch between conversations
- Send messages with streaming responses
- View message history
- Switch between agents
Running the Examples
# Run the demo script LETTA_API_KEY=your-key uv run letta/conversations/scripts/conversations_demo.py # Run the interactive CLI LETTA_API_KEY=your-key uv run letta/conversations/scripts/conversations_cli.py # CLI with specific agent LETTA_API_KEY=your-key uv run letta/conversations/scripts/conversations_cli.py --agent agent-xxx
SDK Gotchas
- Paginated responses use
to access the list:.itemsclient.agents.list().items - Auth parameter is
, notapi_key
:tokenLetta(base_url=..., api_key=...) - Message streams must be consumed (iterate or
) to complete the requestlist()