Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.maximem.ai/llms.txt

Use this file to discover all available pages before exploring further.

Where to start, depending on what you’re trying to do
  • “I just want to try Synap without installing anything” — open the live playground and exercise the SDK from your browser.
  • “I want to see Synap working in 10 minutes” — you’re on the right page. Stay here.
  • “I want to wire Synap into a real FastAPI / Flask / Next.js / Django app” — head to Setup & Integration after you finish this page.
  • “I want a complete end-to-end tutorial with an LLM, conversation routing, and graceful degradation” — go to First Integration. That tutorial assumes you’ve finished this Quickstart.

TL;DR — Hello World

If you already have an API key, this is everything you need to ingest one memory and read it back:
hello_synap.py
# pip install maximem-synap
# export SYNAP_API_KEY=synap_...
import asyncio
from maximem_synap import MaximemSynapSDK

async def main():
    async with MaximemSynapSDK() as sdk:
        await sdk.memories.create(
            document="User: I prefer dark mode.\nAssistant: Noted!",
            document_type="ai-chat-conversation",
            user_id="user_alice",
            customer_id="acme_corp",
        )

        # Wait briefly for async processing
        await asyncio.sleep(3)

        # Retrieve via the scope you ingested at (user_id here)
        context = await sdk.user.context.fetch(
            user_id="user_alice",
            search_query=["preferences"],
        )
        for p in context.preferences:
            print(p.content)

asyncio.run(main())
The rest of this page unfolds those eight lines into a step-by-step walkthrough — read it if this is your first time. Skip ahead to First Integration for the full agent loop with an LLM.

Prerequisites

1

Install the SDK

Install the Synap SDK from PyPI:
pip install maximem-synap
gRPC streaming is enabled by default — no extra install needed.
Verify the installation:
python -c "import maximem_synap; print(maximem_synap.__version__)"
2

Set Up Your Client

A Client is your organization’s top-level account in Synap. Every instance belongs to a Client. You have two options:Create a new Client
  1. Log in to the Synap Dashboard
  2. Click Create Client, enter your organization name, and confirm
Join an existing ClientIf your team already has a Synap account, ask your administrator to invite you. Once added, log in and you’ll see the shared Client and its instances in your Dashboard.
Skipping this step is not possible — every instance must belong to a Client. If you are unsure whether your organization already has one, check with your team before creating a new Client.
3

Create an Instance

An instance is an isolated memory environment for your agent. Each instance has its own storage, configuration, and scope hierarchy.
  1. In the Dashboard, navigate to Instances in the sidebar
  2. Click Create Instance
  3. Fill in the instance form:
    • Name (required): A human-readable label, e.g. "My First Agent"
    • Agent Type (required): Choose the type that best describes your agent (e.g. B2B Customer Support, B2C Companion, Workflow Agent)
    • Description (optional): A short description of what this instance is for
    • Use-Case Markdown (optional but recommended): Upload a .md file describing your agent’s use case — see below
Creating a new instance in the Synap Dashboard

Use-Case Markdown

The Use-Case Markdown file tells Synap what your agent does, who it serves, and what it should remember. Synap uses it to generate an optimized Memory Architecture Configuration (MACA) for your instance — so the more detail you provide, the better your memory extraction and retrieval will be from day one.Click Download Template in the Create Instance form, fill in at least the three required sections (Agent Objective, Target Users, Task Examples), and upload the file (.md, .markdown, or .txt — max 512 KB) before clicking Create.For the full template and section-by-section guidance, see Writing a Use-Case Markdown File.
You can upload or update the use-case file at any time after instance creation via Instance Settings in the Dashboard. Synap will re-evaluate and update the MACA when a new file is submitted.
4

Generate an API Key

  1. In the Dashboard, go to your newly created instance
  2. Open the API Keys section on the instance detail page
  3. Click Generate API Key
  4. Give it a label (e.g., “development”) and click Generate
  5. Copy the key immediately — it starts with synap_
