Inspecting, correcting, deleting and moving your memories. Deleting works on every plan — removing your own data is never gated. The rest of this group requires Pro or above on the store being acted on.
list_memories
Browse memories
Pro and above
Browses your stored memories, oldest first, a page at a time — the way to actually see what Cogni is holding on you.
Each record comes with its durable mem_id, which is the handle you pass to get_memory, forget or update_memory. Records also carry how often and when recall last surfaced them; these survive a restart, but treat them as advisory usage hints rather than an exact audit trail, because they are a lower bound — a memory reached only through the connection graph does not always bump the count. The creation time is the durable recency anchor.
| Parameter | Type | Default | What it does |
limit optional | int | 50 | How many memories per page. Clamped to 1–500. |
cursor optional | str | None | None | The mem_id to resume after — pass the next_cursor from the previous page. |
space optional | str | None | None | A team space to browse. Requires read membership. |
Returns
A page of memories, oldest first, each with mem_id, text, entities, created_at, and importance, band, protected and affect where set, alongside the access count and last-accessed time (these survive a restart, but are a lower bound — advisory, not audit). Plus count (total live memories) and next_cursor, which is null on the last page.
list_by_entity
List memories about a subject
Pro and above
Lists every memory that mentions a particular person, place or project — the exhaustive “what do you have about X” browse.
Recall is a relevance search: it returns the best few matches. This returns all of them, paginated, which matters as a store grows — a memory that never scores well against any particular question can otherwise become effectively unreachable. Use it for auditing, or for reviewing everything on one topic.
Matching is on the indexed names, not on the memory text, and it expands across name parts in both directions: asking for “Ian” also returns memories filed under “Ian Hamilton”, and vice versa. The names actually matched come back as matched_entities, so you can see whether the answer is broader than you asked for. An empty result means no indexed name matched — which is not quite the same as Cogni knowing nothing about the subject, so it is worth trying recall too.
Archived memories are not included, and browsing does not count as revisiting a memory — so an audit sweep never changes what retention decides to keep.
| Parameter | Type | Default | What it does |
entity required | str | — | The name to look up. Case and punctuation do not matter. |
limit optional | int | 50 | How many memories per page. Clamped to 1–500. |
offset optional | int | 0 | Where to resume — pass the next_offset from the previous page. |
space optional | str | None | None | A team space to browse. Requires write membership, because an exhaustive listing can reproduce a whole shared store. |
Returns
The normalised entity, the matched_entities it resolved to, the total count, the current offset, a next_offset (null on the last page), and a page of memories in the same shape list_memories returns.
get_memory
Get a memory
Pro and above
Fetches one memory's full record by its mem_id.
Like list_memories, it includes access count and last-accessed time. These survive a restart and are a lower bound — advisory rather than audit, though a high count is the real signal the retention policy uses to decide what to keep.
| Parameter | Type | Default | What it does |
mem_id required | str | — | The durable handle, as returned by remember or list_memories. |
space optional | str | None | None | A team space to read from. Requires read membership. |
Returns
The full record — mem_id, text, entities, created_at, importance, band, protected and affect where set, access count and last accessed. If there is no such live memory it reports found: false rather than erroring.
forget
Delete a memory
All plans
Destructive
Deletes a memory by its mem_id. Available on every plan — removing your own data is never gated behind an upgrade.
In your private memory, deleting an ordinary memory cannot be undone. The memory is pruned from every index, including the entity graph, so it is no longer returned by recall in any mode, no longer appears in an export, and no longer acts as a connection between your other memories. The deletion is recorded durably, so it stays deleted across restarts.
In a team space, deletion is reversible. Shared memory is not permanently destroyed by a single member: a team-space forget soft-archives the memory instead, returning reversible: true, and any member can bring it back for free with restore_memory. This is the counterpart of deletion being free — nobody, and no assistant tidying up on their behalf, can quietly erase the team's shared knowledge. A protected memory is refused outright for a member, reporting forgotten: false with a reason naming which rule applied — safety (an allergy or medication, the memories the system marks undeletable), protected (an explicit flag) or high-importance.
The space owner can remove a protected memory from their own space. It is still only archived, so any member brings it back for free and a team-space delete can never be made permanent — the reply says so, with overridden_by: "space-owner" alongside the tier that was overridden. The route exists so that a team whose ordinary work vocabulary overlaps with health and safety language is not left holding notes it can never tidy up. Rewriting a protected memory with update_memory stays refused for everyone, owner included — a rewritten safety fact reads as current and authoritative, where an archived one is visibly absent.
In your own memory, a safety-critical memory is archived first. You can delete it — it is your data, and the protection exists to stop the system quietly retiring a safety fact that simply has not come up in a long time, not to overrule you. But the first forget archives it rather than erasing it: it stops being recalled and returns reversible: true, and restore_memory brings it back. Erasing it for good takes a second call with permanent: true. This tool is normally invoked by an assistant rather than by you directly, so the first delete is made undoable in case it was not something you asked for — and a repeated identical call will not complete the erase.
What private deletion does not do. Memories are held in an append-only log, so deleting one records the deletion rather than overwriting the original entry in place. That entry is cleared the next time the store's log is compacted — a routine maintenance rewrite that keeps the live entries and drops the deleted ones — and a copy remains in any backup snapshot taken before you deleted it until those age out. Nothing in the service reads those entries back — a deleted memory is genuinely unreachable from the moment you delete it — but it is not physically erased at that instant. The Privacy Policy covers this in full.
Finding the handle. Every remember call returns the mem_id of what it just stored, so your assistant can delete something it stored earlier in the same conversation. Looking up the handle for an older memory means browsing with list_memories, which is a Pro tool.
Calling it twice is harmless: an unknown id simply reports forgotten: false. Deleting from a team space requires a write role there.
| Parameter | Type | Default | What it does |
mem_id required | str | — | The handle of the memory to delete. |
space optional | str | None | None | A team space to delete from. Requires a write role. |
permanent optional | bool | false | Completes the erase of a safety-critical memory that is already archived. No effect on a live memory (always archived first) or on an ordinary one. |
Returns
forgotten — false if there was no such live memory — and the mem_id.
update_memory
Replace a memory
Pro and above
Destructive
Replaces a memory's text — the way to correct a fact that has changed.
This replaces the old memory. It is a delete followed by a fresh store, so the replacement gets a new
mem_id. In your private memory the original text is not recoverable; in a team space the replaced version is soft-archived and can be brought back with
restore_memory, and a teammate's safety fact cannot be overwritten (it reports
updated: false,
protected).
One safety behaviour worth knowing: if the new text is rejected as a near-duplicate of some other existing memory, the update is refused and the original is deliberately left intact rather than deleted.
| Parameter | Type | Default | What it does |
mem_id required | str | — | The handle of the memory being replaced. |
text required | str | — | The new text to store in its place. |
importance optional | str | float | None | None | Salience band or raw multiplier for the replacement memory. |
entities optional | list[str] | None | None | Entity names to index the replacement under. |
affect optional | str | None | None | Passive sentiment tag on the new memory; never used to rank recall. |
space optional | str | None | None | A team space to update in. Requires a write role. |
Returns
Whether the update succeeded and the new mem_id. It reports updated: false with a reason when the id does not exist, or when the new text was near-duplicate-rejected.
export_memories
Export memories
Pro and above
Produces a portable JSON snapshot of your memories — your data, in a form you can keep.
The snapshot covers the live set only; deleted memories are never included. Feed the memories list back into import_memories to restore or copy them elsewhere.
| Parameter | Type | Default | What it does |
space optional | str | None | None | A team space to export. Requires a write role — one call returns the whole store, so a viewer is limited to ordinary recall. |
Returns
A version number, a count, and memories — the live records, each with mem_id, text, entities, created_at and salience metadata.
import_memories
Import memories
Pro and above
Adds memories from an export_memories snapshot.
The default merge mode mints fresh ids and skips near-duplicates, which makes it safe to run against any target. The restore mode preserves the original ids and timestamps, and for that reason is allowed only into your own private memory — attempting it against a team space is an error.
An import is metered like any other write: it is refused up front if it would take the target store past its memory cap or monthly write quota, and each memory actually stored counts once (a skipped near-duplicate does not).
| Parameter | Type | Default | What it does |
memories required | list[dict] | — | The memories list from an export snapshot. |
mode optional | str | "merge" | merge mints fresh ids and skips near-duplicates; restore preserves original ids and timestamps and is private-space only. Any other value is rejected. |
space optional | str | None | None | A team space to import into, in merge mode only. Requires a write role. |
Returns
How many memories were imported, how many were skipped — skips being empty text, an id that already exists live or archived, or a near-duplicate — and how many were rejected. A rejected row is one the snapshot could not be read from, such as an unparseable timestamp; it is dropped on its own rather than failing the whole import, so one bad row never costs you the rest of a backup.