Skip to content

Avatar memory

An avatar with a memory recognises someone the second time they call. It remembers what they told it last month, and it stops retelling the same story. Memory is off unless you ask for it: send a memory_id when you mint a session and the avatar picks up where that store left off.

POST /api/v1/sessions
{ "persona": "sage", "context": { "memory_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301" } }

The id is the memory

memory_id is an RFC 4122 UUID you mint and own. We never generate one, never look inside the store, and have no idea whose memory it is — only you can map a person to an id.

That makes the id a bearer capability: anyone who has it can open that memory through an avatar. Treat it exactly like a password.

  • Derive or store it server-side and never let it reach a browser.
  • Derive it from something stable, so the same person on a new phone gets the same memory. An HMAC over (your secret, user id, avatar) works well and stores nothing.
  • One store per relationship. (user, avatar) is usually the right grain — a different avatar is a different relationship, and one shared id would blur them into each other.

Sending context at all is secret-key only (403 tools_context_not_allowed otherwise), and a value that is not a UUID is 400 invalid_context_memory_id. The nil UUID and other guessable shapes are refused for the same reason a password check refuses password.

The first workspace to mint with an id owns it. A mint from any other workspace naming that id is 403 memory_id_not_yours — otherwise a leaked id would let a stranger read the conversation, and an erasure request would have no single owner to act on.

Erasing a memory

Someone deleting their account is asking you to erase what the avatar knows about them. You cannot do that by forgetting the id: the store outlives it. Call this, and do it before you delete the records the id is derived from — afterwards, you can no longer name what to erase.

Terminal window
curl -X DELETE https://api.casola.ai/api/v1/memory/3f2504e0-4f89-41d3-9a0c-0305e82c3301 \
-H "Authorization: Bearer $CASOLA_SECRET_KEY"
{
"memory_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"status": "purged",
"object_deleted": true,
"live_session": false,
"purged_at": 1755730000
}

Requires sessions:write on a secret key — whatever credential can create a memory can erase it, and nothing weaker can do either.

An account usually means several stores, one per avatar. Erase them in one call:

Terminal window
curl -X POST https://api.casola.ai/api/v1/memory/purge \
-H "Authorization: Bearer $CASOLA_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"memory_ids": ["3f2504e0-…-3301", "8a91b0c2-…-77de"]}'
{
"requested": 2,
"purged": 1,
"results": [
{ "memory_id": "3f2504e0-…-3301", "status": "purged", "live_session": false },
{ "memory_id": "8a91b0c2-…-77de", "status": "already_purged" }
]
}

Up to 100 ids per call. The batch answers 200 and reports each id separately, so one unusable id never costs you the rest of an erasure.

statusMeaning
purgedThe store was erased.
already_purgedIt had been erased before. Not an error — retrying an erasure is safe and expected.
not_foundNo store of that id belongs to you.
invalidNot a UUID; nothing was looked up.
errorStorage refused the delete. Retry.

Retrying is always safe. A second call answers already_purged rather than failing, because an erasure endpoint that errors on retry is one that quietly does not happen.

Single-store errors

CodeErrorCause
400invalid_memory_idNot a UUID
401unauthorizedNo credential
403forbiddenCredential lacks sessions:write
403memory_purge_not_allowedA publishable or device key, or a browser session
404not_foundNo store of that id belongs to you
501memory_storage_not_configuredMemory storage is not available in this environment
502memory_delete_failedStorage refused the delete; retry

A store belonging to another workspace answers 404, not 403. Since the id is a capability, confirming that one exists would itself be a leak.

Erasing during a live call

A purge is never refused because a conversation is running. If one is, live_session is true: the avatar keeps the memory it already loaded until that call ends, and the copy it saves on its way out is deleted within the hour. Nothing you need to do — but if the person is watching, the avatar can still remember them for the rest of that one conversation.

What we keep afterwards

The store is gone. We keep the id, the workspace, and the fact that it was erased and when, so we can answer for the erasure later and so that late copy gets caught. No conversation content survives.

Closing a Casola account erases the memory stores its workspaces own, on the same path.