supermemory/apps/docs/quickstart.mdx
MaheshtheDev 672defc08b docs: move SDK snippets to the shipped v5 call shape and finish the namespace rename (#1772)
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.
2026-10-06 17:06:38 +00:00

579 lines
19 KiB
Text
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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>