The API key is displayed only once. Copy it now and store it securely. If you lose it, revoke it from the dashboard and generate a new one.
5

Initialize the SDK

Set your API key as an environment variable:
export SYNAP_API_KEY="synap_your_key_here"
Create a new Python file:
main.py
import asyncio
from maximem_synap import MaximemSynapSDK

async def main():
    sdk = MaximemSynapSDK()
    await sdk.initialize()

    print("Synap SDK initialized successfully!")

    # Your code goes here...

    await sdk.shutdown()

if __name__ == "__main__":
    asyncio.run(main())
That’s it. The SDK reads SYNAP_API_KEY from your environment automatically.
You can also pass the API key directly if you prefer:
sdk = MaximemSynapSDK(api_key="synap_your_key_here")
Run the script:
python main.py
You should see Synap SDK initialized successfully!
On Windows, python is sometimes intercepted by the Microsoft Store app execution alias and fails with "Python was not found". Use py (the Windows Python launcher) instead — it ships with every official Python installer. The same applies to pip: py -m pip install maximem-synap always works regardless of PATH configuration.
6

Ingest Your First Memory

Now let’s send a conversation to Synap. The ingestion pipeline will automatically extract structured knowledge — facts, preferences, entities, and more.
# Ingest a sample conversation
response = await sdk.memories.create(
    document=(
        "User: What's the weather like?\n"
        "Assistant: It's sunny and 72°F in San Francisco today.\n"
        "User: Nice! I love warm weather. I'm planning a trip to Japan next month.\n"
        "Assistant: That sounds exciting! Japan in spring is beautiful."
    ),
    document_type="ai-chat-conversation",
    user_id="user_123",
    customer_id="acme_corp",
)

print(f"Ingestion ID: {response.ingestion_id}")
print(f"Status: {response.status}")
The SDK returns immediately with an ingestion ID. The pipeline processes the content asynchronously, extracting:
  • Fact: User is located in San Francisco
  • Preference: User loves warm weather
  • Temporal event: User is planning a trip to Japan next month
  • Entities: San Francisco, Japan (resolved and linked in the knowledge graph)
Ingestion is asynchronous by design. The memories.create() call returns as soon as the content is accepted by Synap Cloud. Processing typically completes within a few seconds, but complex documents may take longer.
7

Retrieve Context

Once memories are ingested and processed, you can retrieve relevant context. Synap searches across both vector and graph storage, ranks results by relevance, and respects scope boundaries.
Match the retrieval interface to the scope you ingested at. Synap has three scope-specific retrieval methods, and a memory is only returned through the one that matches how it was tagged:
If you ingested with…Retrieve via…
user_id=...sdk.user.context.fetch(user_id=...)
customer_id=... (no user)sdk.customer.context.fetch(customer_id=...)
A conversation registered via record_message(...)sdk.conversation.context.fetch(conversation_id=...)
A memory tagged with multiple identifiers is retrievable through any matching interface. Calling conversation.context.fetch with a brand-new, unregistered conversation_id returns empty results by design — there is no conversation row to anchor scope resolution. See Context Fetch for the full reference.
The ingestion above used user_id="user_123", so retrieve at user scope:
# Retrieve relevant context at user scope (matches the ingestion above)
context = await sdk.user.context.fetch(
    user_id="user_123",
    search_query=["weather preferences", "travel plans"],
    max_results=5,
)

# Print retrieved facts
print(f"Retrieved {len(context.facts)} facts:")
for fact in context.facts:
    print(f"  - {fact.content} (confidence: {fact.confidence})")

# Print retrieved preferences
print(f"\nRetrieved {len(context.preferences)} preferences:")
for pref in context.preferences:
    print(f"  - {pref.content}")

# Print retrieved episodes
print(f"\nRetrieved {len(context.episodes)} episodes:")
for episode in context.episodes:
    print(f"  - {episode.summary}")
Example output:
Retrieved 1 facts:
  - User is located in San Francisco (confidence: 0.92)

Retrieved 1 preferences:
  - User loves warm weather

