crouter
DocsSdk

Memory

Read the person's public documents — knowledge and preferences about you — from an app's server with client.memory.

client.memory is the SDK's read-only view of the person's documents: the knowledge and preference documents owned by the person on the canvas (the same objects crtr canvas read shows them). The memory name and the /v1/memory routes are the API's names for this. An app reads the person's public documents with memory.list and memory.get, and needs no scope to do it. It never sees a friends or private memory, and cannot tell one from a memory that does not exist: both answer 404 not_found. This list is what the app's agents can read in memory about you, so an app can show the person exactly which of their memories its agents draw on.

const page = await client.memory.list({ store: 'user' });
for (const item of page.items) console.log(item.name, item.preview);

const doc = await client.memory.get({ store: 'user', name: page.items[0].name });
console.log(doc.body);

store is 'user' (memory about you) in this release; any other value answers 400 invalid_request with param: "store". An app whose grant holds crtr:memory:manage:user (a first-party app) sees every privacy level.

Reading records nothing: no watch, no read event, no audit row. Both methods are GET requests and follow the SDK's retry rule for safe requests.

List

list({store, path?, kind?, limit?, cursor?}, options?) sends GET /v1/memory and returns Promise<MemoryListPage>, {items, next_cursor}.

FieldMeaning
pathA folder: lists documents whose name starts with <path>/, at any depth
kindknowledge or preference; both when omitted
limit1 to 100; default 50
cursorThe previous page's next_cursor, with the same store, path and kind

Items are ordered by name. Each MemoryListItem is {name, folder, kind, preview, summary, privacy, revision, created_at, updated_at}: name has no user/ prefix, folder is the name up to its last / ("" at the top level), and updated_at is the current revision's time. Folders are not items, and deleted and unlisted documents are left out. next_cursor is null on the last page.

listAll(params, options?) takes the same fields without cursor and yields every item across pages, fetching the next page only as you iterate; stop early with break:

for await (const item of client.memory.listAll({ store: 'user', path: 'work' })) render(item);

Get

get({store, name}, options?) sends GET /v1/memory/document and returns Promise<MemoryDocument>: a list item's fields plus body, size, truncated and grantee.

  • body is the current markdown as stored; [[links]] are not resolved. A body over 1 MiB is cut to its longest whole-character prefix of at most 1 MiB, with truncated: true; size is always the full length in UTF-8 bytes.
  • grantee is app:<id> of the app whose agent wrote the first revision, or null when the person wrote it.
  • An absent, deleted, friends or private name rejects with NotFoundError (code: 'not_found'); a malformed field rejects with BadRequestError.

On this page