Memory
The remember, recall, update, and forget verbs plus the /api/memories management surface — store, search, list, and delete your iCog memories.
This is the contract reference for iCog memory. Two route groups make up the
surface: the cognitive verbs (remember, recall, update, forget) that you
use to write and read memories, and the /api/memories management routes that
list, search, count, and delete them. Everything here is grounded in the live
API at https://api.cognitivx.io.
Every endpoint requires authentication. Pass either Authorization: Bearer <key>
or X-API-Key: <key>, where the key is an icog_-prefixed API key created at
developers.cognitivx.io/keys, or a
short-lived JWT access token. An icog_ value works in the Authorization: Bearer
header too. Missing or invalid auth returns 401 with WWW-Authenticate: Bearer.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /api/remember | Store a new memory. |
POST | /api/recall | Semantic + temporal search over your memories. |
POST | /api/update | Replace an existing memory's content. |
POST | /api/forget | Soft-delete a memory by id (verb form). |
GET | /api/memories | Paginated list with an optional type filter. |
GET | /api/memories/{id} | Fetch one memory by id. |
GET | /api/memories/counts | Counts grouped by type. |
GET | /api/memories/pinned | All foundational (pinned) memories. |
POST | /api/memories/search | Hybrid keyword + semantic search. |
POST | /api/memories/bulk-delete | Soft-delete up to 500 memories. |
DELETE | /api/memories/{id} | Soft-delete one memory (REST form). |
DELETE | /api/memories/wipe | Delete all memories, or all of one type. |
Memory types
memory_type is the one field worth understanding before you write. It is a
fixed enum, and the four values you may write are:
| Type | Use it for |
|---|---|
semantic | Facts, knowledge, decisions, architecture. |
episodic | Events, sessions, what happened. Powers the chronological timeline. |
procedural | Skills, how-tos, coding patterns. |
foundational | Pinned facts. Always injected into context, never evicted. |
Omit memory_type on a write and iCog classifies the content for you. Pass an
invalid value and you get 400 with the list of accepted values in detail.
The enum also contains system-only types — error, pattern, insight,
reflective, meta, emergent — populated by the cognition and dream engines.
They can appear in read responses, but do not write them. Passing one to
remember or update is rejected as an invalid memory_type.
Tier and org behavior
- Tier gate.
POST /api/rememberandPOST /api/updaterequire anawakenedtier account or higher for personal callers. Below that you get403with{"error":"tier_insufficient", ..., "required_tier":"awakened", "upgrade_url":"/settings"}.recall,forget, and all/api/memoriesreads and deletes have no tier gate. Org members are entitled through their seat and skip the personal tier check. - Org isolation. Every endpoint resolves the effective owner as the active
org account when one is selected (via the optional
X-Org-IDheader on/api/memories/*), otherwise the caller. Reads and writes then target the org's shared store. Cross-user and cross-org access is always masked as404, never403. - Quota. Writes (
remember,update, pinning) return429with a quota detail body when the account's memory capacity is exceeded.
The TypeScript SDK is @cognitivx/sdk. The cognitive verbs live in the memory
namespace; the management routes live in the memories namespace. Call
configureApiClient once, then call the namespaced functions; failures throw
ApiError.
Remember a memory
Store a new memory. This is the single write entry point for facts, events, skills, and pinned facts.
POST /api/remember · Authorization: Bearer <key> or X-API-Key. Personal
(non-org) callers must be awakened tier or higher.
| Field | Type | Required | Description |
|---|---|---|---|
content | string | yes | The memory text to store. |
memory_type | string | null | no | One of semantic, episodic, procedural, foundational. Omit to let iCog classify. Do not pass the system-only types. |
agent_slug | string | null | no | Identifies the writing agent. When set, the write is stamped to that agent (private agent visibility) and is read back only by recall calls that pass the same agent_slug. |
deep | boolean | no | Default false. When true, the response is an SSE stream: iCog searches related memories, classifies the content as new, duplicate, or refinement, then writes or skips. The final event (kind="done") carries memory_id and the action taken. |
curl -X POST https://api.cognitivx.io/api/remember \
-H "Authorization: Bearer $ICOG_KEY" \
-H "Content-Type: application/json" \
-d '{"content":"We chose asyncpg over SQLAlchemy for the iCog backend to keep pooled connections explicit.","memory_type":"semantic"}'import { configureApiClient, memory } from '@cognitivx/sdk';
configureApiClient({ apiKey: process.env.ICOG_KEY });
const { memory_id } = await memory.remember({
content:
'We chose asyncpg over SQLAlchemy for the iCog backend to keep pooled connections explicit.',
memory_type: 'semantic',
});{
"memory_id": "a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b"
}Errors: 400 invalid memory_type, or a validation/anchor rejection from the
store (foundational writes require a first-person anchor). 401 missing or
invalid auth. 403 tier_insufficient (below awakened, personal caller).
429 memory quota exceeded. 500 unexpected storage error.
Recall memories
Semantic plus temporal search over your stored memories. This is the primary read path for "what do I know about X".
POST /api/recall · Authorization: Bearer <key> or X-API-Key. No tier gate.
| Field | Type | Required | Description |
|---|---|---|---|
query | string | yes | Natural-language search query. |
limit | integer | no | Max memories to return. Default 10. |
memory_type | string | null | no | Restrict to one type. |
temporal | string | null | no | Optional hint to bias toward a time frame (for example, recency). |
deep | boolean | no | Default false. When true, the response is an SSE chain stream; the final event (kind="done") carries the curated memory list. |
agent_slug | string | null | no | Pass the same slug used at write time to read back that agent's private memories. Omit for the user-scoped view. |
curl -X POST https://api.cognitivx.io/api/recall \
-H "X-API-Key: $ICOG_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"why did we pick asyncpg","limit":5}'import { configureApiClient, memory } from '@cognitivx/sdk';
configureApiClient({ apiKey: process.env.ICOG_KEY });
const { memories, count } = await memory.recall({
query: 'why did we pick asyncpg',
limit: 5,
});{
"memories": [
{
"id": "a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b",
"text": "We chose asyncpg over SQLAlchemy for the iCog backend to keep pooled connections explicit.",
"memory_type": "semantic",
"age_days": 3,
"created_at": "2026-06-13T18:04:22.512000+00:00",
"occurred_at": null,
"occurred_at_end": null,
"occurred_precision": null,
"similarity": 0.83,
"temporal_context": null
}
],
"count": 1
}The occurred_at* fields are event-time and are distinct from created_at
(write-time). occurred_precision is one of instant, hour, day, week,
month, range, or unknown. similarity is the vector match score.
Recall swallows internal errors and returns 200 with
{"memories":[],"count":0} rather than a 5xx. Check count, not just the
status code. Memories whose owner does not match the effective owner are filtered
out by the cross-contamination guard.
Errors: 401 missing or invalid auth. 429 quota exceeded (rare on read).
Update a memory
Replace an existing memory's content. This soft-deletes the old row and stores a
new one, preserving the original memory_type.
POST /api/update · Authorization: Bearer <key> or X-API-Key. Personal
(non-org) callers must be awakened tier or higher.
| Field | Type | Required | Description |
|---|---|---|---|
memory_id | string (UUID) | yes | The memory to replace. Must be owned by the caller (or the active org). |
content | string | yes | The new content. memory_type is carried over from the original automatically. |
curl -X POST https://api.cognitivx.io/api/update \
-H "Authorization: Bearer $ICOG_KEY" \
-H "Content-Type: application/json" \
-d '{"memory_id":"a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b","content":"We chose asyncpg over SQLAlchemy for explicit pooled connections and lower overhead."}'import { configureApiClient, memory } from '@cognitivx/sdk';
configureApiClient({ apiKey: process.env.ICOG_KEY });
const { old_memory_id, new_memory_id } = await memory.update(
'a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b',
'We chose asyncpg over SQLAlchemy for explicit pooled connections and lower overhead.',
);{
"old_memory_id": "a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b",
"new_memory_id": "b2e4d3c5-6c7f-5a89-0b12-3d4e5f6a7b8c"
}The new_memory_id differs from old_memory_id: re-embedding the new content
mints a new row. The ownership lookup excludes already soft-deleted rows.
Errors: 400 invalid memory_id UUID, or a validation/anchor rejection on
the new content. 401 missing or invalid auth. 403 tier_insufficient
(below awakened, personal caller). 404 memory not found or not owned by the
caller. 429 quota exceeded. 500 transient on the re-store.
Forget a memory
Soft-delete a single memory by id, verb form with a JSON body. Verifies ownership first.
POST /api/forget · Authorization: Bearer <key> or X-API-Key. No tier gate.
| Field | Type | Required | Description |
|---|---|---|---|
memory_id | string (UUID) | yes | The memory to soft-delete. Must be owned by the caller (or the active org). |
curl -X POST https://api.cognitivx.io/api/forget \
-H "X-API-Key: $ICOG_KEY" \
-H "Content-Type: application/json" \
-d '{"memory_id":"a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b"}'import { configureApiClient, memory } from '@cognitivx/sdk';
configureApiClient({ apiKey: process.env.ICOG_KEY });
const { forgotten } = await memory.forget('a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b');{
"memory_id": "a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b",
"forgotten": true
}On an internal delete failure this route still returns 200, but with
{"memory_id":null,"forgotten":false}. Check the forgotten flag, not just the
status code. For id-in-path deletion, use
DELETE /api/memories/{id}.
Errors: 400 invalid memory_id UUID. 401 missing or invalid auth.
404 memory not found or not owned by the caller.
List memories
Paginated listing of stored memories with an optional type filter.
GET /api/memories · Authorization: Bearer <key> or X-API-Key. Optional
X-Org-ID header scopes to org memory.
| Name | Type | Required | Description |
|---|---|---|---|
memory_type | string | no | Filter by one type. Invalid value returns 400. |
limit | integer | no | Max results. Default 50, capped at 200. |
offset | integer | no | Pagination offset. Default 0. |
sort | string | no | recent (default) or relevance. |
curl "https://api.cognitivx.io/api/memories?memory_type=semantic&limit=20" \
-H "X-API-Key: $ICOG_KEY"import { configureApiClient, memories } from '@cognitivx/sdk';
configureApiClient({ apiKey: process.env.ICOG_KEY });
const { memories: rows, total, has_more } = await memories.list({
memory_type: 'semantic',
limit: 20,
});{
"memories": [
{
"id": "a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b",
"content": "We chose asyncpg over SQLAlchemy for the iCog backend.",
"memory_type": "semantic",
"source": "icog:web",
"source_label": "Chat",
"tags": [],
"created_at": "2026-06-13T18:04:22.512000+00:00",
"updated_at": null,
"access_count": 2,
"display_text": "We chose asyncpg over SQLAlchemy for the iCog backend.",
"canonical_url": null
}
],
"total": 1,
"has_more": false
}Each object also carries cognitive scores (wisdom_score, base_strength,
plasticity, emotional_valence, experiential_weight), the attribution
envelope (claimant_slug, claim_type, subject_kind, agent_visibility),
and occurred_at* event-time fields. The human-relevant subset is shown above;
the rest are present on the wire.
Errors: 400 invalid memory_type. 401 missing or invalid auth.
Get one memory
Fetch a single stored memory by id. The object is wrapped under memory.
GET /api/memories/{memory_id} · Authorization: Bearer <key> or X-API-Key.
| Name | Type | Required | Description |
|---|---|---|---|
memory_id | string (UUID, path) | yes | The memory id. |
curl https://api.cognitivx.io/api/memories/a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b \
-H "X-API-Key: $ICOG_KEY"import { configureApiClient, memories } from '@cognitivx/sdk';
configureApiClient({ apiKey: process.env.ICOG_KEY });
const { memory: row } = await memories.get('a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b');{
"memory": {
"id": "a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b",
"content": "We chose asyncpg over SQLAlchemy for the iCog backend.",
"memory_type": "semantic",
"source": "icog:web",
"source_label": "Chat",
"tags": [],
"created_at": "2026-06-13T18:04:22.512000+00:00",
"updated_at": null,
"access_count": 2,
"canonical_url": null
}
}Errors: 400 invalid memory ID format. 401 missing or invalid auth.
404 memory not found or owned by another user.
Search memories
Hybrid keyword (full-text) plus semantic search, merged with reciprocal-rank
fusion. Inputs are query-string params even though this is a POST.
POST /api/memories/search · Authorization: Bearer <key> or X-API-Key.
| Name | Type | Required | Description |
|---|---|---|---|
query | string | yes | Search query. |
memory_type | string | no | Restrict to one type. |
limit | integer | no | Max results. Default 20. |
The params go in the query string, not a JSON body, despite the POST
method. The SDK builds this correctly; hand-written curl needs the params on the
URL.
curl -X POST "https://api.cognitivx.io/api/memories/search?query=asyncpg&limit=10" \
-H "X-API-Key: $ICOG_KEY"import { configureApiClient, memories } from '@cognitivx/sdk';
configureApiClient({ apiKey: process.env.ICOG_KEY });
const { memories: hits } = await memories.search({ query: 'asyncpg', limit: 10 });{
"memories": [
{
"id": "a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b",
"content": "We chose asyncpg over SQLAlchemy for the iCog backend.",
"memory_type": "semantic",
"source": "icog:web",
"source_label": "Chat",
"tags": [],
"created_at": "2026-06-13T18:04:22.512000+00:00",
"updated_at": null,
"access_count": 2,
"canonical_url": null
}
],
"total": 1,
"has_more": false
}has_more is always false: search does not paginate. The difference from
/api/recall: search returns full stored-memory objects
(content, source, tags), while recall returns a lighter result with similarity
and event-time fields.
Errors: 400 invalid memory_type. 401 missing or invalid auth.
422 missing the required query param.
Bulk delete memories
Soft-delete up to 500 memories in one call by id list. Only ids owned by the caller are deleted; others are silently skipped.
POST /api/memories/bulk-delete · Authorization: Bearer <key> or X-API-Key.
| Field | Type | Required | Description |
|---|---|---|---|
memory_ids | string[] (UUIDs) | yes | Up to 500 ids. More than 500 returns 400. |
curl -X POST https://api.cognitivx.io/api/memories/bulk-delete \
-H "Authorization: Bearer $ICOG_KEY" \
-H "Content-Type: application/json" \
-d '{"memory_ids":["a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b","b2e4d3c5-6c7f-5a89-0b12-3d4e5f6a7b8c"]}'{
"deleted": 2
}There is no SDK helper for bulk-delete. Call apiClient.post('/api/memories/bulk-delete', { memory_ids })
directly.
Errors: 400 more than 500 ids, or any id is not a valid UUID. 401
missing or invalid auth.
Delete one memory
Soft-delete a single memory by id. This is the REST-style counterpart to
POST /api/forget.
DELETE /api/memories/{memory_id} · Authorization: Bearer <key> or X-API-Key.
| Name | Type | Required | Description |
|---|---|---|---|
memory_id | string (UUID, path) | yes | The memory to delete. Must be owned by the caller (or the active org). |
curl -X DELETE https://api.cognitivx.io/api/memories/a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b \
-H "Authorization: Bearer $ICOG_KEY"import { configureApiClient, memories } from '@cognitivx/sdk';
configureApiClient({ apiKey: process.env.ICOG_KEY });
await memories.remove('a1f3c2d4-5b6e-4f78-9a01-2c3d4e5f6a7b');{
"message": "Memory deleted"
}The DELETE is atomic on (id, user_id). Cross-user access is masked as 404,
never 403.
The SDK types memories.remove(id) as returning { ok?: true }, but the server
returns {"message":"Memory deleted"}. The call works; the typed shape is wrong.
Do not rely on an ok field.
Errors: 400 invalid memory ID format. 401 missing or invalid auth.
404 memory not found or owned by another user.
Wipe memories
Nuclear delete of all memories, or all of one type. Irreversible from the API surface.
DELETE /api/memories/wipe · Authorization: Bearer <key> or X-API-Key.
| Name | Type | Required | Description |
|---|---|---|---|
memory_type | string | no | If set, deletes only that type. If omitted, deletes everything for the effective owner. |
Omitting memory_type wipes the entire store for the caller (or the active org).
There is no undo. Guard this behind a confirmation in any UI.
curl -X DELETE "https://api.cognitivx.io/api/memories/wipe?memory_type=episodic" \
-H "Authorization: Bearer $ICOG_KEY"{
"deleted": 42
}There is no SDK helper for wipe. Note the param is on the query string, not a body.
Errors: 400 invalid memory_type. 401 missing or invalid auth.
Memory counts by type
Aggregate counts of stored memories grouped by type, plus an all total.
GET /api/memories/counts · Authorization: Bearer <key> or X-API-Key. No
params.
curl https://api.cognitivx.io/api/memories/counts \
-H "X-API-Key: $ICOG_KEY"import { configureApiClient, memories } from '@cognitivx/sdk';
configureApiClient({ apiKey: process.env.ICOG_KEY });
const counts = await memories.counts();{
"counts": {
"all": 128,
"semantic": 71,
"episodic": 44,
"procedural": 9,
"foundational": 4
}
}Which keys appear depends on what you have stored; all is the grand total used
for list pagination.
The raw HTTP response nests under counts. The SDK memories.counts() is typed
as Record<string, number> and omits that wrapper, so read the returned object's
fields against your own runtime shape.
Errors: 401 missing or invalid auth.
List pinned memories
Return all foundational (pinned) memories — the facts always injected into session context. They are never evicted.
GET /api/memories/pinned · Authorization: Bearer <key> or X-API-Key. No
params.
curl https://api.cognitivx.io/api/memories/pinned \
-H "X-API-Key: $ICOG_KEY"{
"memories": [
{
"id": "c3f5e4d6-7d8a-6b90-1c23-4e5f6a7b8c9d",
"content": "The user's name is Parsa and the active product is CognitiveX / iCog.",
"memory_type": "foundational",
"source": "icog:web",
"source_label": "Chat",
"tags": ["pinned"],
"created_at": "2026-05-30T11:20:00+00:00",
"updated_at": null,
"access_count": 0,
"canonical_url": null
}
]
}Foundational memories are created either by remember with
memory_type: "foundational" or via the dedicated POST /api/memories/pin
endpoint.
Errors: 401 missing or invalid auth.
Related
- Authentication & keys — how Bearer and
X-API-Keyauth resolve, and where to createicog_keys. - Quickstart — your first
rememberandrecallround trip.
Authentication & keys
The /api/auth, /api/profile, and /api/preferences endpoints for signup, login, OAuth, sessions, handoff, instructions, and API key lifecycle.
Chat & sessions
SSE streaming chat, follow-up suggestions, session CRUD, message history, search, export, and categories under /api/chat and /api/sessions.