mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-10-11 03:37:56 +00:00
Rewrites 339 TypeScript calls across 50 pages from the rc.5 `method({ namespace, body })` form to the shipped `method(namespace, { ... })` form, and aligns field names with the live v5 spec: `attach` to `include`, `authUrl` to `authorization`, `lastSync` to `latestRun`, `deletedCount` to `count`, and the paginated `namespaces.list()`.
Renames container tags to namespaces across concepts, connectors, integrations and snippets. The namespace pages keep container tag in the description, search keywords and a rename note so old searches still land, and the v3 reference page points at v5.
The migration guide's SDK table now covers both 5.0.0 SDKs, and the SDK integration page uses the real client options (`baseUrl`, `timeoutInSeconds`, `maxRetries`) and error classes.
579 lines
19 KiB
Text
579 lines
19 KiB
Text
---
|
||
title: "Quickstart"
|
||
description: "Ingest a conversation and a document, retrieve them three ways, then wire it into a chat harness."
|
||
icon: "/icons/hugeicons/play.svg"
|
||
---
|
||
|
||
By the end of this page you will:
|
||
|
||
1. **Ingest a conversation** (how personal memory actually arrives)
|
||
2. **Ingest a document** (how knowledge for RAG arrives)
|
||
3. **Retrieve three ways** — document search (RAG), memory graph traversal, and user profile
|
||
4. **Drop it into a chat harness** that remembers across restarts
|
||
|
||
Same `namespace` for everything. One engine, three ways out. A namespace is what v3/v4 called a container tag.
|
||
|
||
## Get an API key
|
||
|
||
Grab a key from the [developer console](https://console.supermemory.ai) — **API Keys → Create API Key**.
|
||
|
||
**console.supermemory.ai** is where keys and usage live.
|
||
|
||
<CodeGroup>
|
||
```bash TypeScript
|
||
npm i supermemory
|
||
export SUPERMEMORY_API_KEY="sm_..."
|
||
```
|
||
|
||
```bash Python
|
||
pip install supermemory
|
||
export SUPERMEMORY_API_KEY="sm_..."
|
||
```
|
||
|
||
```bash curl
|
||
export SUPERMEMORY_API_KEY="sm_..."
|
||
```
|
||
</CodeGroup>
|
||
|
||
## 1. Ingest a conversation
|
||
|
||
Real apps do not push four isolated one-liners as separate “memories.” They send **conversation turns** — often the full session — under a stable `id` so the pipeline can extract facts and link entities.
|
||
|
||
We’ll use one user (`user_4f8a`) and one chat session. The turns never say “Sarah *is* my VP of Product” — that connection is what the graph should resolve later.
|
||
|
||
<CodeGroup>
|
||
```typescript TypeScript
|
||
import { Supermemory } from "supermemory";
|
||
|
||
const supermemory = new Supermemory({ apiKey: process.env.SUPERMEMORY_API_KEY });
|
||
const user = "user_4f8a"; // the namespace
|
||
|
||
const conversation = `
|
||
user: Just got back from Tokyo — the team offsite went great.
|
||
assistant: Glad it went well! Anything stand out?
|
||
user: Sarah presented the Q3 roadmap at the offsite.
|
||
assistant: Sounds like a big moment for her.
|
||
user: She's being promoted to VP of Product.
|
||
assistant: Congrats to Sarah — that's huge.
|
||
user: I need a gift idea for my VP of Product.
|
||
assistant: Happy to help brainstorm something personal.
|
||
`.trim();
|
||
|
||
const conv = await supermemory.add(user, {
|
||
content: conversation,
|
||
id: "chat_offsite_2026", // one session → one document
|
||
metadata: { type: "conversation" },
|
||
dreaming: "instant", // process this document now — see note below
|
||
});
|
||
|
||
console.log(conv.id, conv.status); // e.g. "queued"
|
||
```
|
||
|
||
```python Python
|
||
from supermemory import Supermemory
|
||
|
||
client = Supermemory()
|
||
user = "user_4f8a"
|
||
|
||
conversation = """
|
||
user: Just got back from Tokyo — the team offsite went great.
|
||
assistant: Glad it went well! Anything stand out?
|
||
user: Sarah presented the Q3 roadmap at the offsite.
|
||
assistant: Sounds like a big moment for her.
|
||
user: She's being promoted to VP of Product.
|
||
assistant: Congrats to Sarah — that's huge.
|
||
user: I need a gift idea for my VP of Product.
|
||
assistant: Happy to help brainstorm something personal.
|
||
""".strip()
|
||
|
||
conv = client.add(
|
||
user,
|
||
content=conversation,
|
||
id="chat_offsite_2026", # one session → one document
|
||
metadata={"type": "conversation"},
|
||
dreaming="instant", # process this document now, see note below
|
||
)
|
||
print(conv.id, conv.status) # e.g. "queued"
|
||
```
|
||
|
||
```bash curl
|
||
curl -X POST "https://api.supermemory.ai/ns/user_4f8a/document?dreaming=instant" \
|
||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"content": "user: Just got back from Tokyo — the team offsite went great.\nassistant: Glad it went well! Anything stand out?\nuser: Sarah presented the Q3 roadmap at the offsite.\nassistant: Sounds like a big moment for her.\nuser: She is being promoted to VP of Product.\nassistant: Congrats to Sarah — that is huge.\nuser: I need a gift idea for my VP of Product.\nassistant: Happy to help brainstorm something personal.",
|
||
"id": "chat_offsite_2026",
|
||
"metadata": { "type": "conversation" }
|
||
}'
|
||
```
|
||
</CodeGroup>
|
||
|
||
`add` returns immediately with `status: "queued"`. Processing is still **async** — wait until `done` before searching.
|
||
|
||
<Note>
|
||
**`dreaming: "instant"`** — By default, dreaming is `"dynamic"`: Supermemory batches related documents so memories form from coherent units, so a fresh namespace can show zero memories and an empty profile for several minutes. For this quickstart (and any path where you need memories/profiles right away), pass **`dreaming: "instant"`** so the document is processed on its own as soon as it finishes indexing. That bills one extra operation per document. See [Processing Modes](/ingestion/add-memories#processing-modes).
|
||
</Note>
|
||
|
||
## 2. Ingest a document
|
||
|
||
Now add **knowledge** the agent should ground on — a short internal note the conversation never fully spelled out. This is the SuperRAG / document path.
|
||
|
||
<CodeGroup>
|
||
```typescript TypeScript
|
||
const handbook = `
|
||
# Team notes — gifts & recognition
|
||
|
||
When someone is promoted to VP or above, the company recommends a thoughtful gift
|
||
in the $75–$150 range. Experiences tied to recent team milestones land better
|
||
than generic swag.
|
||
|
||
For product leadership, books on platform strategy or a dinner near the last
|
||
offsite city are common picks. Tokyo offsites often inspire travel-themed gifts.
|
||
`.trim();
|
||
|
||
const doc = await supermemory.add(user, {
|
||
content: handbook,
|
||
id: "doc_gift_policy",
|
||
metadata: { type: "document", source: "handbook" },
|
||
taskType: "superrag",
|
||
});
|
||
|
||
console.log(doc.id, doc.status);
|
||
```
|
||
|
||
```python Python
|
||
handbook = """
|
||
# Team notes — gifts & recognition
|
||
|
||
When someone is promoted to VP or above, the company recommends a thoughtful gift
|
||
in the $75–$150 range. Experiences tied to recent team milestones land better
|
||
than generic swag.
|
||
|
||
For product leadership, books on platform strategy or a dinner near the last
|
||
offsite city are common picks. Tokyo offsites often inspire travel-themed gifts.
|
||
""".strip()
|
||
|
||
doc = client.add(
|
||
user,
|
||
content=handbook,
|
||
id="doc_gift_policy",
|
||
metadata={"type": "document", "source": "handbook"},
|
||
task_type="superrag",
|
||
)
|
||
print(doc.id, doc.status)
|
||
```
|
||
|
||
```bash curl
|
||
curl -X POST "https://api.supermemory.ai/ns/user_4f8a/document?taskType=superrag" \
|
||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"content": "# Team notes — gifts & recognition\n\nWhen someone is promoted to VP or above, the company recommends a thoughtful gift in the $75–$150 range. Experiences tied to recent team milestones land better than generic swag.\n\nFor product leadership, books on platform strategy or a dinner near the last offsite city are common picks. Tokyo offsites often inspire travel-themed gifts.",
|
||
"id": "doc_gift_policy",
|
||
"metadata": { "type": "document", "source": "handbook" }
|
||
}'
|
||
```
|
||
</CodeGroup>
|
||
|
||
## 3. Wait until both are `done`
|
||
|
||
Poll document status. With **`dreaming: "instant"`**, once `system.status` is `done` the document is indexed **and** memories for that document should be available for search and profiles (`queued → extracting → … → done`).
|
||
|
||
> Note that the preferred way is to have `dreaming: dynamic`. supermemory charges one extra operation for instant dreaming. Instant is good for one off tests, setup, debugging and benchmarking.
|
||
|
||
<CodeGroup>
|
||
```typescript TypeScript
|
||
async function waitUntilDone(id: string) {
|
||
for (;;) {
|
||
const d = await supermemory.documents.get(user, id);
|
||
if (d.system.status === "done" || d.system.status === "failed") return d;
|
||
await new Promise((r) => setTimeout(r, 1500));
|
||
}
|
||
}
|
||
|
||
await waitUntilDone(conv.id);
|
||
await waitUntilDone(doc.id);
|
||
console.log("ready to search");
|
||
```
|
||
|
||
```python Python
|
||
import time
|
||
|
||
def wait_until_done(doc_id: str):
|
||
while True:
|
||
d = client.documents.get(user, doc_id)
|
||
if d.system.status in ("done", "failed"):
|
||
return d
|
||
time.sleep(1.5)
|
||
|
||
wait_until_done(conv.id)
|
||
wait_until_done(doc.id)
|
||
print("ready to search")
|
||
```
|
||
|
||
```bash curl
|
||
# replace DOC_ID with each document id from the add responses
|
||
curl "https://api.supermemory.ai/ns/user_4f8a/document/DOC_ID" \
|
||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY"
|
||
# repeat until "system": { "status": "done" }
|
||
```
|
||
</CodeGroup>
|
||
|
||
Short text with instant dreaming usually finishes in a few seconds. Larger PDFs take longer. If you omit `dreaming` (default `"dynamic"`), document RAG can work after `done` while memory extraction may still be batching — use `"instant"` when the next step is memory search or profiles.
|
||
|
||
## 4. Three ways to get context back
|
||
|
||
### A. Document search (RAG)
|
||
|
||
Chunk-level retrieval over raw knowledge — use when you need **what the docs say**.
|
||
|
||
<CodeGroup>
|
||
```typescript TypeScript
|
||
const rag = await supermemory.search(user, {
|
||
query: "gift ideas for a VP promotion after a Tokyo offsite",
|
||
searchMode: "chunks",
|
||
limit: 3,
|
||
});
|
||
|
||
for (const hit of rag.results) {
|
||
console.log(hit.similarity, hit.chunk);
|
||
}
|
||
```
|
||
|
||
```python Python
|
||
rag = client.search(
|
||
user,
|
||
query="gift ideas for a VP promotion after a Tokyo offsite",
|
||
search_mode="chunks",
|
||
limit=3,
|
||
)
|
||
|
||
for hit in rag.results:
|
||
print(hit.similarity, hit.chunk)
|
||
```
|
||
|
||
```bash curl
|
||
curl -X POST "https://api.supermemory.ai/ns/user_4f8a/search?searchMode=chunks&limit=3" \
|
||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "query": "gift ideas for a VP promotion after a Tokyo offsite" }'
|
||
```
|
||
</CodeGroup>
|
||
|
||
You should see chunks from the handbook (budget range, Tokyo offsite angle) — **document grounding**, not personal facts.
|
||
|
||
Omit `searchMode` (or set it to `"hybrid"`, the default) to get extracted memories and document chunks together:
|
||
|
||
```typescript
|
||
await supermemory.search(user, {
|
||
query: "gift ideas for a VP promotion after a Tokyo offsite",
|
||
searchMode: "hybrid",
|
||
limit: 5,
|
||
});
|
||
```
|
||
|
||
### B. Memory graph traversal
|
||
|
||
Search **extracted memories** with related edges. This is the entity-chain moment: gift → VP of Product → Sarah → Tokyo offsite.
|
||
|
||
<CodeGroup>
|
||
```typescript TypeScript
|
||
const memories = await supermemory.search(user, {
|
||
query: "What gift should I get, and why?",
|
||
include: { related: true },
|
||
searchMode: "memories",
|
||
limit: 5,
|
||
});
|
||
|
||
console.log(JSON.stringify(memories, null, 2));
|
||
```
|
||
|
||
```python Python
|
||
memories = client.search(
|
||
user,
|
||
query="What gift should I get, and why?",
|
||
search_mode="memories",
|
||
include={"related": True},
|
||
limit=5,
|
||
)
|
||
print(memories.to_json())
|
||
```
|
||
|
||
```bash curl
|
||
curl -X POST "https://api.supermemory.ai/ns/user_4f8a/search?searchMode=memories&limit=5" \
|
||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"query": "What gift should I get, and why?",
|
||
"include": { "related": true }
|
||
}'
|
||
```
|
||
</CodeGroup>
|
||
|
||
Abbreviated shape:
|
||
|
||
```json
|
||
{
|
||
"results": [
|
||
{
|
||
"id": "mem_8c1f",
|
||
"memory": "Sarah is being promoted to VP of Product",
|
||
"similarity": 0.81,
|
||
"included": {
|
||
"related": {
|
||
"parents": [
|
||
{ "id": "mem_2a90", "memory": "Sarah presented the Q3 roadmap at the Tokyo offsite" }
|
||
],
|
||
"children": [
|
||
{ "id": "mem_b713", "memory": "User needs a gift idea for their VP of Product, Sarah" }
|
||
]
|
||
}
|
||
}
|
||
}
|
||
],
|
||
"searchTime": 287
|
||
}
|
||
```
|
||
|
||
You never wrote “Sarah is my VP of Product” as one sentence. The graph connected sessions of speech. Deep dive: [graph memory](/concepts/graph-memory).
|
||
|
||
### C. User profile
|
||
|
||
Profiles are the **always-on** summary (static + recent dynamic) of an entity (or a namespace) - what you inject every turn without re-searching the world.
|
||
|
||
<CodeGroup>
|
||
```typescript TypeScript
|
||
const { profile } = await supermemory.profile(user);
|
||
|
||
console.log("static:", profile.static.map((m) => m.memory));
|
||
console.log("dynamic:", profile.dynamic.map((m) => m.memory));
|
||
```
|
||
|
||
```python Python
|
||
profile = client.profile(user).profile
|
||
|
||
print("static:", [m.memory for m in profile.static])
|
||
print("dynamic:", [m.memory for m in profile.dynamic])
|
||
```
|
||
|
||
```bash curl
|
||
curl -X POST "https://api.supermemory.ai/ns/user_4f8a/profile" \
|
||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY"
|
||
```
|
||
</CodeGroup>
|
||
|
||
The v5 profile call takes no query. When you also want query-ranked memories, run a `search` next to it (the harness below does exactly that).
|
||
|
||
> There is a lot more to profiles - with [Buckets](/user-profiles/buckets), for example, you can make supermemory learn and categorize incoming information for learning specific things.
|
||
|
||
|
||
| Path | Use when |
|
||
|---|---|
|
||
| **Document search** | Ground in policies, docs, handbooks |
|
||
| **Memory + related** | Personal facts, entity links, “what’s true about this user” |
|
||
| **Profile** | Cheap always-on context every LLM turn |
|
||
|
||
Same `namespace` → same context pool. See [Memory vs RAG](/concepts/memory-vs-rag).
|
||
|
||
## 5. Put it in a harness
|
||
|
||
There is no single required harness. The pattern is the same wherever you run the model: **read** context (profile / search / docs), generate, **write** the turn back under a stable `id` so the session stays one document.
|
||
|
||
Here are two example shapes — pick whatever matches your stack.
|
||
|
||
### Example: explicit profile + search + add
|
||
|
||
<CodeGroup>
|
||
```typescript TypeScript
|
||
// npm i supermemory openai
|
||
import { Supermemory } from "supermemory";
|
||
import OpenAI from "openai";
|
||
import * as readline from "node:readline/promises";
|
||
|
||
const supermemory = new Supermemory({ apiKey: process.env.SUPERMEMORY_API_KEY });
|
||
const llm = new OpenAI();
|
||
const user = "user_4f8a";
|
||
const sessionId = "chat_live_session";
|
||
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
||
|
||
while (true) {
|
||
const question = await rl.question("you: ");
|
||
|
||
const { profile } = await supermemory.profile(user);
|
||
|
||
const related = await supermemory.search(user, {
|
||
query: question,
|
||
searchMode: "memories",
|
||
limit: 5,
|
||
});
|
||
|
||
// optional: also pull document chunks for grounding
|
||
const rag = await supermemory.search(user, {
|
||
query: question,
|
||
searchMode: "chunks",
|
||
limit: 3,
|
||
});
|
||
|
||
const context = [
|
||
"## Profile (static)",
|
||
...profile.static.map((m) => m.memory),
|
||
"## Profile (dynamic)",
|
||
...profile.dynamic.map((m) => m.memory),
|
||
"## Related memories",
|
||
...related.results.map((r) => r.memory).filter(Boolean),
|
||
"## Docs",
|
||
...rag.results.map((r) => r.chunk).filter(Boolean),
|
||
].join("\n");
|
||
|
||
const res = await llm.chat.completions.create({
|
||
model: "gpt-4o",
|
||
messages: [
|
||
{ role: "system", content: `You help this user. Context:\n${context}` },
|
||
{ role: "user", content: question },
|
||
],
|
||
});
|
||
const answer = res.choices[0].message.content ?? "";
|
||
console.log(`assistant: ${answer}`);
|
||
|
||
// append this turn into the same conversation document
|
||
await supermemory.add(user, {
|
||
content: `user: ${question}\nassistant: ${answer}`,
|
||
id: sessionId,
|
||
});
|
||
}
|
||
```
|
||
|
||
```python Python
|
||
# pip install supermemory openai
|
||
from supermemory import Supermemory
|
||
from openai import OpenAI
|
||
|
||
memory = Supermemory()
|
||
llm = OpenAI()
|
||
user = "user_4f8a"
|
||
session_id = "chat_live_session"
|
||
|
||
while True:
|
||
question = input("you: ")
|
||
|
||
profile = memory.profile(user).profile
|
||
|
||
related = memory.search(user, query=question, search_mode="memories", limit=5)
|
||
|
||
# optional: also pull document chunks for grounding
|
||
rag = memory.search(user, query=question, search_mode="chunks", limit=3)
|
||
|
||
context = "\n".join(
|
||
[
|
||
"## Profile (static)",
|
||
*[m.memory for m in profile.static],
|
||
"## Profile (dynamic)",
|
||
*[m.memory for m in profile.dynamic],
|
||
"## Related memories",
|
||
*[r.memory for r in related.results if r.memory],
|
||
"## Docs",
|
||
*[r.chunk for r in rag.results if r.chunk],
|
||
]
|
||
)
|
||
|
||
res = llm.chat.completions.create(
|
||
model="gpt-4o",
|
||
messages=[
|
||
{"role": "system", "content": f"You help this user. Context:\n{context}"},
|
||
{"role": "user", "content": question},
|
||
],
|
||
)
|
||
answer = res.choices[0].message.content or ""
|
||
print(f"assistant: {answer}")
|
||
|
||
# append this turn into the same conversation document
|
||
memory.add(
|
||
user,
|
||
content=f"user: {question}\nassistant: {answer}",
|
||
id=session_id,
|
||
)
|
||
```
|
||
</CodeGroup>
|
||
|
||
### Example: Vercel AI SDK
|
||
|
||
Same pattern, wrapped: `withSupermemory` injects context and can save the conversation for you. Details: [AI SDK integration](/integrations/ai-sdk).
|
||
|
||
```typescript
|
||
// npm install ai @ai-sdk/openai @supermemory/tools
|
||
import { generateText } from "ai";
|
||
import { openai } from "@ai-sdk/openai";
|
||
import { withSupermemory } from "@supermemory/tools/ai-sdk";
|
||
import * as readline from "node:readline/promises";
|
||
|
||
const model = withSupermemory(openai("gpt-4o"), {
|
||
namespace: "user_4f8a",
|
||
id: "chat_live_session", // keep stable for the whole session
|
||
mode: "full", // profile + query search
|
||
});
|
||
|
||
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
||
|
||
while (true) {
|
||
const prompt = await rl.question("you: ");
|
||
const { text } = await generateText({ model, prompt });
|
||
console.log(`assistant: ${text}`);
|
||
}
|
||
```
|
||
|
||
Try:
|
||
|
||
```
|
||
you: What gift should I get for the person being promoted?
|
||
assistant: You're looking for something for Sarah — she's being promoted to VP of
|
||
Product after presenting the Q3 roadmap in Tokyo. Your handbook suggests $75–$150
|
||
and something tied to the offsite; a Tokyo-inspired experience or platform-strategy
|
||
book would fit…
|
||
```
|
||
|
||
### Kill it, restart it
|
||
|
||
Ctrl+C the process, start again with the **same** `namespace` (and optional same `id` for the live session). Ask:
|
||
|
||
```
|
||
you: who's getting promoted?
|
||
assistant: Sarah — she's being promoted to VP of Product.
|
||
```
|
||
|
||
Nothing was reloaded from your process. Memory and docs live in supermemory.
|
||
|
||
## Mental model
|
||
|
||
```
|
||
INGEST WAIT RETRIEVE
|
||
────── ──── ────────
|
||
Conversation (id) → system.status === done → Memory graph (+ related)
|
||
Document (id) → system.status === done → Document search (RAG)
|
||
→ Profile (static + dynamic)
|
||
│
|
||
▼
|
||
Chat harness
|
||
```
|
||
|
||
## Where next
|
||
|
||
<CardGroup cols={2}>
|
||
<Card title="Add context" icon="/icons/hugeicons/plus-sign.svg" href="/ingestion/add-memories">
|
||
Conversations, files, URLs, `id` updates, and status.
|
||
</Card>
|
||
<Card title="Search" icon="/icons/hugeicons/search-01.svg" href="/recall/search">
|
||
Hybrid vs memories, filters, thresholds, rerank.
|
||
</Card>
|
||
<Card title="Graph memory" icon="/icons/hugeicons/route-02.svg" href="/concepts/graph-memory">
|
||
How relations and entity chains are produced.
|
||
</Card>
|
||
<Card title="User profiles" icon="/icons/hugeicons/user.svg" href="/concepts/user-profiles">
|
||
Static vs dynamic, and when to inject a profile every turn.
|
||
</Card>
|
||
<Card title="AI SDK" icon="/icons/hugeicons/triangle.svg" href="/integrations/ai-sdk">
|
||
withSupermemory modes, id, addMemory.
|
||
</Card>
|
||
<Card title="Namespaces" icon="/icons/hugeicons/lock.svg" href="/concepts/container-tags">
|
||
Isolation for multi-tenant products.
|
||
</Card>
|
||
</CardGroup>
|