# Memory stores

Make memory stores, give them to a task, write and read the notes in them, and read every version of a note.

A memory store holds notes that workers read and write from one task to the next. A note is a text at a path, such as `/customers/sam.md`, and every change to a note is kept as a version that says who made it and when. [Memory](/concepts/memory) explains how a task reads its stores, and the dreams that tidy a store up.

A workspace has two kinds of store. A shared store is one you make here, or a person makes in the app. A worker's own store is made when the worker first saves a note, is named after the worker, and holds what the worker remembers by itself. The list shows both. A worker's own store cannot be archived or deleted, and it cannot be given to a task, since every task already reads its worker's own store.

A task reads the stores a person attached to its worker in the app, unless the task is given stores of its own. Name them in the task's `resources`, as `{ "type": "memory_store", "memory_store_id": "memstore_..." }`, with `access` set to `read_write` (the default) or `read_only`, and `instructions` of up to 4,096 characters that tell the worker how to use the store. With any `memory_store` entry, the task reads only the stores named, at most 8, besides its worker's own. A task keeps the name, access and instructions each store had when the task was made, so a later rename does not reach it.

A note holds 0 to 102,400 UTF-8 bytes, and a store holds up to 10,000 notes. A workspace keeps up to 1,000 live shared stores. A worker's own store does not count, and archiving a store frees its place. A note whose text or path holds a saved password is refused. A write to an archived store is refused.

Every change to a note saves a version. Versions are kept for 30 days after they are written. The two newest versions of a note that still exists are always kept, so a note that rarely changes can keep history longer. Versions of a deleted note and redacted versions follow the same rule. To keep history longer, read the versions with this API and keep your own copy. Little Worker running on your own computer keeps every version.

> [!NOTE]
> The words are Claude Managed Agents' words for memory. A note is a `memory`, a folder in a listing is a `memory_prefix`, and a version is a `memory_version`. A change a worker makes in a task is a `task_actor` version. Every note you write with a key is an `api_actor` version, and the key is its author.

## The memory store object

