## Migrate by hand
This is a breaking API migration. Do not change only the URL: fields moved, search defaults changed, response envelopes changed, and some legacy operations have no v5 replacement.
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. 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
Search for `/v3/`, `/v4/`, `containerTag`, `containerTags`, `customId`, `entityContext`, `filterByMetadata`, `filters`, and legacy SDK methods such as `client.search.execute`, `client.profile`, and `client.connections.*`.
Move the legacy `containerTag` into `/ns/{namespace}`. Never infer scope from a document or memory ID, and never send multiple namespaces to one v5 request.
Apply [ingestion](/migration/api-v5-document-writes), [updates](/migration/api-v5-document-updates), [content management](/migration/api-v5-document-reads), [search](/migration/api-v5-recall), [profiles](/migration/api-v5-profiles), [forgetting](/migration/api-v5-memory-forgetting), [namespaces](/migration/api-v5-settings), [organization](/migration/api-v5-organization), and [filter](/migration/api-v5-filters) changes independently.
Migrate envelopes, includes, pagination, profile buckets, system fields, and partial-error handling before switching traffic.
Follow the [verification and rollout guide](/migration/api-v5-rollout). Compare identity and behavior—not raw JSON ordering—and set changed defaults explicitly during rollout.
Switch traffic, monitor failures and semantic drift, then remove legacy compatibility code only after that domain passes verification.
## Upgrade the SDK
The v5 TypeScript SDK ships as the same `supermemory` package. Install it, then replace the legacy client:
```bash
npm i supermemory
```
```ts Legacy
import Supermemory from "supermemory"
const client = new Supermemory({ apiKey: process.env.SUPERMEMORY_API_KEY })
await client.add({ content: "new turn", containerTag: "user_1" })
```
```ts v5
import { Supermemory } from "supermemory"
const supermemory = new Supermemory({ apiKey: process.env.SUPERMEMORY_API_KEY })
await supermemory.add("user_1", { content: "new turn" })
```
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
| Legacy | v5 | SDK method |
| --- | --- | --- |
| `POST /v3/documents` | `POST /ns/{namespace}/document` | `supermemory.add` |
| `POST /v3/documents/batch` | `POST /ns/{namespace}/document/batch` | `supermemory.documents.batchAdd` |
| `POST /v3/documents/file` | `POST /ns/{namespace}/document/file` | `supermemory.documents.uploadFile` |
| `GET/PATCH /v3/documents/{id}` | `GET/PATCH /ns/{namespace}/document/{id}` | `supermemory.documents.get` / `supermemory.documents.update` |
| File replace or partial file update | `POST/PATCH /ns/{namespace}/document/file/{id}` | `supermemory.documents.replaceWithFile` / `supermemory.documents.updateFile` |
| Single or bulk document delete | `DELETE /ns/{namespace}/document` | `supermemory.documents.delete` |
| Legacy document or memory lists | `POST /ns/{namespace}/list/{type}` | `supermemory.list` |
| `POST /v3/search` or `/v4/search` | `POST /ns/{namespace}/search` | `supermemory.search` |
| `POST /v4/profile` | `POST /ns/{namespace}/profile` | `supermemory.profile` |
| `POST /v4/profile/buckets` | `GET/PUT/DELETE /ns/{namespace}/profile/buckets` | `supermemory.profiles.getBuckets` / `setBuckets` / `deleteBuckets` |
| Legacy memory forget routes | `DELETE /ns/{namespace}/memories...` | `supermemory.memories.forget` / `supermemory.memories.forgetMatching` |
| Container-tag settings and lifecycle | `/namespaces` and `/ns/{namespace}` | `supermemory.namespaces.list` / `get` / `update` / `delete` |
| `GET/PATCH /v3/settings` | `GET/PATCH /organization` | `supermemory.organization.get` / `update` |
### Connectors
Connector routes also move under the namespace. Legacy `containerTags` arrays become one namespace per connector.
| Legacy | v5 | SDK method |
| --- | --- | --- |
| `POST /v3/connections/list` | `GET /ns/{namespace}/connectors` or `GET /connectors` | `supermemory.connectors.list` / `supermemory.connectors.listAll` |
| `POST /v3/connections/{provider}` | `POST /ns/{namespace}/connectors` | `supermemory.connectors.create` |
| `GET /v3/connections/{connectionId}` | `GET /ns/{namespace}/connectors/{id}` | `supermemory.connectors.get` |
| `POST /v3/connections/{connectionId}/configure` | `PATCH /ns/{namespace}/connectors/{id}` | `supermemory.connectors.update` |
| `DELETE /v3/connections/{connectionId}` | `DELETE /ns/{namespace}/connectors/{id}` | `supermemory.connectors.delete` |
| `POST /v3/connections/{provider}/import` | `POST /ns/{namespace}/connectors/{id}/sync` | `supermemory.connectors.sync` |
```ts Legacy
const connection = await client.connections.create("notion", {
containerTags: ["user_1"],
redirectUrl: "https://app.example.com/connected",
})
```
```ts v5
const { id, authorization } = await supermemory.connectors.create("user_1", {
provider: "notion",
redirectUrl: "https://app.example.com/connected"
})
```
`authorization` is `null` for config providers (`web-crawler`, `s3`, `granola`), which start syncing immediately. `connectors.sync` returns `{ id, status: "queued" }` and `409` when a sync is already running.