From 2197c04ac12184d56e172f6441f89c12d6bc17c7 Mon Sep 17 00:00:00 2001 From: sohamd22 <85427822+sohamd22@users.noreply.github.com> Date: Thu, 15 Oct 2026 18:52:41 +0000 Subject: [PATCH] docs(api): fix namespace move, scoped keys and SDK call shape in v5 docs (#1811) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes namespace, auth and SDK-shape docs. - **Namespace move example deleted instead.** It sent `moveTo` in a JSON body on `DELETE /ns/{namespace}`. The route only reads `moveTo` from the query string and ignores the body, so following the docs permanently deleted the namespace. It now uses `?moveTo=`, and the overview warns about this. - **SDK call shape.** URL values are positional (`namespace` first), followed by one options object; the docs described one object with `body`. Python 5.0.0 is the v5 client, so "no v5 Python SDK" is gone. - **Scoped keys** (`authentication.mdx`): - The allowed-endpoints list now includes the `/ns/*` routes; all legacy routes are kept. - `containerTags` (several namespaces) is documented. - Namespace names don't allow dots. - **Key permissions.** Read/write applies to the whole key; only restricted members have per-namespace permissions. - **Smaller fixes:** - The move response has no `success` field. - `namespaceCount` only matches the namespace list for an unrestricted key. - `setup --json` does nothing. - The agent prompt's ban on `memories.*` now covers only the calls v5 removed. 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) --- apps/docs/agents-and-mcp.mdx | 3 +-- apps/docs/authentication.mdx | 16 +++++++++++----- apps/docs/concepts/container-tags.mdx | 18 +++++++++--------- apps/docs/snippets/api-v5-organization.mdx | 2 +- apps/docs/snippets/api-v5-overview.mdx | 4 ++-- apps/docs/snippets/api-v5-sdks.mdx | 2 +- apps/docs/v5/api-reference/overview.mdx | 2 +- 7 files changed, 26 insertions(+), 21 deletions(-) diff --git a/apps/docs/agents-and-mcp.mdx b/apps/docs/agents-and-mcp.mdx index 4a1a4290..13f3f78d 100644 --- a/apps/docs/agents-and-mcp.mdx +++ b/apps/docs/agents-and-mcp.mdx @@ -28,7 +28,6 @@ Useful for coding agents: ```bash npx supermemory setup # detect project, launch/print integration flow npx supermemory setup --prompt # print integration prompt only -npx supermemory setup --json # machine-readable output npx supermemory help --json # agent-readable command catalog npx supermemory help --all npx supermemory migrate # move a v3/v4 project to v5 with your agent @@ -210,7 +209,7 @@ DO NOT USE — deprecated, undocumented, or fabricated: - Endpoints: /v1/anything, /v3/documents, /v3/search, /v4/search, /v4/profile, /v4/memories (use /ns/{namespace}/...) - Headers: x-supermemory-api-key, x-api-key, x-sm-user-id (for API auth) - Body keys: containerTag, containerTags, customId (use `id`), entityContext (use `supportingContext`), filterByMetadata (use `group`), documentDate (use `date`), q (use `query`), filters (use `filter`), userId, spaces -- SDK: `client.add({ containerTag })`, `client.search.execute`, `client.memories.*`, `client.profile({ q })` +- SDK: `client.add({ containerTag })`, `client.search.execute`, `client.memories.add` / `client.memories.updateMemory`, `client.profile({ q })` SCOPING IS LOAD-BEARING. Every write and every search MUST name one namespace in the path. diff --git a/apps/docs/authentication.mdx b/apps/docs/authentication.mdx index 9c90b9c6..70315a74 100644 --- a/apps/docs/authentication.mdx +++ b/apps/docs/authentication.mdx @@ -50,11 +50,15 @@ This works for Google Drive, Notion, and OneDrive. See the full setup in [Custom ## Scoped API keys -Scoped keys are restricted to one namespace (what v3/v4 called a container tag). They can only access documents and search within that namespace — use them to give a client, session, or tenant limited access without shipping your org master key. +Scoped keys are restricted to one namespace (what v3/v4 called a container tag), or to a fixed list of namespaces. They can read and write content only inside those namespaces, subject to the key's read/write permission and member restrictions — use them to give a client, session, or tenant limited access without shipping your org master key. + + +Namespace scoping is not read-only access. Writable scoped keys can update and delete documents and forget memories. Deleting or moving a namespace additionally requires an org admin or owner with write access to the source and, for moves, the destination. + Pairs with [namespaces](/concepts/container-tags) for multi-tenant isolation. -**Allowed endpoints:** `/v3/documents`, `/v3/memories`, `/v4/memories`, `/v3/search`, `/v4/search`, `/v4/profile` +**Allowed endpoints:** `/ns/{namespace}/document`, `/ns/{namespace}/list`, `/ns/{namespace}/search`, `/ns/{namespace}/profile`, and `/ns/{namespace}/memories`; `/namespaces` and `/ns/{namespace}`; and the legacy `/v3/documents`, `/v3/memories`, `/v4/memories`, `/v4/conversations`, `/v3/search`, `/v4/search`, `/v4/profile`, `/v3/container-tags/list`, and `/v3/session` routes. Any other route returns `403`. Scoped keys **cannot** read billing, manage org settings, or mint further keys. @@ -78,7 +82,8 @@ curl https://api.supermemory.ai/v3/auth/scoped-key \ | Parameter | Required | Default | Description | | --- | --- | --- | --- | -| `containerTag` | Yes | — | The namespace to scope the key to. Alphanumeric, hyphens, underscores, colons, dots | +| `containerTag` | Yes, unless `containerTags` is set | — | The namespace to scope the key to. Up to 100 characters: letters, numbers, hyphens, underscores, colons | +| `containerTags` | No | — | Scope the key to several namespaces instead of one. Takes precedence over `containerTag` | | `name` | No | `scoped_{containerTag}` | Display name for the key | | `expiresInDays` | No | — | 1–365 days | | `rateLimitMax` | No | `500` | Max requests per window (1–10,000) | @@ -92,8 +97,9 @@ curl https://api.supermemory.ai/v3/auth/scoped-key \ "id": "key-id", "name": "scoped_my-project", "containerTag": "my-project", + "containerTags": ["my-project"], "expiresAt": "2026-03-08T00:00:00.000Z", - "allowedEndpoints": ["/v3/documents", "/v3/memories", "/v4/memories", "/v3/search", "/v4/search", "/v4/profile"] + "allowedEndpoints": ["/v3/session", "/v3/documents", "/v3/memories", "/v4/memories", "/v4/conversations", "/ns/*/memories", "/v3/search", "/v4/search", "/v4/profile", "/v3/container-tags/list", "/ns/*/document", "/ns/*/list", "/ns/*/search", "/ns/*/profile", "/namespaces$", "/ns$", "/ns/*$"] } ``` @@ -111,4 +117,4 @@ curl https://api.supermemory.ai/v3/auth/scoped-key/KEY_ID \ ```json { "success": true } -``` \ No newline at end of file +``` diff --git a/apps/docs/concepts/container-tags.mdx b/apps/docs/concepts/container-tags.mdx index f555cbd8..e5e3cf72 100644 --- a/apps/docs/concepts/container-tags.mdx +++ b/apps/docs/concepts/container-tags.mdx @@ -97,7 +97,7 @@ The colon is intentionally allowed so you can build **hierarchical** namespaces ## Scope lives in the URL -In v5 the namespace is a path segment, not a body field. Every scoped endpoint starts with `/ns/{namespace}/`, and every SDK call takes `namespace` as a top-level key next to `body`. +In v5 the namespace is a path segment, not a body field. Every scoped endpoint starts with `/ns/{namespace}/`, and every scoped SDK call takes `namespace` as its first argument. | Legacy (v3/v4) | v5 | |-----------|------| @@ -138,8 +138,8 @@ await supermemory.list("project_q1", "documents"); Namespaces are also an **authorization boundary**, not just an organizational one. Two mechanisms can restrict which namespaces a given caller may touch: -- **API key scopes** — an API key can be limited to a specific set of namespaces, with read or write permission per namespace. -- **Member restrictions** — an organization member can be granted access to only certain namespaces. +- **API key scopes** — an API key can be limited to a specific set of namespaces, and a key can be read-only. +- **Member restrictions** — an organization member can be granted access to only certain namespaces, with read or write permission per namespace. When a request is restricted, Supermemory validates the namespace in the URL against the caller's allowed set: @@ -159,11 +159,13 @@ The `namespaces.*` SDK methods read and change a namespace itself, as opposed to | `supermemory.namespaces.list()` | Page through namespaces with `documentCount` and `memoryCount`. | | `supermemory.namespaces.get(namespace)` | Read one namespace and its `supportingContext`. | | `supermemory.namespaces.update(namespace, { supportingContext })` | Set a context prompt applied when processing documents in this namespace. Useful for steering extraction per project or tenant. | -| `supermemory.namespaces.delete(namespace)` | Delete the namespace and all its documents and memories. | +| `supermemory.namespaces.delete(namespace)` | Delete the namespace, its namespace-owned memory records, and documents exclusive to it. Shared documents are retained. | | `supermemory.namespaces.delete(namespace, { moveTo })` | Move the content into another namespace, then remove this one. Queued; returns an `operationId`. | `supportingContext` is what v3/v4 called `entityContext`. The legacy "merge" operation is now a delete with `moveTo`, one source namespace per request. +Namespace deletion and moves require an org admin or owner with write access to the source namespace; moves also require write access to the destination. The default `sm_project_default` namespace cannot be permanently deleted. See [deletion scope and erasure limits](/overview/security). + ```typescript TypeScript @@ -178,7 +180,7 @@ const { namespaces, pagination } = await supermemory.namespaces.list(); await supermemory.namespaces.delete("project_research_old", { moveTo: "project_research", }); -// { success, status: "queued", operationId, namespace, moveTo } +// { status: "queued", operationId, namespace, moveTo } ``` ```bash curl @@ -190,10 +192,8 @@ curl -X PATCH "https://api.supermemory.ai/ns/project_research" \ curl "https://api.supermemory.ai/namespaces" \ -H "Authorization: Bearer $SUPERMEMORY_API_KEY" -curl -X DELETE "https://api.supermemory.ai/ns/project_research_old" \ - -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ "moveTo": "project_research" }' +curl -X DELETE "https://api.supermemory.ai/ns/project_research_old?moveTo=project_research" \ + -H "Authorization: Bearer $SUPERMEMORY_API_KEY" ``` diff --git a/apps/docs/snippets/api-v5-organization.mdx b/apps/docs/snippets/api-v5-organization.mdx index 765073bb..608a2050 100644 --- a/apps/docs/snippets/api-v5-organization.mdx +++ b/apps/docs/snippets/api-v5-organization.mdx @@ -69,6 +69,6 @@ await supermemory.organization.update({ - Compare the v5 context with the legacy `filterPrompt` before cutover. - Set, replace, and clear organizational context. -- Confirm `namespaceCount` agrees with `pagination.totalItems` from `GET /namespaces` for the same credentials. +- Confirm `namespaceCount` agrees with `pagination.totalItems` from `GET /namespaces` when called with an unrestricted org key. `namespaceCount` always counts every namespace in the organization, while `GET /namespaces` only counts the namespaces the caller can read. - Verify non-admin callers receive `403` on PATCH. - Confirm removed fields are not required by downstream configuration code. diff --git a/apps/docs/snippets/api-v5-overview.mdx b/apps/docs/snippets/api-v5-overview.mdx index fbea7e63..a63c3709 100644 --- a/apps/docs/snippets/api-v5-overview.mdx +++ b/apps/docs/snippets/api-v5-overview.mdx @@ -6,7 +6,7 @@ The API base URL and bearer keys do not change. -**Where parameters live:** `GET` options go in the query string. `POST`, `PATCH`, and `PUT` options go in the JSON body, or as form fields on file uploads; the one exception is list pagination (`page`, `limit`, `sort`, `order`), which stays in the query string. `DELETE` options such as `moveTo` go in the query string, while bulk deletes send their `ids` in the JSON body. Routes reject options sent in the wrong place with `400`. v5 application routes are unversioned; [`/v5/reference`](https://api.supermemory.ai/v5/reference) is the interactive v5 reference, not an API path prefix. +**Where parameters live:** `GET` options go in the query string. `POST`, `PATCH`, and `PUT` options go in the JSON body, or as form fields on file uploads; the one exception is list pagination (`page`, `limit`, `sort`, `order`), which stays in the query string. `DELETE` options such as `moveTo` go in the query string, while bulk deletes send their `ids` in the JSON body. Most routes reject options sent in the wrong place with `400`. `DELETE /ns/{namespace}` does not: it ignores a JSON body, so a `moveTo` sent in the body permanently deletes the namespace instead of moving it. v5 application routes are unversioned; [`/v5/reference`](https://api.supermemory.ai/v5/reference) is the interactive v5 reference, not an API path prefix. ## Recommended migration process @@ -55,7 +55,7 @@ await supermemory.add("user_1", { content: "new turn" }) ``` -Every v5 call takes one object. `namespace`, path IDs, and query parameters are top-level keys; the JSON body goes under `body`. Legacy `containerTag` never appears in a body again. There is no v5 Python SDK yet. +URL values are positional (`namespace` first, then `id` where there is one); everything else goes in one object. Legacy `containerTag` never appears in a body again. The Python SDK speaks v5 from 5.0.0 with the same shape and keyword arguments: `client.add("user_1", content="new turn")`. ## Endpoint map diff --git a/apps/docs/snippets/api-v5-sdks.mdx b/apps/docs/snippets/api-v5-sdks.mdx index 1a2ae281..80dd71b3 100644 --- a/apps/docs/snippets/api-v5-sdks.mdx +++ b/apps/docs/snippets/api-v5-sdks.mdx @@ -1,4 +1,4 @@ -Check which client you call the API through before you translate requests. Both official SDKs speak v5; the integration packages do not yet. +Check which client you call the API through before you translate requests. Both official SDKs and `@supermemory/tools` 3.x speak v5; check the table before upgrading anything else. | Client | v5 support | What to do | | --- | --- | --- | diff --git a/apps/docs/v5/api-reference/overview.mdx b/apps/docs/v5/api-reference/overview.mdx index bd6b9bee..981df7f6 100644 --- a/apps/docs/v5/api-reference/overview.mdx +++ b/apps/docs/v5/api-reference/overview.mdx @@ -36,7 +36,7 @@ import { Supermemory } from "supermemory" const supermemory = new Supermemory({ apiKey: process.env.SUPERMEMORY_API_KEY }) ``` -Every SDK call takes one object. `namespace`, path IDs, and query parameters are top-level keys; the JSON body goes under `body`. Each reference page below shows the SDK call next to the equivalent `curl`. There is no v5 Python SDK yet. +URL values are positional arguments (`namespace` first, then `id` where there is one), and everything else goes in one object: `supermemory.add("user_123", { content })`. Each reference page below shows the SDK call next to the equivalent `curl`. The Python SDK (`pip install supermemory`, 5.0.0 and later) follows the same shape with keyword arguments: `client.add("user_123", content="...")`.