The routes for stores answer a store, or a list of them. The routes for notes answer a note, which has its own fields under [Write a note](#write-a-note), and the routes for versions answer a version, with its fields under [Read a version](#read-a-version). Times are RFC 3339 in UTC, to the millisecond.

- `type` (string): Always `memory_store`.

- `id` (memory store id): The store's id: `memstore_` and 32 hex digits.

- `name` (string): The store's name, 1 to 255 characters.

- `description` (string): What the store is for, up to 1,024 characters. Empty when unset.

- `metadata` (object): Your own labels for the store: up to 16 keys of 1 to 64 characters, each with a string value of up to 512.

- `created_at` (time): When the store was made.

- `updated_at` (time): When the store's name, description or labels last changed, or when it was archived. Writing a note does not move it.

- `archived_at` (time, or null): When the store was archived. `null` while it is not.

```json
{
  "type": "memory_store",
  "id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
  "name": "Customer notes",
  "description": "What customers order and how they like to be reached.",
  "metadata": {
    "team": "sales"
  },
  "created_at": "2026-10-20T09:14:02.331Z",
  "updated_at": "2026-10-20T09:14:02.331Z",
  "archived_at": null
}
```

## Make a memory store

`POST /memory_stores`

Make a shared store. It starts empty. To let a task use it, name it in the task's `resources`. This route ignores `Idempotency-Key`, so a retry after a timeout can make a second store. List the stores and look for yours before you try again.

### Body

- `name` (string, required): The store's name, 1 to 255 characters, with no control characters such as a line break or a tab.
- `description` (string): What the store is for, up to 1,024 characters.
- `metadata` (object): Your own labels: up to 16 keys of 1 to 64 characters, each with a string value of up to 512.

### Returns

`200` and the store.

### Example

```bash
curl "https://core.thelittleworker.com/api/v1/memory_stores" \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19" \
  -H "content-type: application/json" \
  -d '{
  "name": "Customer notes",
  "description": "What customers order and how they like to be reached.",
  "metadata": {
    "team": "sales"
  }
}'
```

```json
{
  "type": "memory_store",
  "id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
  "name": "Customer notes",
  "description": "What customers order and how they like to be reached.",
  "metadata": {
    "team": "sales"
  },
  "created_at": "2026-10-20T09:14:02.331Z",
  "updated_at": "2026-10-20T09:14:02.331Z",
  "archived_at": null
}
```

### Errors

- 400 `invalid_request_error`: A field is missing or not valid (`error_code` `validation_error`), or the workspace already keeps 1,000 live shared stores. `message` says which. Archive or delete a store it no longer needs.
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## List memory stores

`GET /memory_stores`

List the stores in the key's workspace, newest first. Archived stores are left out unless you ask for them.

### Query parameters

- `limit` (integer): How many to answer, 1 to 100. The default is 20.
- `page` (string): The `next_page` of the answer before, to read the next page.
- `order` (string): `desc`, newest first (the default), or `asc`, oldest first. One of `desc`, `asc`.
- `created_at[gt]` (time): Only those made after this time, an RFC 3339 time compared to the millisecond the answer shows. It may end in `Z` or in an offset such as `+02:00`. `created_at[lt]` works the same way. `created_at[gte]` and `created_at[lte]` take a UTC time that ends in `Z`, and an offset is refused.
- `include_archived` (string): `true` lists archived stores too. One of `true`, `false`.

### Returns

A list: `data` holds the stores, and `next_page` is the `page` to send for the next ones (`null` on the last page).

### Example

```bash
curl "https://core.thelittleworker.com/api/v1/memory_stores?limit=10" \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19"
```

```json
{
  "data": [
    {
      "type": "memory_store",
      "id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
      "name": "Customer notes",
      "description": "What customers order and how they like to be reached.",
      "metadata": {
        "team": "sales"
      },
      "created_at": "2026-10-20T09:14:02.331Z",
      "updated_at": "2026-10-20T09:14:02.331Z",
      "archived_at": null
    }
  ],
  "next_page": null
}
```

### Errors

- 400 `invalid_request_error`: A filter is not valid, such as a `limit` outside 1 to 100, an `include_archived` that is not `true` or `false`, or a time that is not an RFC 3339 time (`error_code` `validation_error`). `page` is not a page this list gave (`error_code` `validation_error`, `That cursor is not valid.`), or it was made with another `order` (`That cursor was made with another order. Use the same one, or read the first page again.`).
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## Read a memory store

`GET /memory_stores/{memory_store_id}`

Read one store, archived or not.

### Path parameters

- `memory_store_id` (memory store id, required): The memory store, such as `memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24`.

### Returns

The store.

### Example

```bash
curl https://core.thelittleworker.com/api/v1/memory_stores/memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24 \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19"
```

```json
{
  "type": "memory_store",
  "id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
  "name": "Customer notes",
  "description": "What customers order and how they like to be reached.",
  "metadata": {
    "team": "sales"
  },
  "created_at": "2026-10-20T09:14:02.331Z",
  "updated_at": "2026-10-20T09:14:02.331Z",
  "archived_at": null
}
```

### Errors

- 400 `invalid_request_error`: `memory_store_id` is not a memory store id. `error_code` is `validation_error`.
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 404 `not_found_error`: No memory store in the key's workspace has this id (`Memory store not found.`).
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## Change a memory store

`POST /memory_stores/{memory_store_id}`

Change a store's name, description or labels. A field left out, or sent as `null`, stays as it was. An archived store takes no change.

### Path parameters

- `memory_store_id` (memory store id, required): The memory store, such as `memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24`.

### Body

- `name` (string): A new name, 1 to 255 characters.
- `description` (string): A new description, up to 1,024 characters.
- `metadata` (object): Labels to set on the store. A key with a string value is set, a key set to `null` is removed, and keys left out stay. The request holds at most 16 keys, and at most 16 remain.

### Returns

The store, changed.

### Example

```bash
curl "https://core.thelittleworker.com/api/v1/memory_stores/memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24" \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19" \
  -H "content-type: application/json" \
  -d '{
  "metadata": {
    "region": "west"
  }
}'
```

```json
{
  "type": "memory_store",
  "id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
  "name": "Customer notes",
  "description": "What customers order and how they like to be reached.",
  "metadata": {
    "team": "sales",
    "region": "west"
  },
  "created_at": "2026-10-20T09:14:02.331Z",
  "updated_at": "2026-10-21T08:30:12.507Z",
  "archived_at": null
}
```

### Errors

- 400 `invalid_request_error`: A field is not valid, or the labels would pass 16 (`error_code` `validation_error`). The store is archived and can only be read (`This memory store is archived and can only be read.`).
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 404 `not_found_error`: No memory store in the key's workspace has this id (`Memory store not found.`).
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## Archive a memory store

`POST /memory_stores/{memory_store_id}/archive`

Archive a store so it can only be read. It cannot be undone. Its notes and versions stay, lists leave it out unless you ask for `include_archived=true`, and it no longer counts toward the workspace's 1,000 live shared stores. Archiving a store twice changes nothing. A task that already has the store can still read it.

### Path parameters

- `memory_store_id` (memory store id, required): The memory store, such as `memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24`.

### Returns

The store, with `archived_at` set.

### Example

```bash
curl "https://core.thelittleworker.com/api/v1/memory_stores/memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24/archive" \
  -X POST \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19"
```

```json
{
  "type": "memory_store",
  "id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
  "name": "Customer notes",
  "description": "What customers order and how they like to be reached.",
  "metadata": {
    "team": "sales"
  },
  "created_at": "2026-10-20T09:14:02.331Z",
  "updated_at": "2026-10-25T17:12:03.418Z",
  "archived_at": "2026-10-25T17:12:03.418Z"
}
```

### Errors

- 400 `invalid_request_error`: `memory_store_id` is not a memory store id. `error_code` is `validation_error`.
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 404 `not_found_error`: No memory store in the key's workspace has this id (`Memory store not found.`).
- 409 `conflict_error`: The store is a worker's own (`A worker's own memory cannot be archived.`).
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## Delete a memory store

`DELETE /memory_stores/{memory_store_id}`

Delete a shared store with all its notes and versions, and its place in any worker's stores and in any task or routine that names it. An archived store can be deleted. It cannot be undone.

### Path parameters

- `memory_store_id` (memory store id, required): The memory store, such as `memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24`.

### Returns

`type` is `memory_store_deleted`, with the store's `id`.

### Example

```bash
curl "https://core.thelittleworker.com/api/v1/memory_stores/memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24" \
  -X DELETE \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19"
```

```json
{
  "type": "memory_store_deleted",
  "id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24"
}
```

### Errors

- 400 `invalid_request_error`: `memory_store_id` is not a memory store id. `error_code` is `validation_error`.
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 404 `not_found_error`: No memory store in the key's workspace has this id (`Memory store not found.`).
- 409 `conflict_error`: The store is a worker's own (`A worker's own memory goes when the worker does.`).
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## Write a note

`POST /memory_stores/{memory_store_id}/memories`

Write a new note at a path. The note starts with one `created` version, made by your key. A path that already holds a note is refused, even for the same text. To replace a note, change it. This route ignores `Idempotency-Key`.

### Path parameters

- `memory_store_id` (memory store id, required): The memory store, such as `memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24`.

### Query parameters

- `view` (string): `full` answers the text of the note. `basic`, the default, leaves `content` as `null`. One of `basic`, `full`.

### Body

- `path` (string, required): Where to put the note, such as `/customers/sam.md`: it starts with `/`, is 2 to 1,024 UTF-8 bytes, and has no empty, `.` or `..` part between its slashes. It is kept in Unicode normal form NFC.
- `content` (string, required): The note's text, 0 to 102,400 UTF-8 bytes. Send `""` for an empty note.

### Returns

`200` and the note, with `content` left as `null` unless you send `view=full`. Its `content_sha256` is the hash of the text you sent.

- `type` (string): Always `memory`.
- `id` (note id): The note's id: `mem_` and 32 hex digits.
- `memory_store_id` (memory store id): The store the note is in.
- `memory_version_id` (version id): The note's newest version, which holds the text it has now.
- `path` (string): Where the note is in its store, such as `/customers/sam.md`. A path starts with `/`, is 2 to 1,024 UTF-8 bytes, has no empty, `.` or `..` part between its slashes, and so does not end with `/`. Case matters.
- `content` (string, or null): The note's text. `null` in the basic view. Reading one note answers the text by default. Writing, changing and listing leave it out unless you ask for `view=full`.
- `content_sha256` (string): The SHA-256 of the note's text as UTF-8 bytes, in lowercase hexadecimal. It is the hash of the bytes you sent, so a client can compute it, and it is what `precondition` and `expected_content_sha256` take.
- `content_size_bytes` (integer): The text's size in UTF-8 bytes. A note holds 0 to 102,400.
- `created_at` (time): When the note was made.
- `updated_at` (time): When the note's path or text last changed.

### Example

```bash
curl "https://core.thelittleworker.com/api/v1/memory_stores/memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24/memories" \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19" \
  -H "content-type: application/json" \
  -d '{
  "path": "/customers/sam.md",
  "content": "Sam orders on Fridays and likes a text more than a call."
}'
```

```json
{
  "type": "memory",
  "id": "mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20",
  "memory_store_id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
  "memory_version_id": "memver_1d3f5a7c9e0b4c2d8a6e4f2b0c9d7a35",
  "path": "/customers/sam.md",
  "content": null,
  "content_sha256": "3264f64c28ae4c6a20c3a58ebdfa89735a5aeeff334fb1a7a1f2e815b8b197ba",
  "content_size_bytes": 56,
  "created_at": "2026-10-20T09:20:41.007Z",
  "updated_at": "2026-10-20T09:20:41.007Z"
}
```

### Errors

- 400 `invalid_request_error`: A field is missing or not valid (`error_code` `validation_error`): the path is not a note path, the text is over 102,400 bytes, or the `view` is not `basic` or `full`. The text holds a saved password (`This note contains a saved password. Remove it and try again.`), or so does the path. The store is archived and can only be read (`This memory store is archived and can only be read.`).
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 404 `not_found_error`: No memory store in the key's workspace has this id (`Memory store not found.`).
- 409 `memory_path_conflict_error`: A note is already at the path, at a folder above it, or inside it as a folder (`error_code` `memory_path_conflict`). `/notes` and `/notes/todo.md` cannot both be notes. Choose another path.
- 409 `conflict_error`: The store already holds 10,000 notes. Delete one, or change one that is there.
- 413 `request_too_large`: The request body is over 10 MiB (`error_code` `request_too_large`). A note holds at most 102,400 bytes.
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## List notes

`GET /memory_stores/{memory_store_id}/memories`

List the notes in a store, by path. A listing holds notes and, when you ask for `depth=1`, folders. A folder is a `memory_prefix`, which has only a `type` and a `path` that ends with `/`. It has no id.

Notes come in path order, not newest first, and this list takes no `order` and no `created_at` filter. To see what changed lately, list the versions.

### Path parameters

- `memory_store_id` (memory store id, required): The memory store, such as `memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24`.

### Query parameters

- `path_prefix` (string): The folder to list: `/` (the default), or a path that ends with `/`, such as `/customers/`.
- `depth` (string): `0`, the default, lists every note below the folder. `1` lists only what is directly in it, and shows each folder inside it as one `memory_prefix`. One of `0`, `1`.
- `view` (string): `full` answers the text of the notes. `basic`, the default, leaves `content` as `null`. One of `basic`, `full`.
- `limit` (integer): How many to answer, 1 to 1,000. The default is 100. With `view=full` the most is 20, and the default is 20.
- `page` (string): The `next_page` of the answer before, to read the next page.

### Returns

A list: `data` holds notes and folders, in path order, and `next_page` is the `page` to send for the next ones (`null` on the last page). A note has the fields of [Write a note](#write-a-note).

### Example

```bash
curl "https://core.thelittleworker.com/api/v1/memory_stores/memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24/memories?path_prefix=%2Fcustomers%2F&depth=1" \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19"
```

```json
{
  "data": [
    {
      "type": "memory_prefix",
      "path": "/customers/archive/"
    },
    {
      "type": "memory",
      "id": "mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20",
      "memory_store_id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
      "memory_version_id": "memver_1d3f5a7c9e0b4c2d8a6e4f2b0c9d7a35",
      "path": "/customers/sam.md",
      "content": null,
      "content_sha256": "3264f64c28ae4c6a20c3a58ebdfa89735a5aeeff334fb1a7a1f2e815b8b197ba",
      "content_size_bytes": 56,
      "created_at": "2026-10-20T09:20:41.007Z",
      "updated_at": "2026-10-20T09:20:41.007Z"
    }
  ],
  "next_page": null
}
```

### Errors

- 400 `invalid_request_error`: `path_prefix` is not a folder, `limit` is outside its range, `limit` is over 20 with `view=full`, or `depth` or `view` is not one of its values (`error_code` `validation_error`). `page` is not a page this list gave (`error_code` `validation_error`, `That cursor is not valid.`). Read the first page again.
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 404 `not_found_error`: No memory store in the key's workspace has this id (`Memory store not found.`).
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## Read a note

`GET /memory_stores/{memory_store_id}/memories/{memory_id}`

Read one note. Unlike a listing, a read answers the note's text unless you ask for `view=basic`.

### Path parameters

- `memory_store_id` (memory store id, required): The memory store, such as `memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24`.
- `memory_id` (note id, required): The note, such as `mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20`.

### Query parameters

- `view` (string): `basic` leaves the text of the note out, and `content` is `null`. `full`, the default, answers it. One of `basic`, `full`.

### Returns

The note, as [Write a note](#write-a-note) shows it.

### Example

```bash
curl https://core.thelittleworker.com/api/v1/memory_stores/memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24/memories/mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20 \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19"
```

```json
{
  "type": "memory",
  "id": "mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20",
  "memory_store_id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
  "memory_version_id": "memver_1d3f5a7c9e0b4c2d8a6e4f2b0c9d7a35",
  "path": "/customers/sam.md",
  "content": "Sam orders on Fridays and likes a text more than a call.",
  "content_sha256": "3264f64c28ae4c6a20c3a58ebdfa89735a5aeeff334fb1a7a1f2e815b8b197ba",
  "content_size_bytes": 56,
  "created_at": "2026-10-20T09:20:41.007Z",
  "updated_at": "2026-10-20T09:20:41.007Z"
}
```

### Errors

- 400 `invalid_request_error`: An id is not of its kind, or `view` is not `basic` or `full` (`error_code` `validation_error`).
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 404 `not_found_error`: The workspace has no memory store with this id (`Memory store not found.`), or the store has no note with this id (`Memory not found.`).
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## Change a note

`POST /memory_stores/{memory_store_id}/memories/{memory_id}`

Change a note's text, its path, or both. A `content` or `path` left out, or sent as `null`, stays as it was. Changing the path moves the note, and the new path must be free. A change that changes nothing answers the note as it is and saves no version.

To change a note only if no one else has, send a `precondition` with the `content_sha256` you read. If the note's text is no longer that text, the change is refused. If the note already has the path and text you ask for, the answer is `200` even when the hash is stale, so a retry of a change that landed is safe.

### Path parameters

- `memory_store_id` (memory store id, required): The memory store, such as `memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24`.
- `memory_id` (note id, required): The note, such as `mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20`.

### Query parameters

- `view` (string): `full` answers the text of the note. `basic`, the default, leaves `content` as `null`. One of `basic`, `full`.

### Body

- `content` (string): The new text, 0 to 102,400 UTF-8 bytes.
- `path` (string): The new path, which moves the note. It follows the rules of a path in [Write a note](#write-a-note).
- `precondition` (object): Change the note only if it still has the text a hash names.
  - `type` (string, required): Always `content_sha256`.
  - `content_sha256` (string, required): The `content_sha256` of the text you read.

### Returns

The note, as [Write a note](#write-a-note) shows it. A change that saves a version names it in `memory_version_id`.

### Example

```bash
curl "https://core.thelittleworker.com/api/v1/memory_stores/memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24/memories/mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20?view=full" \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19" \
  -H "content-type: application/json" \
  -d '{
  "content": "Sam orders on Mondays and likes a text more than a call.",
  "precondition": {
    "type": "content_sha256",
    "content_sha256": "3264f64c28ae4c6a20c3a58ebdfa89735a5aeeff334fb1a7a1f2e815b8b197ba"
  }
}'
```

```json
{
  "type": "memory",
  "id": "mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20",
  "memory_store_id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
  "memory_version_id": "memver_8b2d4f6a0c1e4a3b9d5f7e1c3a9b6d48",
  "path": "/customers/sam.md",
  "content": "Sam orders on Mondays and likes a text more than a call.",
  "content_sha256": "fc0f613597834eece1ddce8ff30052ac267e1fac58ba8496e6ac67a9872711c5",
  "content_size_bytes": 56,
  "created_at": "2026-10-20T09:20:41.007Z",
  "updated_at": "2026-10-24T11:02:19.640Z"
}
```

### Errors

- 400 `invalid_request_error`: A field is not valid (`error_code` `validation_error`): the path is not a note path, the text is over 102,400 bytes, `precondition.content_sha256` is not a SHA-256 in lowercase hexadecimal, or the `view` is not `basic` or `full`. The text holds a saved password (`This note contains a saved password. Remove it and try again.`), or so does the path. The store is archived and can only be read (`This memory store is archived and can only be read.`).
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 404 `not_found_error`: The workspace has no memory store with this id (`Memory store not found.`), or the store has no note with this id (`Memory not found.`).
- 409 `memory_path_conflict_error`: A note is already at the path, at a folder above it, or inside it as a folder (`error_code` `memory_path_conflict`). `/notes` and `/notes/todo.md` cannot both be notes. Choose another path.
- 409 `memory_precondition_failed_error`: The note's text is no longer the text the hash names (`error_code` `memory_precondition_failed`). Read the note again and make the change from its new hash.
- 413 `request_too_large`: The request body is over 10 MiB (`error_code` `request_too_large`). A note holds at most 102,400 bytes.
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## Delete a note

`DELETE /memory_stores/{memory_store_id}/memories/{memory_id}`

Delete a note. Its versions stay, with a `deleted` version on top, so the change can be seen. To delete only if no one else has changed the note, send the `content_sha256` you read as `expected_content_sha256`.

### Path parameters

- `memory_store_id` (memory store id, required): The memory store, such as `memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24`.
- `memory_id` (note id, required): The note, such as `mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20`.

### Query parameters

- `expected_content_sha256` (string): Delete the note only if its text still has this hash.

### Returns

`type` is `memory_deleted`, with the note's `id`.

### Example

```bash
curl "https://core.thelittleworker.com/api/v1/memory_stores/memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24/memories/mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20?expected_content_sha256=fc0f613597834eece1ddce8ff30052ac267e1fac58ba8496e6ac67a9872711c5" \
  -X DELETE \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19"
```

```json
{
  "type": "memory_deleted",
  "id": "mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20"
}
```

### Errors

- 400 `invalid_request_error`: An id is not of its kind, or `expected_content_sha256` is not a SHA-256 in lowercase hexadecimal (`error_code` `validation_error`). The store is archived and can only be read (`This memory store is archived and can only be read.`).
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 404 `not_found_error`: The workspace has no memory store with this id (`Memory store not found.`), or the store has no note with this id (`Memory not found.`).
- 409 `memory_precondition_failed_error`: The note's text is no longer the text the hash names (`error_code` `memory_precondition_failed`). Nothing was deleted.
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## List versions

`GET /memory_stores/{memory_store_id}/memory_versions`

List every change made in a store, newest first, across all its notes. Filter by note, by what the change did, by the task a worker was in, or by the key that made it.

### Path parameters

- `memory_store_id` (memory store id, required): The memory store, such as `memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24`.

### Query parameters

- `memory_id` (note id): Only the versions of this note.
- `operation` (string): Only changes of this kind. One of `created`, `modified`, `deleted`.
- `task_id` (task id): Only the changes a worker made in this task.
- `api_key_id` (api key id): Only the changes this key made.
- `view` (string): `full` answers the text of the versions. `basic`, the default, leaves `content` as `null`. One of `basic`, `full`.
- `limit` (integer): How many to answer, 1 to 100. The default is 20. With `view=full` the most is 20.
- `page` (string): The `next_page` of the answer before, to read the next page.
- `order` (string): `desc`, newest first (the default), or `asc`, oldest first. One of `desc`, `asc`.
- `created_at[gt]` (time): Only those made after this time, an RFC 3339 time compared to the millisecond the answer shows. It may end in `Z` or in an offset such as `+02:00`. `created_at[lt]` works the same way. `created_at[gte]` and `created_at[lte]` take a UTC time that ends in `Z`, and an offset is refused.

### Returns

A list: `data` holds the versions, and `next_page` is the `page` to send for more (`null` on the last page). A version has the fields of [Read a version](#read-a-version).

### Example

```bash
curl "https://core.thelittleworker.com/api/v1/memory_stores/memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24/memory_versions?memory_id=mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20" \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19"
```

```json
{
  "data": [
    {
      "type": "memory_version",
      "id": "memver_8b2d4f6a0c1e4a3b9d5f7e1c3a9b6d48",
      "memory_id": "mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20",
      "memory_store_id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
      "operation": "modified",
      "path": "/customers/sam.md",
      "content": null,
      "content_sha256": "fc0f613597834eece1ddce8ff30052ac267e1fac58ba8496e6ac67a9872711c5",
      "content_size_bytes": 56,
      "created_by": {
        "type": "api_actor",
        "api_key_id": "apikey_7c1e3a5b9d2f4e6a8b0c4d6f2a1e9b35"
      },
      "created_at": "2026-10-24T11:02:19.640Z",
      "redacted_at": null,
      "redacted_by": null
    },
    {
      "type": "memory_version",
      "id": "memver_1d3f5a7c9e0b4c2d8a6e4f2b0c9d7a35",
      "memory_id": "mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20",
      "memory_store_id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
      "operation": "created",
      "path": "/customers/sam.md",
      "content": null,
      "content_sha256": "3264f64c28ae4c6a20c3a58ebdfa89735a5aeeff334fb1a7a1f2e815b8b197ba",
      "content_size_bytes": 56,
      "created_by": {
        "type": "api_actor",
        "api_key_id": "apikey_7c1e3a5b9d2f4e6a8b0c4d6f2a1e9b35"
      },
      "created_at": "2026-10-20T09:20:41.007Z",
      "redacted_at": null,
      "redacted_by": null
    }
  ],
  "next_page": null
}
```

### Errors

- 400 `invalid_request_error`: A filter is not valid, such as an id of the wrong kind, an `operation` that is not one of its values, a time that is not an RFC 3339 time, a `limit` outside its range, or a `limit` over 20 with `view=full` (`error_code` `validation_error`). `page` is not a page this list gave (`error_code` `validation_error`, `That cursor is not valid.`), or it was made with another `order` (`That cursor was made with another order. Use the same one, or read the first page again.`).
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 404 `not_found_error`: No memory store in the key's workspace has this id (`Memory store not found.`).
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## Read a version

`GET /memory_stores/{memory_store_id}/memory_versions/{memory_version_id}`

Read one version. Like a note, a version answers its text unless you ask for `view=basic`.

### Path parameters

- `memory_store_id` (memory store id, required): The memory store, such as `memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24`.
- `memory_version_id` (version id, required): The version, such as `memver_1d3f5a7c9e0b4c2d8a6e4f2b0c9d7a35`.

### Query parameters

- `view` (string): `basic` leaves the text of the version out, and `content` is `null`. `full`, the default, answers it. One of `basic`, `full`.

### Returns

`type` is `memory_version`, with these fields.

- `type` (string): Always `memory_version`.
- `id` (version id): The version's id: `memver_` and 32 hex digits.
- `memory_id` (note id): The note it changed.
- `memory_store_id` (memory store id): The store the note is in.
- `operation` (string): What the change did: `created` the note, `modified` its path or text, or `deleted` it. One of `created`, `modified`, `deleted`.
- `path` (string, or null): The note's path after the change, or the path it was deleted from. `null` once the version is redacted.
- `content` (string, or null): The note's text after the change. `null` for a `deleted` version, for a redacted one, and in the basic view.
- `content_sha256` (string, or null): The SHA-256 of the text. `null` for a `deleted` version and a redacted one.
- `content_size_bytes` (integer, or null): The text's size in bytes. `null` for a `deleted` version and a redacted one.
- `created_by` (object, or null): Who made the change. `null` for a change the service made, and for a worker's write outside a task.
  - `type` (string): `task_actor` for a worker's write in a task, `api_actor` for a key's write, `user_actor` for a person's write in the app. One of `task_actor`, `api_actor`, `user_actor`.
  - `task_id` (task id): Only on a `task_actor`: the task the worker was in.
  - `api_key_id` (api key id): Only on an `api_actor`: the key, `apikey_` and 32 hex digits.
  - `user_id` (user id): Only on a `user_actor`: the person, `user_` and 32 hex digits. It is the same on every device.
- `created_at` (time): When the change was made.
- `redacted_at` (time, or null): When the version's path, text, hash and size were removed. `null` if they were not.
- `redacted_by` (object, or null): Who redacted it: a key (`api_actor`) or a person (`user_actor`). `null` if it was not redacted.
  - `type` (string): `api_actor` for a key, `user_actor` for a person in the app. One of `api_actor`, `user_actor`.
  - `api_key_id` (api key id): Only on an `api_actor`: the key, `apikey_` and 32 hex digits.
  - `user_id` (user id): Only on a `user_actor`: the person, `user_` and 32 hex digits. It is the same on every device.

### Example

```bash
curl https://core.thelittleworker.com/api/v1/memory_stores/memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24/memory_versions/memver_1d3f5a7c9e0b4c2d8a6e4f2b0c9d7a35 \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19"
```

```json
{
  "type": "memory_version",
  "id": "memver_1d3f5a7c9e0b4c2d8a6e4f2b0c9d7a35",
  "memory_id": "mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20",
  "memory_store_id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
  "operation": "created",
  "path": "/customers/sam.md",
  "content": "Sam orders on Fridays and likes a text more than a call.",
  "content_sha256": "3264f64c28ae4c6a20c3a58ebdfa89735a5aeeff334fb1a7a1f2e815b8b197ba",
  "content_size_bytes": 56,
  "created_by": {
    "type": "api_actor",
    "api_key_id": "apikey_7c1e3a5b9d2f4e6a8b0c4d6f2a1e9b35"
  },
  "created_at": "2026-10-20T09:20:41.007Z",
  "redacted_at": null,
  "redacted_by": null
}
```

### Errors

- 400 `invalid_request_error`: An id is not of its kind, or `view` is not `basic` or `full` (`error_code` `validation_error`).
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 404 `not_found_error`: The workspace has no memory store with this id (`Memory store not found.`), or the store has no version with this id (`Version not found.`).
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.

## Redact a version

`POST /memory_stores/{memory_store_id}/memory_versions/{memory_version_id}/redact`

Remove a version's path, text, hash and size from history, for a text that should not have been kept. The version stays, with who made the change and when, and `redacted_at` and `redacted_by` say who redacted it. It cannot be undone. Redacting a version twice answers it as it is. An archived store can still be redacted.

### Path parameters

- `memory_store_id` (memory store id, required): The memory store, such as `memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24`.
- `memory_version_id` (version id, required): The version, such as `memver_1d3f5a7c9e0b4c2d8a6e4f2b0c9d7a35`.

### Returns

The version, as [Read a version](#read-a-version) shows it.

### Example

```bash
curl "https://core.thelittleworker.com/api/v1/memory_stores/memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24/memory_versions/memver_1d3f5a7c9e0b4c2d8a6e4f2b0c9d7a35/redact" \
  -X POST \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19"
```

```json
{
  "type": "memory_version",
  "id": "memver_1d3f5a7c9e0b4c2d8a6e4f2b0c9d7a35",
  "memory_id": "mem_c4e8a2f6b0d14a3e9b7c5d1f3a8e6b20",
  "memory_store_id": "memstore_6a1f9c3e5b7d4e2a8f0c1d3b5a7e9f24",
  "operation": "created",
  "path": null,
  "content": null,
  "content_sha256": null,
  "content_size_bytes": null,
  "created_by": {
    "type": "api_actor",
    "api_key_id": "apikey_7c1e3a5b9d2f4e6a8b0c4d6f2a1e9b35"
  },
  "created_at": "2026-10-20T09:20:41.007Z",
  "redacted_at": "2026-10-25T17:12:03.418Z",
  "redacted_by": {
    "type": "api_actor",
    "api_key_id": "apikey_7c1e3a5b9d2f4e6a8b0c4d6f2a1e9b35"
  }
}
```

### Errors

- 400 `invalid_request_error`: An id is not of its kind. `error_code` is `validation_error`.
- 401 `authentication_error`: The key is missing, removed, or not a key. Send it in `x-api-key`.
- 404 `not_found_error`: The workspace has no memory store with this id (`Memory store not found.`), or the store has no version with this id (`Version not found.`).
- 409 `conflict_error`: The version is the newest of a note that still exists, so it holds the note's text now (`This is the note's current text. Change or forget the note first.`). Change or delete the note first.
- 429 `rate_limit_error`: The workspace made too many requests this minute. Wait the seconds in `Retry-After`, then try again.
