Memory
Append, retrieve, read, update, delete and consolidate memories, and track ingestion and erasure — the core /v1/memory endpoints.
All endpoints take a bearer token and name the workspace they act on. Required capability is listed per endpoint. Errors follow the shared error format.
| Method | Path | Capability |
|---|---|---|
POST | /v1/memory/append | write |
POST | /v1/memory/retrieve | read |
GET | /v1/memory/{id} | read |
PUT | /v1/memory/{id} | write |
DELETE | /v1/memory/{id} | delete |
GET | /v1/memory/{id}/erasure | read |
GET | /v1/memory/operations/{operationId} | read |
POST | /v1/memory/consolidate | curate |
Share, explain, change feed, quarantine review and evaluations are on Memory governance.
Append a memory
POST /v1/memory/append — store one memory. Supports Idempotency-Key.
curl -s -X POST "$AGENT_MEMORY_BASE_URL/v1/memory/append" \
-H "Authorization: Bearer $AGENT_MEMORY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c0c9e-2b7a-4d43-9a0f-8f6d2a1b3c4d" \
-d '{
"workspaceId": "'"$AGENT_MEMORY_WORKSPACE_ID"'",
"runId": "run-1",
"layer": "Workspace",
"type": "decision",
"content": "All entity IDs are GUIDs, never ints",
"tags": { "facet": "persistence" }
}'Body
| Field | Type | Required | Notes |
|---|---|---|---|
workspaceId | GUID | yes | Must be the workspace the credential holds. |
runId | string | yes | 1–128 characters: letters, digits, ., _, -. One per task. |
layer | string | yes | Workspace stores durably at once (and records the entry in the run). Session writes run-scoped memory that consolidation may promote. |
type | string | yes | decision, correction, violation, approved_pattern, artifact_ref, preference or raw. See Memory types. |
content | string | yes | The memory text. Screened before it is stored. |
applicationId | GUID | no | Scope to an application. An application-scoped key pins this and cannot be overridden. |
agentId | string | no | Omit to act as the credential's default agent. See Identity. |
userId | string | no | The end user the memory is about. Requires canActForUsers. |
tags | object | no | String key/value pairs. facet is the conventional facet tag. Platform-owned keys (origin_entry_id, episode_id, promoted_from_run) are refused with 400. |
summary | string | no | A short summary to use in compact renderings. |
visibility | string | no | private, agent, user, workspace (default) or tenant (needs promote). |
classification | string | no | public, internal (default), confidential, restricted. Stored, not enforced. |
sourceKind | string | no | agent (default), user, document or import. derived and system are set by the platform and refused. |
sourceRef | string | no | A pointer into the source, such as contract-828.pdf#p14 or a URL. |
observedAt | timestamp | no | When the fact was observed. Defaults to createdAt. |
validFrom / validTo | timestamp | no | When the fact is true in the world. validTo must be after validFrom. |
createdAt | timestamp | no | Event time for histories imported after the fact. Defaults to now. |
agentInstanceId | string | no | Identifies a specific instance of the agent. |
Response
{ "id": "8b0c1c0e-…", "merged": false, "contentReplaced": false, "operationId": "3e5f…" }idis always the surviving memory. When the content is a near-duplicate of an existing memory, the write is merged into it,mergedistrueandidis the existing memory's ID;contentReplacedsays whether the existing text was replaced.operationIdis the ingestion receipt.
Content that looks like prompt injection or data exfiltration is stored quarantined and never recalled until reviewed — see Review a quarantined memory.
Retrieve context
POST /v1/memory/retrieve — recall a ranked, token-budgeted context. Every option and section is described in Retrieval.
curl -s -X POST "$AGENT_MEMORY_BASE_URL/v1/memory/retrieve" \
-H "Authorization: Bearer $AGENT_MEMORY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"workspaceId": "'"$AGENT_MEMORY_WORKSPACE_ID"'",
"runId": "run-1",
"semanticQuery": "how are entity IDs typed?",
"tokenBudget": 2000
}'Key fields: workspaceId, runId, semanticQuery, applicationId, agentId, userId, topN, tokenBudget, mode, rerank, minScore, tags, includeSuperseded, asOf, asOfAxis, temporalBefore, temporalAfter, temporalAnchor, expandSessions, expandSessionCount, expandSessionWindow, raw, explain, overrides.
Response: a MemoryContext with receiptId, blocks, userProfile, platformEntries, tenantFloors, tenantEntries, workspaceEntries, procedures, relevantEpisodes, fileDocs, sessionSummary, sessionEntries, omittedWorkspaceCount, supersededHiddenCount, compilation and (with explain) diagnostics.
Errors specific to retrieve: 400 for an invalid mode, asOfAxis or overrides value, or for mode: "deterministic" with rerank: true; 422 CONTEXT_BUDGET_TOO_SMALL when the budget cannot hold non-negotiable policy.
Get a memory
GET /v1/memory/{id}?workspaceId=…
| Query | Notes |
|---|---|
workspaceId | Required. |
applicationId | Optional. An application-scoped caller sees its application plus the workspace-wide pool. |
agentId, userId | Optional subject for the visibility check. |
Returns the memory entry, including version, provenance, temporal and policy fields and trust. 404 when it does not exist or is not visible to the subject. Use this for artifact_ref memories, which semantic search does not surface.
Update a memory
PUT /v1/memory/{id} — replace a memory's content in place. Supports Idempotency-Key and If-Match.
{ "workspaceId": "…", "content": "All entity IDs are GUIDs (v7)", "applicationId": null, "agentId": null, "userId": null }| Status | Meaning |
|---|---|
200 | { "id": "…", "version": 8 } plus ETag: "8". |
400 | Blank content, or an If-Match value that isn't a version or *. |
403 | policy_denied — visible but not updatable by this principal. |
404 | Unknown or not visible. |
409 | concurrent_update (lost a race) or IDEMPOTENCY_CONFLICT. |
412 | precondition_failed with currentVersion — the memory changed since you read it. |
The content is screened and re-embedded; an update row is written to the change feed. See Updating and forgetting.
Delete a memory
DELETE /v1/memory/{id}?workspaceId=…[&cascade=true] — soft-delete the memory and run the erasure cascade. Supports Idempotency-Key.
| Query | Notes |
|---|---|
workspaceId | Required. |
cascade | true flags live dependents as stale and proceeds. Default false. |
applicationId, agentId, userId | Optional, as for get. |
| Status | Body | Meaning |
|---|---|---|
204 | — | Deleted, cleanup complete. |
202 | {"cleanup":"pending"} | Deleted; derived copies still being removed. Poll erasure status. |
403 | problem | policy_denied, or FORBIDDEN for tenant-scope content. |
404 | — | Unknown or not visible. |
409 | problem | deletion_blocked_by_active_dependents with blockingDependents. Nothing written. |
Erasure status
GET /v1/memory/{id}/erasure?workspaceId=… — where a memory's erasure stands.
{ "memoryId": "8b0c1c0e-…", "status": "pending", "attempts": 2, "erasedAt": null }status is none, pending, complete or dead. Takes the same optional applicationId, agentId, userId query parameters. 404 when the memory is unknown or was never visible to the caller.
Ingestion receipt
GET /v1/memory/operations/{operationId}?workspaceId=… — what became of an append. An append is durable when it returns, but some effects (embedding, when the workspace defers it, and the webhook event) can finish afterwards.
{
"operationId": "3e5f…",
"memoryId": "8b0c1c0e-…",
"merged": false,
"contentReplaced": false,
"status": "indexed",
"createdAt": "2026-10-01T09:00:00Z",
"effects": [ { "kind": "event", "state": "succeeded", "attempt": 1, "lastError": null } ]
}status is pending, indexed or failed. Each effect has a kind (embed or event), a state (pending, failed, succeeded or dead), the attempt count and the last error. A receipt from another workspace answers 404.
Consolidate a run
POST /v1/memory/consolidate — end a run: create its episode, extract facts, learn procedures and clear its session memory. Supports Idempotency-Key.
{
"workspaceId": "…",
"runId": "run-1",
"applicationId": null,
"goal": "Add vegetarian filtering to the menu service",
"extractionInstructions": "Only keep decisions about the public API."
}Response: {"status":"consolidated"}. goal and extractionInstructions are optional. Idle runs are consolidated automatically by the background worker. See Runs and consolidation.