Memory API

Agent memory stores facts, preferences, patterns, and outcomes learned during task execution. Each memory is scoped to a profile and carries a confidence score that decays over time. The Memory API supports CRUD operations with category and status filtering, confidence adjustment, and soft-delete archival.

Quick Start

Store a memory, retrieve memories by category, boost confidence on a useful one, and archive a stale one — the full memory lifecycle:

// 1. Store a fact learned during task execution
const res1 = await fetch('/api/memory', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
  profileId: 'data-analyst',
  category: 'fact',
  content: 'Project uses PostgreSQL 16 with TimescaleDB extension for time-series data',
  tags: ['database', 'postgresql', 'timescaledb'],
  confidence: 0.9,
}),
});
const { id: memId }: { id: string } = await res1.json();
// → { id: "mem-7c3a-2e1f" }

// 2. Store a preference
await fetch('/api/memory', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
  profileId: 'data-analyst',
  category: 'preference',
  content: 'User prefers seaborn over matplotlib for visualizations',
  tags: ['visualization', 'python'],
  confidence: 0.85,
}),
});

// 3. Retrieve all active facts for a profile
const factsRes = await fetch('/api/memory?profileId=data-analyst&category=fact&status=active');
const facts: Array<{ confidence: number; content: string }> = await factsRes.json();

console.log(`${facts.length} active facts:`);
facts.forEach((m) => {
const conf: string = (m.confidence / 1000 * 100).toFixed(0);
console.log(`  [${conf}%] ${m.content}`);
});

// 4. Boost confidence on a memory that proved useful
await fetch('/api/memory', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: memId, confidence: 950 }),
});

// 5. Archive a stale memory (soft delete — can be restored later)
await fetch('/api/memory', {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: 'mem-old-stale-one' }),
});

Base URL

/api/memory

Endpoints

List Memories

GET /api/memory

Retrieve memories for a profile with optional filtering by category and status. Results are ordered by confidence (highest first).

Query Parameters

Param Type Req Description
profileId string * Profile UUID — required for all queries
category enum Filter by category: fact, preference, pattern, or outcome
status enum Filter by status: active, decayed, archived, or rejected

Response 200 — Array of memory objects ordered by confidence descending

Memory Object

FieldTypeReqDescription
idstring (UUID)*Memory identifier
profileIdstring*Associated profile ID
categoryenum*fact, preference, pattern, or outcome
contentstring*Memory content text
confidencenumber (0–1000)*Confidence score — higher means more reliable
tagsstring (JSON)JSON-encoded array of tags
accessCountnumber*Number of times this memory has been accessed
decayRatenumber*Confidence decay rate per cycle
statusenum*active, decayed, archived, or rejected
createdAtISO 8601*Creation timestamp
updatedAtISO 8601*Last modification timestamp

Errors: 400 — Missing profileId

Retrieve all active memories for a profile — the agent uses these as context during task execution:

// Fetch active facts for a profile, sorted by confidence
const response: Response = await fetch(
'/api/memory?profileId=data-analyst&category=fact&status=active'
);
const memories: Array<{ confidence: number; content: string; accessCount: number }> =
await response.json();

// Display with human-readable confidence percentages
memories.forEach((m) => {
const conf: string = (m.confidence / 10).toFixed(0);
const accessed: string = m.accessCount === 1 ? '1 access' : `${m.accessCount} accesses`;
console.log(`[${conf}%] ${m.content} (${accessed})`);
});

Example response:

[
  {
    "id": "mem-7c3a-2e1f",
    "profileId": "data-analyst",
    "category": "fact",
    "content": "Project uses PostgreSQL 16 with TimescaleDB extension for time-series data",
    "confidence": 900,
    "tags": "[\"database\",\"postgresql\",\"timescaledb\"]",
    "accessCount": 7,
    "decayRate": 10,
    "status": "active",
    "createdAt": "2026-03-20T14:00:00.000Z",
    "updatedAt": "2026-04-03T09:30:00.000Z"
  },
  {
    "id": "mem-4b8d-9f2c",
    "profileId": "data-analyst",
    "category": "fact",
    "content": "API rate limit is 100 requests per minute per client IP",
    "confidence": 700,
    "tags": "[\"api\",\"rate-limit\"]",
    "accessCount": 3,
    "decayRate": 10,
    "status": "active",
    "createdAt": "2026-03-25T10:15:00.000Z",
    "updatedAt": "2026-04-01T08:00:00.000Z"
  }
]

