supermemory/apps/docs/concepts/how-it-works.mdx
Dhravya Shah f882f1104d
docs: restructure documentation site and update integration UI (#1331)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-07-21 20:19:30 -07:00

182 lines
7.5 KiB
Text

---
title: "How Supermemory Works"
sidebarTitle: "How it works"
description: "From a file or chat turn to something you can search — the ingest pipeline, statuses, and outputs."
icon: "cpu"
---
At it's core, supermemory is powered by a custom learning model and a graph database that we built internally.
<CardGroup cols={2}>
<Card title="Learning model">
Decides what and how to learn, what is important, when to forget, creating relations, etc.
</Card>
<Card title="Temporal Vector-graph engine">
Where the learnings are actually stored, optimized for search. Fact-based temporal graph that has Vector, FTS, and graph built in.
</Card>
</CardGroup>
But, you don't have to think about the above. The interface for users is as simple as it gets.
## Get started in under a minute
<CardGroup cols={2}>
<Card title="1. Get an API key" icon="key" href="https://console.supermemory.ai">
From the [developer console](https://console.supermemory.ai) — **API Keys → Create API Key**. `console.supermemory.ai` is where keys and usage live.
</Card>
<Card title="2. Use it" icon="terminal" href="/using-supermemory">
Install the SDK, drop in your key, add a memory, and search it — right below, or the full [ingest → retrieve loop](/using-supermemory).
</Card>
</CardGroup>
<CodeGroup>
```bash TypeScript
npm install supermemory
```
```typescript TypeScript
import Supermemory from "supermemory";
const client = new Supermemory({ apiKey: "sm_..." }); // from console.supermemory.ai → API Keys
await client.add({ content: "The user loves Paris.", containerTag: "user_123" });
const { results } = await client.search({
q: "where does the user want to travel?",
containerTag: "user_123",
});
```
```python Python
from supermemory import Supermemory
client = Supermemory(api_key="sm_...") # from console.supermemory.ai → API Keys
client.add(content="The user loves Paris.", container_tag="user_123")
results = client.search(
q="where does the user want to travel?",
container_tag="user_123",
)
```
```bash curl
curl -X POST https://api.supermemory.ai/v3/documents \
-H "Authorization: Bearer sm_..." \
-H "Content-Type: application/json" \
-d '{
"content": "The user loves Paris.",
"containerTag": "user_123"
}'
```
</CodeGroup>
## What you send: documents
A **document** is raw input — whatever you hand Supermemory:
- Conversation transcripts and messages
- Text, markdown, HTML
- PDFs, images, audio/video, code
- URLs and connector items (Drive, Notion, Gmail, …)
You do not pre-chunk or pick an embedding model. See [Multi-modal ingestion](/concepts/content-types) for formats, and [Add context](/ingestion/add-memories) for the API.
Supermemory handles the ingestion and extraction for you. This also gives us a big advantage for quality - The engine extracts it in an optimized way with Contextual Chunking and other features for better quality search and memory generation.
> Use a stable **`customId`** when the same conversation or file will be updated later (sessions, connector syncs). That identity also drives [diff billing](/overview/billing#full-discount-on-already-seen-tokens-diff-billing) on re-ingest.
## What the pipeline does
| Stage | What happens |
| --- | --- |
| **Queued** | Accepted; waiting to run |
| **Extracting** | Text / OCR / transcription / page fetch |
| **Chunking** | Splits content for retrieval (type-aware where needed) |
| **Embedding** | Vectors for similarity search |
| **Indexing** | Makes chunks and derived structure searchable |
| **Done** | Document path is ready for search |
```typescript
const doc = await client.add({
content: conversationText,
containerTag: "user_123",
customId: "chat_session_1",
});
// Poll until ready
const status = await client.documents.get(doc.id);
// status.status → "queued" | "extracting" | ... | "done" | "failed"
```
Larger PDFs and long video take longer. Short chat turns usually finish in seconds.
## Dreaming (how memories enter the graph)
Document **status `done`** means chunks are indexed for search. **Memories** — the graph facts, updates, and derives — come from a second phase called **dreaming**.
This is when the content is passed through the memory model and merged, arranged and organized for the future.
Pass `dreaming` on [add](/ingestion/add-memories):
| Mode | Default? | Behavior | When to use |
| --- | --- | --- | --- |
| **`dynamic`** | Yes | Related documents are grouped so memories form from **coherent units**, not one isolated write at a time. Graph quality is higher for real multi-turn / multi-doc flows. Memory extraction may continue **after** `status: "done"`. | Production agents, connectors, ongoing sessions |
| **`instant`** | No | This document is dreamed **on its own, right away**. Memories are available as soon as processing finishes for that doc. Bills **one extra [operation](/overview/billing)** per document. | Demos, quickstarts, “I need the graph now” |
```typescript
// Production default — omit or set explicitly
await client.add({
content: conversationText,
containerTag: "user_123",
customId: "chat_session_1",
dreaming: "dynamic",
});
// Need memories immediately (e.g. tutorial)
await client.add({
content: conversationText,
containerTag: "user_123",
customId: "chat_session_1",
dreaming: "instant",
});
```
**Rule of thumb:** prefer **`dynamic`** for quality and cost in real apps, use **`instant`** when the next step is a memory search or profile that must reflect this document immediately (as in the [quickstart](/quickstart)). Keeping it dynamic helps it pair better with other memories and better connections, inferences to be made.
How those memories connect and stay true over time is [Graph memory](/concepts/graph-memory). API detail: [Processing modes](/ingestion/add-memories#processing-modes).
## What you get out
After the pipeline runs, the same document leads to three things -> Chunks, Memories and Profile. (in the same `containerTag`):
| Output | Role | Go deeper |
| --- | --- | --- |
| **Document chunks** | Grounding in the raw source (RAG / SuperRAG) | [SuperRAG](/concepts/super-rag), [Search API](/recall/search) |
| **Memories** | Extracted facts in a living graph — updates, links, time | [Graph memory](/concepts/graph-memory) |
| **Profile** | A sample of memories, static + dynamic summary for always-on context | [Profiles](/concepts/user-profiles), [Profile API](/recall/user-profiles) |
Supermemory does **not** only store the file. It derives **memories** (understanding) and keeps **chunks** (the source) so you can personalize *and* ground. That distinction is the core of [Memory vs RAG](/concepts/memory-vs-rag).
## Isolation and identity
- **`containerTag`** — hard isolation boundary (user, tenant, project). See [Container tags](/concepts/container-tags).
- **Metadata** — soft dimensions *inside* a tag for filtering. See [Metadata filtering](/concepts/filtering).
- **Scoped API keys** — credentials that cannot cross a container. See [API keys](/authentication#scoped-api-keys).
## Next steps
<CardGroup cols={2}>
<Card title="Graph memory" icon="vector-square" href="/concepts/graph-memory">
How facts connect, update, and stay true over time.
</Card>
<Card title="Multi-modal ingestion" icon="file-stack" href="/concepts/content-types">
Formats, extractors, and what you can send.
</Card>
<Card title="Add context" icon="plus" href="/ingestion/add-memories">
API: add, customId, files, dreaming, status.
</Card>
<Card title="Search API" icon="search" href="/recall/search">
Query documents and memories after the pipeline finishes.
</Card>
</CardGroup>