Every endpoint requires authentication and workspace context.
workspace_id is
accepted only by the workspace middleware (query parameter, path context, or
X-Workspace-ID); it is never part of a memory operation’s payload. crew_id,
when set, is validated against the caller’s workspace (cross-tenant lookups
return 404).Endpoints
Export and import require
OWNER or ADMIN (the route’s manage role). The
workspace is selected by the authenticated session’s workspace context;
workspace_id is not part of either operation’s request payload. Both require
crew_id; an empty agent_slug addresses crew-shared memory.
Memory portability
GET /api/v1/memory/export
Request: no body. Required query parameter crew_id identifies a crew in
the caller’s workspace; optional agent_slug selects an agent within that
crew. With no format (or any value other than zip), the response is
200 OK, application/json:
documents and skipped are always arrays. Document fields are path,
tier, and body, with scope, title, tags, and sources omitted when
empty. Each skipped entry has source and reason.
With format=zip, a non-empty scope returns 200 OK with
Content-Type: application/zip, Content-Disposition: attachment, and a
Content-Length; the body is the OKF ZIP bundle, not JSON.
POST /api/v1/memory/import
Request: application/json, capped at 32 MiB:
crew_id, agent_slug, and documents are request fields; every document
requires path, tier, and body. The operation is per-document rather than
transactional. 200 OK returns:
detail is omitted when empty; a successful response can contain rejected or
failed documents. Prompt-injection findings are reported in rejected with
kind: "prompt_injection".
Health
Read-only snapshot for the memory health dashboard. Backed byinternal/consolidate.ComputeHealth. The five aggregate queries it runs are cheap, so the handler recomputes on every request rather than reading the persisted memory_health_snapshots table — those snapshots exist for time-series plots, not real-time reads.
See Episodic memory — health scoring for the formula and operator interpretation.
Get health snapshot
Auth: Every workspace member can read. The response contains only counts and ratios, no raw entry content.
Response:
200 OK
There is no separate
band field — clients categorise locally:
The CLI uses these exact thresholds (
internal/cli colour helpers) and the FE follows.
Errors:
Hybrid search
k = 60):
- FTS5 / BM25 — the workspace-tier full-text index over markdown memory.
- Episodic recall — dense-vector + BM25 recall over the crew journal.
200 with an empty
hits array and count: 0 — the same shape the sidecar /memory/search
uses.
Auth: required + workspace context (MEMBER+). Every query is anchored
on the caller’s session workspace, so a foreign workspace_id cannot be
smuggled through the body.
Request body:
Response:
200 OK
null
(fts / episodic both carry omitempty): an FTS-sourced hit has no
episodic key and vice-versa.
Memory versions audit trail
The HTTP mirror ofcrewship memory log/show. Workspace is anchored from the session — query strings never carry workspace_id, so a cross-workspace probe can’t smuggle a foreign id through. Restore (POST /api/v1/memory/versions/{sha}/restore) is documented separately on the Admin reference because it requires OWNER/ADMIN and mutates canonical state; the two read endpoints below are MEMBER+.
GET /api/v1/memory/versions
Returns the audit chain for one canonical memory path, newest-first.
Auth: required + workspace context.
Query parameters:
Response:
200 OK
projection — whether an empty entries may be read as a fact.
memory_versions is a projection of the .memory tree, not the tree itself: a file appears only if some writer records it. An unprojected path and a path nobody has written to both answer {"entries": []}, and a client cannot tell them apart — so the server says which it is. Clients must not hard-code the list of projected tiers; it is a property of the writers and it changes.
GET /api/v1/memory/versions/{sha}
Returns the raw blob bytes for one historical version. Pipe-friendly: the body is the historical content, metadata travels in headers so a CLI pipe to a file produces the exact bytes that were written.
Auth: required + workspace context.
Path parameters:
Query parameters:
Response:
200 OK — raw bytes, Content-Type: application/octet-stream.
The restore endpoint (
POST /api/v1/memory/versions/{sha}/restore) is OWNER/ADMIN-only and applies extra server-side path confinement to refuse canonical targets outside the configured memory root. See the Admin reference for the full mutation surface.Tenancy
workspace_idis always pulled from the session — never accepted as a query parameter or body field.crew_id, when set, is validated viacrewBelongsToWorkspace(same helper as the Paymaster API). Cross-tenant lookups return404.
Related
- Episodic memory guide.
crewship memory health— CLI wrapper.- Crew Journal — source of indexed entries.