Create Memory

POST /api/memory

Create a memory manually (operator injection). The confidence value is provided as a 0–1 float and stored internally as 0–1000 integer. Default confidence is 0.7 (700).

Request Body

FieldTypeReqDescription
profileIdstring*Profile to associate the memory with
categoryenum*fact, preference, pattern, or outcome
contentstring*Memory content text
tagsstring[]Categorization tags (stored as JSON)
confidencenumber (0–1)Initial confidence score(default: 0.7)

Response 201 Created{ "id": "uuid" }

Errors: 400 — Missing required fields or invalid category

Store different types of memories — facts for objective information, preferences for user choices, patterns for recurring behaviors, and outcomes for task results:

// Store a preference memory with high confidence
const response: Response = await fetch('/api/memory', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
  profileId: 'data-analyst',
  category: 'preference',
  content: 'User prefers seaborn over matplotlib for visualizations',
  tags: ['visualization', 'python'],
  confidence: 0.85,  // Stored as 850 internally
}),
});
const { id }: { id: string } = await response.json();

console.log(`Created memory: ${id}`); // "mem-7c3a-2e1f"

// Store a pattern observed across multiple task runs
await fetch('/api/memory', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
  profileId: 'devops-engineer',
  category: 'pattern',
  content: 'CI failures spike on Monday mornings due to dependency cache expiration over weekends',
  tags: ['ci', 'caching', 'reliability'],
  confidence: 0.75,
}),
});

Example response:

{
  "id": "mem-7c3a-2e1f"
}

Update Memory

PATCH /api/memory

Update a memory's confidence score or status. Confidence is provided as a 0–1000 integer at this level. Status transitions are validated.

Request Body

FieldTypeReqDescription
idstring (UUID)*Memory identifier
confidencenumber (0–1000)Updated confidence score
statusenumNew status: active, decayed, archived, or rejected

Response 200{ "ok": true }

Errors: 400 — Missing id or invalid status

Boost confidence on a memory that proved accurate, or reject one that turned out to be wrong:

// Boost confidence on a memory that was useful during execution
await fetch('/api/memory', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
  id: 'mem-7c3a-2e1f',
  confidence: 950,  // Boost from 850 to 950
}),
});

// Mark a memory as incorrect — it will be excluded from agent context
await fetch('/api/memory', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
  id: 'mem-4b8d-9f2c',
  status: 'rejected',
}),
});

Archive Memory

DELETE /api/memory

Soft-delete a memory by setting its status to archived. No hard deletes are performed — memories can be restored by updating status back to active.

Request Body

FieldTypeReqDescription
idstring (UUID)*Memory identifier to archive

Response 200{ "ok": true }

Errors: 400 — Missing id or archive failure

Archive a memory you no longer need — it’s a soft delete, so you can restore it later by updating status back to active:

// Soft-delete a memory — can be restored later
await fetch('/api/memory', {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: 'mem-4b8d-9f2c' }),
});

// Restore it later by updating status back to active
await fetch('/api/memory', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: 'mem-4b8d-9f2c', status: 'active' }),
});

Memory Categories

CategoryDescriptionExamples
factObjective information learned from execution”Project uses PostgreSQL 16”, “API rate limit is 100 req/min”
preferenceUser or operational preferences”Prefer TypeScript over JavaScript”, “Use dark theme in reports”
patternRecurring behaviors or execution patterns”CI failures usually happen on Monday mornings”, “Auth errors spike after deploys”
outcomeResults and learnings from completed tasks”Refactoring reduced build time by 40%”, “Migration completed without data loss”

Memory Lifecycle

Memories follow a confidence-based lifecycle:

StatusDescription
activeMemory is current and used in agent context
decayedConfidence dropped below threshold — still available but deprioritized
archivedSoft-deleted by user or system — excluded from agent context
rejectedExplicitly marked as incorrect — excluded from agent context

Constants

ConstantValueDescription
DEFAULT_CONFIDENCE700 (0.7)Default confidence for new memories
DEFAULT_DECAY_RATE10Confidence decay per cycle
MIN_CONFIDENCE0Minimum confidence value
MAX_CONFIDENCE1000Maximum confidence value