docs(api): align v5 ingestion and document operations docs with the API (#1810)

Fixes v5 ingestion and document-operation docs.

- **Query params return `400`.** `dreaming`, `fileType` and `mimeType` were documented as query params; they are JSON body or multipart form fields.
- **Errors.** Out-of-balance quota is `402`, not `429`; `429` is only rate limiting. Added the `409` returned during a namespace merge.
- **Statuses.** There is no `processing` status. The real ones are queued, extracting, chunking, embedding, done and failed; treat anything else as in progress.
- **`group` on updates.** `group` is ingestion-side: it picks which existing memories serve as context while content is processed. Changing it only takes effect on re-ingestion, so it's sent with `content`/`file`. The "group-only PATCH" claims are removed from the migration doc.
- **Lists, deletes and forget:**
  - Valid `sort` values per type, a `limit` max of 100, and `include.forgotten`.
  - Deletes skip documents that are still processing.
  - Forget-matching has a 100-match cap and a 2000-character `query` limit.
- **Failed documents stay `failed`.** The docs said they're deleted after 2 minutes. They actually stay `failed`, and resending the same `id` reprocesses them.
- **Smaller fixes:**
  - Metadata allows `string[]`.
  - The batch response field is `count`.
  - `audio` is a valid `fileType`.
  - Chunk overlap is 200 characters.
  - URL extraction no longer claims Markdowner.
  - Search examples no longer index the response object as an array.

Checked against the current API and the published SDKs (TS 5.0.1, Python 5.0.0). Legacy v3/v4 docs are unchanged apart from factual fixes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
sohamd22 2026-10-15 18:52:40 +00:00
parent 8452a00434
commit 4347970d16
12 changed files with 74 additions and 65 deletions

View file

@ -5,7 +5,7 @@ description: "All the content formats Supermemory can ingest and process"
icon: "/icons/hugeicons/files-01.svg"
---
Supermemory automatically extracts and indexes content from various formats. There are two entry points: `supermemory.add()` for text and URLs, `supermemory.documents.uploadFile()` for actual files. Both take the target `namespace` as a top-level key. See [Add Memories](/ingestion/add-memories) to learn how to ingest content via the API.
Supermemory automatically extracts and indexes content from various formats. There are two entry points: `supermemory.add()` for text and URLs, `supermemory.documents.uploadFile()` for actual files. Both take the target `namespace` as the first argument. See [Add Memories](/ingestion/add-memories) to learn how to ingest content via the API.
## Text content
@ -31,7 +31,7 @@ await supermemory.add("documentation", {
});
```
**Extracts:** Article text, headings, metadata. Strips navigation, ads, boilerplate. URL extraction is powered by [Markdowner](https://md.dhr.wtf).
**Extracts:** Article text, headings, metadata. Strips navigation, ads, boilerplate.
---
@ -102,13 +102,13 @@ await supermemory.add("user_123", {
**Extracts:** Structure, headings, code blocks with syntax awareness.
Code is chunked using [code-chunk](https://github.com/supermemoryai/code-chunk), which understands AST boundaries to keep functions, classes, and logical blocks intact. See [Super RAG](/concepts/super-rag) for how Supermemory optimizes chunking for each content type.
See [Super RAG](/concepts/super-rag) for how Supermemory optimizes chunking for each content type.
---
## Images
Set `fileType: "image"` and `mimeType` so Supermemory knows exactly how to process it. Both are query parameters, so they sit next to `namespace` rather than inside `body`:
Set `fileType: "image"` and `mimeType` so Supermemory knows exactly how to process it. Both are multipart form fields, sent in the same object as `file` and `metadata`:
```typescript
await supermemory.documents.uploadFile("user_123", {
@ -127,7 +127,7 @@ await supermemory.documents.uploadFile("user_123", {
## Audio & video
Video has a dedicated `fileType`; audio is uploaded the same way and detected from the file itself:
Video and audio each have a dedicated `fileType` (`"video"`, `"audio"`); set it with `mimeType` when inference is not enough:
```typescript
// Video
@ -142,6 +142,7 @@ await supermemory.documents.uploadFile("user_123", {
await supermemory.documents.uploadFile("user_123", {
file: fs.createReadStream('call-recording.mp3'),
metadata: JSON.stringify({ title: "Customer Call Recording" }),
fileType: "audio",
mimeType: "audio/mpeg",
});
```
@ -215,7 +216,7 @@ await supermemory.add("user_123", { content: "https://example.com/page" });
await supermemory.add("user_123", { content: "User said they prefer email contact" });
```
For files, `uploadFile` detects type from the file itself in most cases. `fileType` and `mimeType` only exist to force specific processing when inference is not enough — set them for images and video.
For files, `uploadFile` detects type from the file itself in most cases. `fileType` and `mimeType` only exist to force specific processing when inference is not enough — set them for images, video, and audio.
---
@ -227,7 +228,7 @@ For files, `uploadFile` detects type from the file itself in most cases. `fileTy
| Files | 50MB |
| URLs | Fetched content up to 10MB |
**Typical processing time:** text is near-instant; PDFs take 1-5s; images 2-10s; video 10s+; webpages 1-3s. Text content is chunked at the sentence level with a 2-sentence overlap between chunks.
**Typical processing time:** text is near-instant; PDFs take 1-5s; images 2-10s; video 10s+; webpages 1-3s. Text content is split on sentence boundaries, with about 200 characters of overlap carried between chunks.
<Tip>
For large files, consider chunking or using [connectors](/connectors/overview) for automatic sync.

View file

@ -27,7 +27,7 @@ await supermemory.add("user_123", {
dreaming: "instant", // memories land in the graph right away
});
const results = await supermemory.search("user_123", {
const { results } = await supermemory.search("user_123", {
query: "where does Alex work?",
include: { related: true },
searchMode: "memories",
@ -154,7 +154,7 @@ await supermemory.add("user_123", {
content: "Alex mentioned he just started at Stripe",
});
const results = await supermemory.search("user_123", {
const { results } = await supermemory.search("user_123", {
query: "where does Alex work?",
include: { related: true },
searchMode: "memories",

View file

@ -61,10 +61,10 @@ results = client.search("user_123", query="where does the user want to travel?")
```
```bash curl
curl -X POST "https://api.supermemory.ai/ns/user_123/document?dreaming=instant" \
curl -X POST "https://api.supermemory.ai/ns/user_123/document" \
-H "Authorization: Bearer sm_..." \
-H "Content-Type: application/json" \
-d '{ "content": "The user loves Paris." }'
-d '{ "content": "The user loves Paris.", "dreaming": "instant" }'
curl -X POST "https://api.supermemory.ai/ns/user_123/search" \
-H "Authorization: Bearer sm_..." \
@ -118,7 +118,7 @@ A document with status `done` has its chunks indexed for search. Memories (the g
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) (a query parameter, so a top-level key in the SDK):
Pass `dreaming` on [add](/ingestion/add-memories) (a field in the JSON body, next to `content` in the SDK):
| Mode | Default? | Behavior | When to use |
| --- | --- | --- | --- |

View file

@ -66,7 +66,7 @@ Every write goes to one `namespace` (what v3/v4 called a container tag). The nam
```
<Warning>
If an irrecoverable processing error occurs, the document is automatically deleted after 2 minutes.
If an irrecoverable processing error occurs, the document's status becomes `failed`. Send the content again with the same `id` to reprocess it.
</Warning>
---
@ -193,16 +193,16 @@ Scale and Enterprise include [advanced document extraction for PDFs](/concepts/c
## Parameters
`namespace`, `taskType`, and `dreaming` are top-level keys on the SDK call (`taskType` and `dreaming` are query parameters on the HTTP route). Everything else goes in `body`.
`namespace` is the first argument on the SDK call and the URL path on the HTTP route. Every other parameter, including `taskType` and `dreaming`, goes in the request object (the JSON body over HTTP). The route accepts no query parameters; sending one returns `400`.
| Parameter | Type | Description |
|-----------|------|-------------|
| `namespace` | string | **Required.** Group by user/project. Goes in the URL path. Required for user profiles |
| `content` | string | **Required.** Any raw content — text, conversations, URLs, HTML |
| `id` | string | **Recommended.** Your ID for the content (conversation ID, doc ID). Enables updates and deduplication. The response `id` echoes it back |
| `metadata` | object | Key-value pairs for filtering (strings, numbers, booleans) |
| `metadata` | object | Key-value pairs for filtering (strings, numbers, booleans, or arrays of strings) |
| `group` | object | Filter which existing memories are used as context during ingestion. See [Filtered Writes](#filtered-writes) |
| `supportingContext` | string | Context for memory extraction on this namespace. Max 1500 chars. See [Customization](/concepts/customization#entity-context) |
| `supportingContext` | string | Context for memory extraction on this namespace. Max 1500 chars. See [Customization](/concepts/customization#supporting-context) |
| `date` | string | ISO 8601 date the content was originally created. Use when backfilling. See [Backfill historical data](/ingestion/batch-ingest-historical-data) |
| `dreaming` | `"dynamic" \| "instant"` | Processing mode. Default `"dynamic"`. `"instant"` processes each document on its own and bills one extra operation. See [Processing Modes](#processing-modes) |
| `taskType` | `"memory" \| "superrag"` | Pipeline to run. Default `"memory"`. `"superrag"` skips fact extraction and profile updates, doing only chunk/embed/index — at 5x cheaper per token. See [SuperRAG ingestion](/concepts/super-rag#ingesting-as-pure-superrag-tasktype-superrag) |
@ -223,16 +223,16 @@ Scale and Enterprise include [advanced document extraction for PDFs](/concepts/c
{ content: "# Project Docs\n\n## Features\n- Real-time sync" }
```
**Namespaces:**
**Namespaces** (first argument; letters, numbers, `-`, `_`, and `:`, up to 100 characters):
```typescript
// By user
{ namespace: "user_123" }
await supermemory.add("user_123", { content: "..." });
// By project
{ namespace: "project_alpha" }
await supermemory.add("project_alpha", { content: "..." });
// Hierarchical
{ namespace: "org_456_team_backend" }
await supermemory.add("org_456_team_backend", { content: "..." });
```
**IDs (Recommended):**
@ -262,8 +262,8 @@ Scale and Enterprise include [advanced document extraction for PDFs](/concepts/c
}
}
```
- No nested objects or arrays
- Values: string, number, or boolean only
- No nested objects
- Values: string, number, boolean, or an array of strings
**Supporting Context:**
```typescript
@ -363,7 +363,7 @@ The metadata itself is still written to the document, but the memories will only
### How it works
When `group` is provided:
- **Profile memories** (static context) are filtered to only those from documents matching the metadata
- **Profile memories** (static context) are filtered by the existing memories' metadata
- **Similar memories** used as context during ingestion are filtered the same way
- The new document's own metadata is written normally — the filter only affects which **existing** memories are used as context
@ -371,7 +371,7 @@ When `group` is provided:
| Key | Type | Description |
|-----|------|-------------|
| `group` | `Record<string, string \| number \| boolean \| string[]>` | Key-value pairs to filter existing memories by their source document metadata |
| `group` | `Record<string, string \| number \| boolean \| string[]>` | Key-value pairs to filter existing memories by their own metadata, rather than a live join to source-document metadata |
- **Scalar values** (string, number, boolean) match exactly
- **Array values** match if **any** value in the array matches (OR logic)
@ -404,7 +404,7 @@ When you add content, Supermemory:
Track progress with `GET /ns/{namespace}/document/{id}`:
```typescript
const doc = await supermemory.documents.get("user_123", "abc123");
console.log(doc.system.status); // "queued" | "processing" | "done"
console.log(doc.system.status); // "queued" | "extracting" | "chunking" | "embedding" | "done" | "failed"
```
<AccordionGroup>
@ -444,17 +444,19 @@ console.log(doc.system.status); // "queued" | "processing" | "done"
<Accordion title="Error handling">
| Status | Error | Cause |
|--------|-------|-------|
| 400 | Bad request | Missing required fields, invalid parameters |
| 400 | Bad request | Missing required fields, invalid parameters, unexpected query parameters |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | Insufficient permissions |
| 429 | Rate limited | Too many requests or quota exceeded |
| 402 | Payment required | Insufficient balance or document quota |
| 403 | Forbidden | No write access to this namespace |
| 409 | Conflict | A namespace merge is in progress |
| 429 | Rate limited | Too many requests |
| 500 | Internal error | Processing failure |
```typescript
try {
await supermemory.add("user_123", { content: "..." });
} catch (error) {
// Back off on 429, fix the request on 400, retry later on 5xx
// Back off on 429, top up on 402, fix the request on 400, retry later on 5xx
console.error("add failed:", error);
}
```

View file

@ -102,7 +102,7 @@ curl -X POST "https://api.supermemory.ai/ns/historical_import/document/batch" \
</CodeGroup>
Batch results preserve input order. Inspect `success`, `failed`, and every item in `results`; a batch can contain successful and failed items together.
`results` lists accepted documents first, in request order, then failed ones, so match each result by `id`. Inspect `count` (accepted), `failed`, and every item in `results`; a batch can contain successful and failed items together.
## Optional: wait for processing to finish

View file

@ -49,7 +49,9 @@ Retrieve paginated documents with filtering. One `list` call serves documents, c
"id": "doc_abc123",
"title": "Meeting notes",
"type": "text",
"summary": "Team sync covering the Q3 roadmap",
"metadata": { "source": "slack" },
"url": null,
"system": {
"status": "done",
"dreamingStatus": "done",
@ -73,16 +75,17 @@ Every response contains `documents`, `chunks`, `memories`, and `pagination`. Onl
### Parameters
`namespace` and `type` are required. Pagination and sorting are query parameters (top-level keys in the SDK); `filter` goes in `body`.
`namespace` and `type` are required. Over HTTP, pagination and sorting are query parameters and `filter` and `include` go in the JSON body; the SDK takes them all in one options object after `namespace` and `type`. Unknown query or body keys return `400`.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `type` | string | required | `documents`, `chunks`, or `memories` |
| `limit` | number | 10 | Items per page |
| `limit` | number | 10 | Items per page (maximum 100) |
| `page` | number | 1 | Page number |
| `sort` | string | `createdAt` | Sort by `createdAt`, `updatedAt`, or `position` |
| `sort` | string | `createdAt` | `createdAt` or `updatedAt` for documents and memories; `createdAt` or `position` for chunks |
| `order` | string | `desc` | `desc` (newest) or `asc` (oldest) |
| `body.filter` | object | — | Metadata filter. See [Organizing & Filtering](/concepts/filtering) |
| `body.include.forgotten` | boolean | `false` | Memories only: include forgotten or expired rows that remain latest, returned with `isForgotten: true`. Normal forgetting makes a memory non-latest, so it still will not appear in this list |
<Accordion title="Pagination example">
```typescript
@ -133,8 +136,7 @@ Get a specific document with its processing status. Pass `include` to include it
include: ["chunks", "memories"], // optional
});
console.log(doc.system.status); // "queued" | "processing" | "done" | "failed"
console.log(doc.system.dreamingStatus); // "dreaming" | "done"
console.log(doc.system.status); // "queued" | "extracting" | ... | "done" | "failed"
console.log(doc.content);
```
</Tab>
@ -146,8 +148,7 @@ Get a specific document with its processing status. Pass `include` to include it
include=["chunks", "memories"], # optional
)
print(doc.system.status) # "queued" | "processing" | "done" | "failed"
print(doc.system.dreaming_status) # "dreaming" | "done"
print(doc.system.status) # "queued" | "extracting" | ... | "done" | "failed"
print(doc.content)
```
</Tab>
@ -161,6 +162,10 @@ Get a specific document with its processing status. Pass `include` to include it
The `id` may be the Supermemory document ID or the `id` you supplied at ingestion. It resolves only inside the namespace in the path.
<Note>
The current HTTP response also includes `system.dreamingStatus`. TypeScript SDK 5.0.1 and Python SDK 5.0.0 do not expose that field in their generated models; Python's `system.dreaming_status` is not available. Use the raw HTTP response when monitoring memory generation with these versions, or upgrade the TypeScript SDK to 5.0.2 for typed `system.dreamingStatus`. `system.status: "done"` alone does not mean memories are ready.
</Note>
### Processing status
| Status | Description |
@ -172,6 +177,8 @@ The `id` may be the Supermemory document ID or the `id` you supplied at ingestio
| `done` | Ready for search |
| `failed` | Processing failed |
Treat any status other than `done` or `failed` as still in progress.
### Memory generation status
`system.dreamingStatus` tracks memory generation separately from `system.status`.
@ -202,7 +209,7 @@ With the default `dreaming: "dynamic"`, Supermemory batches related documents be
## Update document
Update a document's content or metadata. **Content changes** trigger full reprocessing; **metadata-only changes** (e.g. updating `accepted`, `version`) do not reindex. The body accepts any non-empty subset of `content`, `metadata`, `supportingContext`, `group`, or `date`.
Update a document's content or metadata. **Content changes** trigger full reprocessing; **metadata-only changes** (e.g. updating `accepted`, `version`) do not reindex. The body accepts any non-empty subset of `content`, `metadata`, `supportingContext`, or `date`. Metadata merges key by key. `group` is an ingestion-side setting: it picks which existing memories serve as context while content is processed, so changing it only takes effect when the document is re-ingested. Send it together with `content`.
<Tabs>
<Tab title="TypeScript">
@ -291,7 +298,7 @@ Permanently remove documents. One call deletes 1 to 100 documents by Supermemory
</Tab>
</Tabs>
Inspect both `count` and per-ID `errors`; HTTP success can include partial failures.
Inspect both `count` and per-ID `errors`; HTTP success can include partial failures. Only documents whose `system.status` is `done` or `failed` can be deleted; a document that is still processing is reported in `errors` as `Document is still processing`. Memories derived from a deleted document are forgotten.
<Warning>
Deletes are permanent — no recovery.
@ -301,7 +308,7 @@ Deletes are permanent — no recovery.
## Processing queue
There is no separate processing endpoint. List documents and read `system.status` and `system.dreamingStatus` on each item.
There is no separate processing endpoint. List documents and read `system.status` and `system.dreamingStatus` on each item in the HTTP response. The SDK examples below count documents still being indexed; use raw HTTP for memory-generation status with the SDK versions noted above.
<Tabs>
<Tab title="TypeScript">
@ -310,16 +317,14 @@ There is no separate processing endpoint. List documents and read `system.status
limit: 100,
});
const processing = documents.filter(d => d.system.status !== "done" && d.system.status !== "failed");
const dreaming = documents.filter(d => d.system.dreamingStatus === "dreaming");
console.log(`${processing.length} documents processing, ${dreaming.length} forming memories`);
console.log(`${processing.length} documents processing`);
```
</Tab>
<Tab title="Python">
```python
page = client.list("user_123", "documents", limit=100)
processing = [d for d in page.documents if d.system.status not in ("done", "failed")]
dreaming = [d for d in page.documents if d.system.dreaming_status == "dreaming"]
print(f"{len(processing)} documents processing, {len(dreaming)} forming memories")
print(f"{len(processing)} documents processing")
```
</Tab>
<Tab title="cURL">

View file

@ -29,13 +29,14 @@ v5 has no direct memory-create route. Ingest a document instead and Supermemory
</Tab>
<Tab title="cURL">
```bash
curl -X POST "https://api.supermemory.ai/ns/user_123/document?dreaming=instant" \
curl -X POST "https://api.supermemory.ai/ns/user_123/document" \
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "John prefers dark mode.\nJohn is from Seattle.",
"id": "prefs_john",
"metadata": { "source": "user_preference" }
"metadata": { "source": "user_preference" },
"dreaming": "instant"
}'
```
</Tab>
@ -88,7 +89,7 @@ Soft-delete memories by ID. Forgotten memories are excluded from search results
|-------|------|-------------|
| `count` | number | Number of memories forgotten; always equals `matches.length` |
| `matches` | array | The memories that were forgotten (`{ id, memory }`) |
| `errors` | array | IDs that were missing or not eligible (`{ id, error }`) |
| `errors` | array | IDs that were missing, already forgotten, or in another namespace (`{ id, error }`) |
HTTP success does not imply every requested ID changed. Check `errors`.
@ -99,7 +100,7 @@ HTTP success does not imply every requested ID changed. Check `errors`.
Forget by meaning. Give a `query` (a prompt or topic) and the service semantically searches the namespace, decides which memories are genuinely about your target, and soft-deletes those — use this for "forget everything about X".
<Warning>
This is a bulk, destructive operation. `dryRun` is required. Call with **`dryRun: true`** first to review what would be forgotten, then apply. The match is semantic, so a too-broad query can select more than you intend.
This is a bulk, destructive operation. `dryRun` is required. Call with **`dryRun: true`** first to review what would be forgotten, then apply. The match is semantic, so a too-broad query can select more than you intend. Each request selects at most 100 memories. After applying a batch, repeat the preview-and-apply workflow to find more; repeated previews alone do not paginate and may return the same matches.
</Warning>
<Tabs>
@ -144,7 +145,7 @@ This is a bulk, destructive operation. `dryRun` is required. Call with **`dryRun
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Namespace to scope the operation to (URL path) |
| `query` | string | yes | What to forget — a natural-language instruction ("forget everything about Project Titan") or a bare topic ("Project Titan") |
| `query` | string | yes | What to forget — a natural-language instruction ("forget everything about Project Titan") or a bare topic ("Project Titan"). 1 to 2000 characters |
| `dryRun` | boolean | yes | `true` returns what *would* be forgotten without changing anything. `false` forgets the memories selected when that request runs |
### Response
@ -161,7 +162,7 @@ Both dry-run and applied requests return the same shape as [Forget Memories](#fo
}
```
The payload does not say which mode was sent, so keep your own record of `dryRun` next to audit logs.
`errors` is always empty for semantic requests. The payload does not say which mode was sent, so keep your own record of `dryRun` next to audit logs.
<Tip>
**Exact, bound deletes.** Re-running `forgetMatching` with `dryRun: false` re-runs the semantic match, so the result can drift from the preview if the namespace changed in between. To forget *precisely* what you reviewed, take the `id`s from the `dryRun` preview and send them to `memories.forget` — the delete is then bound to exactly that set.

View file

@ -31,7 +31,7 @@ GET /ns/{namespace}/memories/{id}?include=related,documents&relatedLimit=10
Returns one memory with `id`, `memory`, `metadata`, `isStatic`, `isInference`, `isLatest`, `isForgotten`, `version`, and `system.createdAt/updatedAt`. A memory from another namespace returns `404`; a forgotten memory, or one past its `forget_after`, is still returned with `isForgotten: true`.
- `include=related` adds `included.related.parents` (earlier versions), `children` (newer versions), and `siblings` (memories connected by `extends` or `derives`). Each list walks outward from the memory until it holds `relatedLimit` items (default `10`, maximum `100`). Forgotten memories and memories in other namespaces are left out.
- `include=related` adds `included.related.parents` (earlier versions), `children` (newer versions), and `siblings` (memories directly connected by `extends` or `derives`). Parents and children reach up to three versions away, nearest first. Each list holds at most `relatedLimit` items (default `10`, maximum `100`). Forgotten memories and memories in other namespaces are left out.
- `include=documents` adds `included.document`, the most recently updated source document. With both values, every related memory also carries its own `document`.
### List documents, chunks, or memories
@ -48,9 +48,9 @@ POST /ns/{namespace}/list/{type}?page=1&limit=100&sort=createdAt&order=desc
```
</CodeGroup>
Set `type` to `documents`, `chunks`, or `memories`. Pagination and sorting move to the query string as plain integers and values; the body takes an optional `filter` and, for memories, `include`. Defaults are `page=1`, `limit=10` (maximum 100), `sort=createdAt`, and `order=desc`.
Set `type` to `documents`, `chunks`, or `memories`. Pagination and sorting move to the query string as plain integers and values; the body takes an optional `filter` and, for memories, `include`. Defaults are `page=1`, `limit=10` (maximum 100), `sort=createdAt`, and `order=desc`. `sort` accepts `createdAt` or `updatedAt` for documents and memories, and `createdAt` or `position` for chunks; any other combination returns `400`.
Memory lists hide forgotten memories and memories past their `forget_after`. Send `"include": {"forgotten": true}` to list them too; they come back with `isForgotten: true`. Document memories (`include=memories` on `GET /ns/{namespace}/document/{id}`) report the same flag.
Memory lists return only the latest version of each memory and hide forgotten memories and memories past their `forget_after`. Sending `"include": {"forgotten": true}` admits forgotten or expired rows only if they remain latest; they come back with `isForgotten: true`. Normal forgetting makes a memory non-latest, so this list does not recover it even with that flag. To search such memories, use search with `include.forgotten`. Document memories (`include=memories` on `GET /ns/{namespace}/document/{id}`) report the same forgotten flag.
Every response contains `documents`, `chunks`, `memories`, and `pagination`. Only the selected resource array is populated. Replace legacy `memories` assumptions in document-list callers with `documents`.
@ -68,7 +68,7 @@ DELETE /ns/{namespace}/document
```
</CodeGroup>
The v5 array accepts 1–100 Supermemory or caller-defined IDs. Inspect both `count` and per-ID `errors`; HTTP success can include partial failures.
The v5 array accepts 1–100 Supermemory or caller-defined IDs. Inspect both `count` and per-ID `errors`; HTTP success can include partial failures. Only documents whose `system.status` is `done` or `failed` are deleted; one that is still processing comes back in `errors` as `Document is still processing`.
### With the SDK

View file

@ -6,7 +6,7 @@ v5 makes the difference between adding new information and replacing the canonic
| --- | --- | --- |
| Add information to a stable caller ID | `POST /ns/{namespace}/document` | Append/diff |
| Replace text or URL content | `PATCH /ns/{namespace}/document/{id}` | Replace and reprocess |
| Update only supporting fields | Same `PATCH` without `content` | Canonical content unchanged |
| Update only metadata, context, or date | Same `PATCH` without `content` | Canonical content unchanged |
| Replace a source file and its user metadata | `POST /ns/{namespace}/document/file/{id}` | Full replacement and reprocess |
| Partially update a file or its supporting fields | `PATCH /ns/{namespace}/document/file/{id}` | Omitted fields remain unchanged |
@ -24,7 +24,7 @@ PATCH /ns/user_1/document/doc_1
```
</CodeGroup>
The v5 body accepts any non-empty subset of `content`, `supportingContext`, `metadata`, `group`, or `date`, plus optional `taskType` and `dreaming` (which alone do not count as a change). Supplying `content` makes it the new canonical source; facts supported only by the previous source can disappear after reprocessing.
The v5 body accepts any non-empty subset of `content`, `supportingContext`, `metadata`, or `date`, plus optional `taskType` and `dreaming` (which alone do not count as a change). `group` is an ingestion-side setting: it picks which existing memories serve as context while content is processed, so changing it only takes effect when the document is re-ingested. Send it together with `content`. Supplying `content` makes it the new canonical source; facts supported only by the previous source can disappear after reprocessing.
### Replace a file-backed document
@ -37,7 +37,7 @@ metadata={"revision":2}
dreaming=dynamic
```
POST requires `file` and replaces the canonical source plus user-controlled metadata, grouping, context, and date. Omitted supporting fields are cleared. Use it when the submitted request is the complete new representation of the file-backed document.
POST requires `file` and replaces the canonical source plus caller metadata, including `date`. Omitted metadata and date are cleared. `supportingContext` is stored on the namespace, so omitting it leaves the namespace's existing context unchanged. Use it when the submitted request is the complete new representation of the file-backed document.
### Partially update a file-backed document
@ -49,7 +49,7 @@ metadata={"reviewed":true}
dreaming=dynamic
```
PATCH changes only supplied fields. Include `file` to replace the source while retaining omitted supporting fields, or omit `file` for metadata-, group-, context-, or date-only changes. `metadata` and `group` are JSON-encoded strings; `supportingContext` and `date` are plain strings.
PATCH changes only supplied fields. Include `file` to replace the source while retaining omitted supporting fields, or omit `file` for metadata-, context-, or date-only changes. Like the JSON update, `group` only takes effect when the file is re-ingested, so send it together with `file`. `metadata` and `group` are JSON-encoded strings; `supportingContext` and `date` are plain strings.
<Warning>
There is no public v5 `PUT /ns/{namespace}/document/file/{id}` operation. Use POST for a complete replacement and PATCH for a partial update.
@ -90,7 +90,7 @@ The path `id` may be the Supermemory document ID or your caller-defined ID. It i
### Processing and conflicts
Content or file replacement is accepted before downstream processing completes. A document still processing, a namespace conflict, or a conflicting internal file path can return `409`; retry only after the conflicting operation reaches a terminal state.
Content or file replacement is accepted before downstream processing completes. A namespace merge in progress or a conflicting internal file path returns `409`; retry a merge conflict after the merge finishes.
### Verification

View file

@ -16,7 +16,7 @@ Content-Type: application/json
{"ids":["mem_1","mem_2"]}
```
Send 1–500 IDs. The response reports successful IDs in `matches` and missing or ineligible IDs in `errors`, so HTTP success does not imply every requested ID changed.
Send 1–500 IDs. The response reports successful IDs in `matches` and missing, already forgotten, or out-of-namespace IDs in `errors`, so HTTP success does not imply every requested ID changed.
### Preview a semantic request
@ -27,7 +27,7 @@ Content-Type: application/json
{"query":"outdated home address","dryRun":true}
```
`dryRun: true` performs selection without changing memory state. `dryRun: false` forgets the memories selected when that request executes.
`dryRun: true` performs selection without changing memory state. `dryRun: false` forgets the memories selected when that request executes. `query` is 1–2000 characters, and each request selects at most 100 memories. After applying a batch, repeat the preview-and-apply workflow to find more; repeated previews alone do not paginate and may return the same matches.
### Avoid selection drift
@ -53,7 +53,7 @@ Use this workflow when a human or policy must approve the exact set. Re-running
}
```
`count` always equals `matches.length`. Both dry-run and applied semantic requests use this shape; the payload alone does not replace your record of which mode was sent.
`count` always equals `matches.length`. Semantic requests always return an empty `errors` array. Both dry-run and applied semantic requests use this shape; the payload alone does not replace your record of which mode was sent.
### With the SDK

View file

@ -41,4 +41,4 @@ curl -X POST "https://api.supermemory.ai/ns/user_1/list/documents?page=1&limit=5
```
</CodeGroup>
Semantic forgetting supports `dryRun: true`, so you can review matches before deleting them. See [document read migration](/migration/api-v5-document-reads) and [memory migration](/migration/api-v5-recall).
Semantic forgetting supports `dryRun: true`, so you can review matches before deleting them. See [document read migration](/migration/api-v5-document-reads) and [memory forgetting migration](/migration/api-v5-memory-forgetting).

View file

@ -27,10 +27,10 @@ const { id, status } = await supermemory.add("user_1", {
```
```bash curl
curl -X POST "https://api.supermemory.ai/ns/user_1/document?dreaming=instant" \
curl -X POST "https://api.supermemory.ai/ns/user_1/document" \
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content":"The user prefers concise project updates","id":"conv_1","metadata":{"source":"chat"}}'
-d '{"content":"The user prefers concise project updates","id":"conv_1","metadata":{"source":"chat"},"dreaming":"instant"}'
```
</CodeGroup>