Skip to content
Talk to our solutions team

AI Memory API

All routes require a Bearer token (which establishes the CPET) and — where scope-claim enforcement is enabled — a signed scope claim in the X-Kis-Scope-Claim header. Errors are { "code": "…", "message": "…" }.

MethodPathBody → Response
POST/v1/sessions{scope, subject:{type,id}}201 {session_id}
POST/v1/sessions/:id/messages{scope, messages:[{role, text, content:[{kind, text, data}]}]}{appended: N}
DELETE/v1/sessions/:id?scope=…Close the session → {status:"closed"} — triggers summarization + episode/fact extraction
POST/v1/events{scope, type, session_id?, detail:{}}{status:"recorded"} — record a decision/preference marker
POST/v1/promote{kind:"session"|"episode", id, target_scope}{status:"promoted"} — re-tag into a team scope (caller must be authorized to write both scopes)

Messages return fast and durably; the analysis (embedding, summaries, facts) happens in the background.

MethodPathPurpose
GET/v1/sessions/:id/messages?window=NThe last N messages (default 50), oldest-first
POST/v1/recallRanked recall (below)
GET/v1/facts?scopes=&subject_type=&subject_id=&at=&limit=&include_sensitive=Structured facts about a subject; at=<RFC3339> gives the as-of (bitemporal) view

Recall:

POST /v1/recall
{
"context": "what does this user prefer",
"scopes": ["agent:helpdesk-7", "user:u-42"],
"budget": { "max_tokens": 2048 },
"limit": 20,
"min_score": 0.0,
"include_sensitive": false
}

{
"items": [
{ "kind": "fact", "text": "prefers terse responses", "scope": "user:u-42", "ref": "", "ts": "", "score": 0.82 },
{ "kind": "message", "text": "", "session_id": "", "ts": "", "score": 0.60 }
],
"tokens_used": 340,
"truncated": false
}

With claim enforcement on, the request scopes can only narrow the claim’s readable set, never widen it; sensitive items are suppressed unless include_sensitive is set. The most recent turn always appears, even while consolidation is catching up.

MethodPathBody → Response
POST/v1/forget{scope, session_id? | subject? | fact_id?, reason?} (exactly one target) → a deletion receipt {sessions_deleted, messages_deleted, episodes_deleted, facts_deleted, multi_source_facts_flagged[], complete}. Incomplete propagation returns 500 with the partial receipt
POST/v1/memory/edit{scope, op:"add"|"correct"|"delete", fact_id?, subject, statement?, predicate?}{status:"edited"} — user edits take precedence over machine facts
POST/v1/exclusions{scope, pattern}{status:"exclusion_set"} — never remember matching content

Cluster-authenticated control plane:

MethodPathPurpose
POST/admin/v1/consolidate{tier:"t1"|"t2", scope?, session_id?} — run consolidation on demand (t1 needs session_id, t2 needs scope)
POST/admin/v1/maintenanceRun one decay + retention cycle across all active scopes
GET/admin/v1/healthLiveness/readiness
GET/admin/v1/statsPersistence backend, and whether semantic recall, consolidation, and claim enforcement are enabled

A bot records each turn and recalls at the start of a conversation:

# start a session
POST /v1/sessions {"scope":"agent:helpdesk-7","subject":{"type":"human","id":"u-42"}}
# append turns as they happen
POST /v1/sessions/{id}/messages {"scope":"agent:helpdesk-7","messages":[{"role":"user","text":"…"}]}
# recall relevant memory before responding
POST /v1/recall {"context":"…","scopes":["agent:helpdesk-7","user:u-42"],"budget":{"max_tokens":2048}}
# close at the end → triggers summary + episode/fact extraction
DELETE /v1/sessions/{id}?scope=agent:helpdesk-7

Bots and the AI harness consume Memory through a recall seam, so an agent’s memory persists across runs and channels without the bot managing storage itself.

RoutesCredential
/v1/*A bearer token
/admin/v1/*A bearer token — control plane

No route is anonymous. The health and readiness probes are the only unauthenticated surface.

The four CPET headers scope every session, event, fact and exclusion. Recall and consolidation never cross a tenant boundary.

Where scope-claim enforcement is enabled, a signed X-Kis-Scope-Claim header narrows access further within the tenant.

CodeStatusMeaning
invalid_request400Malformed body or arguments
invalid_cpet400The CPET could not be resolved
budget_too_small400The recall token budget is too small to return anything
claim_invalid401The scope-claim signature or expiry is invalid
scope_forbidden403The claim does not authorize the requested scope
session_not_found404No session with that id in this tenant
consolidation_busy409A consolidation job for this target is already running
forget_incomplete500A right-to-forget deletion could not fully propagate — a partial receipt is returned
internal500Unexpected server error

forget_incomplete is the one to alert on. It means a deletion request was accepted and only partly applied, so the receipt tells you what remains.