Python SDK

    The official Memorystack SDK for Python. Build memory-enabled applications with full type hints and modern async support.

    ✓ Full Type Hints✓ Python 3.8+✓ Async/Await Support✓ Dataclasses

    Installation

    Install the SDK using your preferred package manager. Type hints are included automatically.

    pip install memorystack

    Memory Operations

    Create, update, delete, and retrieve memories with full CRUD support

    Hybrid Search

    Vector + text search for best accuracy and relevance

    Agent Support

    Auto-detection and scoping for multi-agent systems

    Batch Operations

    Bulk operations with 50% cost savings via batch API

    Auto-Maintenance

    Automated consolidation, reflection, and optimization

    Memory Lineage

    Complete provenance tracking and history

    Contradiction Detection

    Automatic conflict resolution and belief updating

    Export/Import

    Backup and migration support (JSON/CSV)

    Quick Start

    Get started in 30 seconds. The SDK has just 2 main methods: add() and search().

    from memorystack import MemoryStackClient
    import os
    
    client = MemoryStackClient(
        api_key=os.environ["MEMORYSTACK_API_KEY"]
    )
    
    # Store a memory
    client.add("User prefers dark mode")
    
    # Store a conversation
    client.add([
        {"role": "user", "content": "I love Python"},
        {"role": "assistant", "content": "Great choice!"}
    ])
    
    # Search memories
    results = client.search("user preferences")
    print(results["results"])

    Code Examples

    Basic Usage

    Store and search memories in 30 seconds

    from memorystack import MemoryStackClient
    import os
    
    client = MemoryStackClient(
        api_key=os.environ["MEMORYSTACK_API_KEY"]
    )
    
    # Store a memory
    client.add("User prefers dark mode")
    
    # Store a conversation
    client.add([
        {"role": "user", "content": "I love Python"},
        {"role": "assistant", "content": "Great choice!"}
    ])
    
    # Search memories
    results = client.search("user preferences")
    for m in results["results"]:
        print(f"- {m['content']}")

    Configuration

    Constructor Parameters

    ParameterTypeRequiredDescription
    api_keystrRequiredYour Memorystack API key
    base_urlstrOptionalCustom API base URL (for self-hosted)

    Example with Custom Base URL

    client = MemoryStackClient(
        api_key=os.environ["MEMORYSTACK_API_KEY"],
        base_url="https://your-domain.com/api/v1"
    )

    API Reference

    Core Methods

    add()

    Store memories. Accepts a simple string or a list of conversation messages.

    Signature

    add(content: Union[str, List[Dict]], user_id: Optional[str] = None, metadata: Optional[Dict] = None) → Dict

    Parameters

    FieldTypeRequiredDescription
    contentstr | List[Dict]YesText or conversation messages
    user_idOptional[str]NoEnd-user ID for B2B apps
    metadataOptional[Dict]NoCustom metadata to attach

    Examples

    # Simple text
    client.add("User prefers dark mode")
    
    # With user ID (for B2B apps)
    client.add("User likes Python", user_id="user_123")
    
    # Conversation format
    client.add([
        {"role": "user", "content": "What is my favorite color?"},
        {"role": "assistant", "content": "Based on our conversations, you prefer blue!"}
    ])
    
    # With metadata
    client.add(
        "Important deadline is Friday",
        user_id="user_123",
        metadata={"category": "work", "priority": "high"}
    )

    search()

    Find relevant memories using semantic search. Results are ranked by relevance.

    Signature

    search(query: str, user_id: Optional[str] = None, limit: int = 10) → Dict

    Parameters

    FieldTypeRequiredDescription
    querystrYesNatural language search query
    user_idOptional[str]NoFilter by user ID
    limitintNoMax results (default: 10)

    Examples

    # Simple search
    results = client.search("user preferences")
    
    # With user ID filter
    user_results = client.search("favorite color", user_id="user_123")
    
    # Limit results
    top_results = client.search("meetings", limit=5)
    
    # Process results
    for m in results["results"]:
        print(f"- {m['content']}")

    get_stats()

    Get usage statistics for your account including API calls, memory count, and plan limits.

    Example

    stats = client.get_stats()
    
    print(f"Plan: {stats.plan_tier}")
    print(f"API Calls: {stats.usage['api_calls_used']}")
    print(f"Total Memories: {stats.totals['memories']}")

    Additional Methods

    While add() and search() cover most needs, these methods are also available:

    list_memories()

    List all memories with pagination.

    memories = client.list_memories(
        limit=50
    )

    update_memory()

    Update an existing memory.

    client.update_memory(
        "memory-id",
        content="Updated content"
    )

    delete_memory()

    Delete a memory by ID.

    client.delete_memory(
        "memory-id"
    )

    get_stats()

    Get usage statistics.

    stats = client.get_stats()

    Error Handling

    from memorystack import (
        MemoryStackError,
        AuthenticationError,
        RateLimitError,
        ValidationError
    )
    
    try:
        client.add_message("Hello world")
    except AuthenticationError as e:
        print(f"Auth failed: {e.message}")
    except RateLimitError as e:
        print(f"Rate limit: {e.message}")
    except ValidationError as e:
        print(f"Invalid: {e.message}")
    except MemoryStackError as e:
        print(f"Error: {e.message}")

    Common Error Codes

    • 401 - Invalid or missing API key
    • 429 - Rate limit exceeded
    • 400 - Invalid request payload
    • 500 - Internal server error

    Best Practices

    Use Environment Variables

    Store API keys in environment variables, never in code.

    Handle Errors Gracefully

    Always wrap SDK calls in try-except blocks.

    Use Virtual Environments

    Always use venv or virtualenv for project isolation.

    Add Type Hints

    Use type hints for better IDE support and type checking.

    Multi-Agent Systems

    Build collaborative agent systems with memory scoping, agent handoffs, and team coordination.

    Memory Scoping

    Control memory access with personal, team, and project-level scopes:

    from memorystack import MemoryStackClient
    
    # Create agents with different scopes
    writer = MemoryStackClient(
        api_key="your_api_key"
    )
    
    # Personal memory (use agent_id in metadata)
    client.add(
        "My writing style: conversational and data-driven",
        metadata={
            "agent_id": "content_writer",
            "scope": "personal"
        }
    )
    
    # Team memory (shared with team via metadata)
    client.add(
        "Team research: AI market to reach $1.8T by 2030",
        metadata={
            "agent_id": "researcher",
            "team": "editorial",
            "scope": "team"
        }
    )
    
    # Project memory (shared across project)
    client.add(
        "Company brand voice: professional yet approachable",
        metadata={
            "agent_id": "content_writer",
            "project": "content_team",
            "scope": "project"
        }
    )
    
    # Search memories
    results = client.search("writing style")
    team_results = client.search("research finding")

    🔒 Personal Scope

    Private memories accessible only by the creating agent

    👥 Team Scope

    Shared memories within the same team

    🏢 Project Scope

    Accessible to all agents in the project

    Agent Handoffs

    Transfer conversations between agents with full context preservation:

    # Initialize client (only needs API key)
    client = MemoryStackClient(api_key="your_api_key")
    
    # Support agent stores conversation context
    client.add(
        "Customer issue: billing discrepancy for invoice #4521",
        metadata={
            "agent_id": "support_agent",
            "session_id": "customer_123",
            "priority": "high",
            "category": "billing"
        }
    )
    
    # Billing specialist searches for context (same session_id)
    previous_context = client.search("billing discrepancy", limit=10)
    
    # Billing specialist continues with full context
    client.add(
        "Resolved: Invoice #4521 corrected, refund processed",
        metadata={
            "agent_id": "billing_specialist",
            "session_id": "customer_123",
            "handoff_from": "support_agent"
        }
    )

    💡 Handoff Best Practices

    • • Use the same session_id in metadata for context continuity
    • • Store handoff metadata for tracking and analytics
    • • Include issue summary and priority in metadata
    • • Search previous memories before responding

    Team Collaboration

    Build collaborative workflows with shared team knowledge:

    # Initialize client (only needs API key)
    client = MemoryStackClient(api_key="your_api_key")
    
    # Research agent gathers information
    client.add(
        "Research finding: 73% of users prefer AI recommendations",
        metadata={
            "agent_id": "researcher",
            "team": "editorial",
            "project": "content_creation",
            "scope": "team"  # Share with editorial team
        }
    )
    
    # Writer accesses team research
    team_research = client.search("research finding", limit=10)
    
    # Writer creates draft
    client.add(
        "Draft: AI Recommendations article ready for review",
        metadata={
            "agent_id": "writer",
            "team": "editorial",
            "project": "content_creation",
            "scope": "team"
        }
    )
    
    # Editor checks team drafts
    drafts = client.search("draft status")
    
    # Editor provides feedback
    client.add(
        "Feedback: Add more concrete examples in section 2",
        metadata={
            "agent_id": "editor",
            "team": "editorial",
            "project": "content_creation",
            "scope": "team"
        }
    )

    CrewAI Integration

    Integrate Memorystack with CrewAI for powerful multi-agent workflows:

    from crewai import Agent, Task, Crew, Tool
    from memorystack import MemoryStackClient
    
    # Initialize Memorystack client (only needs API key)
    memory = MemoryStackClient(api_key="your_api_key")
    
    # Create memory tools for agents
    def store_memory(content: str, agent_id: str):
        """Store a memory with agent context"""
        return memory.add(content, metadata={
            "agent_id": agent_id,
            "project": "research_team"
        })
    
    def search_memory(query: str):
        """Search memories"""
        return memory.search(query, limit=10)
    
    memory_store_tool = Tool(
        name="store_memory",
        description="Store information in memory",
        func=lambda x: store_memory(x, "researcher")
    )
    
    memory_search_tool = Tool(
        name="search_memory",
        description="Search for information in memory",
        func=search_memory
    )
    
    # Define agents with memory capabilities
    researcher = Agent(
        role="Research Analyst",
        goal="Gather and analyze market data",
        backstory="Expert in market research and data analysis",
        tools=[memory_store_tool, memory_search_tool],
        verbose=True
    )
    
    writer = Agent(
        role="Content Writer",
        goal="Create engaging content from research",
        backstory="Skilled writer with data storytelling expertise",
        tools=[memory_search_tool],
        verbose=True
    )
    
    # Define tasks
    research_task = Task(
        description="Research AI market trends and store findings",
        agent=researcher,
        expected_output="Market research summary with key statistics"
    )
    
    writing_task = Task(
        description="Write article using research findings from memory",
        agent=writer,
        expected_output="1000-word article on AI market trends"
    )
    
    # Create crew
    crew = Crew(
        agents=[researcher, writer],
        tasks=[research_task, writing_task],
        verbose=True
    )
    
    # Execute workflow
    result = crew.kickoff()
    print(result)

    Next Steps