Retrieved 1 episodes:
  - User is planning a trip to Japan next month
You can now inject this context into your LLM’s system prompt or conversation history to create a personalized, context-aware experience.
8

Clean Up

Always shut down the SDK cleanly to flush any pending operations and release resources:
await sdk.shutdown()
The complete script looks like this:
main.py
import asyncio
from maximem_synap import MaximemSynapSDK

async def main():
    # Reads SYNAP_API_KEY from environment; instance ID resolved server-side
    sdk = MaximemSynapSDK()
    await sdk.initialize()

    # Ingest a conversation
    response = await sdk.memories.create(
        document=(
            "User: What's the weather like?\n"
            "Assistant: It's sunny and 72°F in San Francisco today.\n"
            "User: Nice! I love warm weather. I'm planning a trip to Japan next month.\n"
            "Assistant: That sounds exciting! Japan in spring is beautiful."
        ),
        document_type="ai-chat-conversation",
        user_id="user_123",
        customer_id="acme_corp",
    )
    print(f"Ingested: {response.ingestion_id}")

    # Wait briefly for processing (in production, use webhooks instead)
    await asyncio.sleep(3)

    # Retrieve context at the same scope used for ingestion (user)
    context = await sdk.user.context.fetch(
        user_id="user_123",
        search_query=["weather preferences"],
        max_results=5,
    )
    for fact in context.facts:
        print(f"  {fact.content} (confidence: {fact.confidence})")

    await sdk.shutdown()

if __name__ == "__main__":
    asyncio.run(main())
9

Close the loop: retrieve → generate → ingest

A real agent doesn’t ingest in isolation. It fetches relevant context, calls the LLM with that context, and ingests the resulting turn back into memory. That is the atomic unit of using Synap. Here’s the minimum-viable version with OpenAI:
from maximem_synap import MaximemSynapSDK
from openai import AsyncOpenAI

sdk = MaximemSynapSDK()
openai = AsyncOpenAI()

async def turn(user_id: str, customer_id: str, conversation_id: str, user_message: str) -> str:
    # 1. Record the user's message — this also registers the conversation
    #    so conversation.context.fetch can resolve scope on subsequent turns.
    await sdk.conversation.record_message(
        conversation_id=conversation_id,
        role="user",
        content=user_message,
        user_id=user_id,
        customer_id=customer_id,
    )

    # 2. Retrieve relevant memory context for this conversation
    ctx = await sdk.conversation.context.fetch(
        conversation_id=conversation_id,
        search_query=[user_message],
    )
    memories = "\n".join(f"- {f.content}" for f in ctx.facts[:5])

    # 3. Generate with the LLM, injecting memories into the system prompt
    completion = await openai.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": f"Known facts about the user:\n{memories}"},
            {"role": "user", "content": user_message},
        ],
    )
    reply = completion.choices[0].message.content

    # 4. Record the assistant reply, then persist the turn for long-term retrieval
    await sdk.conversation.record_message(
        conversation_id=conversation_id,
        role="assistant",
        content=reply,
        user_id=user_id,
        customer_id=customer_id,
    )
    await sdk.memories.create(
        document=f"User: {user_message}\nAssistant: {reply}",
        document_type="ai-chat-conversation",
        user_id=user_id,
        customer_id=customer_id,
        metadata={"conversation_id": conversation_id},
    )
    return reply
For a fully-worked FastAPI + OpenAI app — including error handling, graceful degradation, and conversation routing — continue to the First Integration guide.

What’s next?

You’ve successfully ingested your first memory and retrieved context. Here’s where to go from here:

Core Concepts

Understand the full Synap architecture — scopes, memory types, entity resolution, and the ingestion pipeline.

SDK Configuration

Configure the SDK for your production environment — timeouts, retries, logging, and credential management.

Memory Architecture

Learn how to configure what gets extracted, how it’s stored, and how retrieval ranking works.

Production Checklist

Security, performance, monitoring, and reliability best practices before going live.