Logo

Memory API

How to use the Quotient SDK to read and write Memory programmatically

Prerequisites

Before you begin, ensure you have:

  • A Quotient account with a private API key
  • The MEMORY_READ and/or MEMORY_WRITE scopes enabled on your key
  • Installed the Quotient Server SDK (@quotientjs/server)

Overview

Quotient exposes its memories via API, making it easy to integrate with other systems and agents. For example, you can fetch Quotient's marketing-related memories inside of a coding agent to help it write better copy for your website. Or you can go in the opposite direction — you can have your AI personal assistant create memories directly in Quotient, or you can set up an integration to write to Quotient's memory from your company knowledge store.

The Memory API models your content as a path-aware filesystem. Content is stored internally as Quotient Rich Text but the SDK uses markdown as the wire format for simplicity.

All paths start with /. The SDK provides separate ls and cat methods with unambiguous return types — no need to check what you got back.

Reading Memory

List folder contents (ls)

import { QuotientServer } from "@quotientjs/server"

const quotient = new QuotientServer({ privateKey: process.env.QUOTIENT_PRIVATE_KEY })

// List direct children of root
const root = await quotient.memory.ls({ path: "/" })
// root.items → [{ type: "folder", name: "projects", path: "/projects/", ... }, ...]

// List direct children of a specific folder
const projects = await quotient.memory.ls({ path: "/projects" })

// Get full recursive tree
const tree = await quotient.memory.ls({ path: "/", deep: true })
// tree.items → nested structure with children arrays

Read a document (cat)

const doc = await quotient.memory.cat({ path: "/projects/budget" })
// doc.title → "Budget"
// doc.content → "# Q1 Budget\n\nTotal: $50,000\n..."
// doc.updatedAt → "2024-01-15T10:30:00.000Z"

Calling cat on a folder path returns a 400 error. Calling ls on a document path returns a 400 error. Each method has a single, unambiguous return type.

Writing Memory

Create or update a document

// Upsert — creates if missing, updates if exists
// Parent folders are auto-created
const doc = await quotient.memory.write({
  path: "/projects/budget",
  title: "Budget",
  content: "# Q1 Budget\n\nTotal: $50,000",
})

Create a folder

const folder = await quotient.memory.mkdir({
  path: "/projects",
  name: "Projects",
})

Deleting Memory

Archive a document

await quotient.memory.rm({ path: "/projects/budget" })

Archive a folder (cascading)

// Archives the folder and all its contents
await quotient.memory.rm({ path: "/projects" })

Path Type Safety

The SDK uses the Path type (/${string}) for compile-time path validation. All paths must start with /:

import type { Path } from "@quotientjs/core"

// TypeScript will enforce the leading slash
const path: Path = "/projects/budget" // OK
// const path: Path = "projects/budget" // Error

Example: Next.js ISR Integration

Here's an example showing how the Memory API can be used in a Next.js app with Incremental Static Regeneration. This is just one way to consume the API — it works with any server-side TypeScript environment.

// app/docs/[...path]/page.tsx
import { QuotientServer } from "@quotientjs/server"
import type { Path } from "@quotientjs/core"

const quotient = new QuotientServer({
  privateKey: process.env.QUOTIENT_PRIVATE_KEY!,
  baseUrl: process.env.BASE_URL,
})

export const revalidate = 60

export default async function DocPage({
  params,
}: {
  params: Promise<{ path: string[] }>
}) {
  const { path } = await params
  const memoryPath = ("/" + path.join("/")) as Path

  // Try as document first, fall back to folder listing
  try {
    const doc = await quotient.memory.cat({ path: memoryPath })
    return <pre>{doc.content}</pre>
  } catch {
    const listing = await quotient.memory.ls({ path: memoryPath })
    return (
      <ul>
        {listing.items.map((item) => (
          <li key={item.path}>{item.name}</li>
        ))}
      </ul>
    )
  }
}

API Reference

memory.cat(options)

ParameterTypeDescription
pathPathDocument path

Returns: CatMemoryResponse{ title, path, content, updatedAt, createdAt }

Returns 400 if path is a folder. Returns 404 if path doesn't exist.

memory.ls(options)

ParameterTypeDescription
pathPathFolder path
deepboolean?If true, returns recursive tree with nested children

Returns: LsMemoryResponse{ items: MemoryFolderItem[] }

Returns 400 if path is a document. Returns 404 if path doesn't exist.

memory.write(options)

ParameterTypeDescription
pathPathDocument path
titlestring?Document title (derived from path if omitted)
contentstringMarkdown content

Returns: WriteMemoryResponse

memory.mkdir(options)

ParameterTypeDescription
pathPathFolder path
namestring?Folder name (derived from path if omitted)

Returns: MkdirMemoryResponse

memory.rm(options)

ParameterTypeDescription
pathPathPath to archive (auto-detects document vs folder)

Returns: RmMemoryResponse{ success: boolean }

Scopes

ScopeRequired for
MEMORY_READmemory.cat(), memory.ls()
MEMORY_WRITEmemory.write(), memory.mkdir(), memory.rm()

Memory scopes are available on private keys only. Documents created via the SDK are visible in the Quotient web UI, and vice versa.