Axiom StudioAXIOMSTUDIO
All docs

API Reference

Memora exposes the same service layer through three programmable surfaces: a REST API under /v1, an MCP server for agent clients, and a Go SDK. This page lists the endpoints, tools, and methods of each, plus the error codes common to all of them.

Request Conventions

Request and response bodies are JSON. Errors use one envelope shape across every endpoint:

{
  "error_code": "cas_conflict",
  "message": "expected watermark wmk_… but head is wmk_…",
  "details": {}
}

Unknown fields in a request body are rejected rather than ignored, so a misspelled key surfaces as 400 invalid_input instead of being silently dropped.

Headers

FieldValue
Authorization: Bearer <key>The server API key, compared in constant time. Required on every non-/ui path when a key is configured.
Memora-Agent-IdThe writing agent. Required on writes to memories, edges, and graph endpoints.
Memora-Identity-ProviderSelects the identity check for that agent. Defaults to opaque.
X-Memora-WorkspaceResolves the workspace when the server runs in multi-tenant mode.
If-MatchThe expected watermark on update, patch, and append. Equivalent to expected_watermark in the body.
X-Request-IDCorrelation ID. Echoed back when supplied; otherwise the server generates one and returns it.

The agent header is required on non-GET requests whose path contains /memories, /edges, or /graph/. Workspace, collection, agent, recall, and pin requests do not require it. A write without the header returns 400 missing_agent_id; one whose identity provider rejects the agent returns 401 agent_verification_failed.

Every request is capped at 8 MiB and runs under the server's configured timeout, 30 seconds by default. Cross-origin requests are answered only for origins on the configured allow-list.

REST Endpoints

All paths are relative to /v1.

Workspaces and Collections

FieldValue
POST /workspacesCreate a workspace.
GET /workspacesList workspaces. Cursor-paginated; limit defaults to 100 and is capped at 200.
GET /workspaces/{ws}Read a workspace.
PUT /workspaces/{ws}Replace a workspace.
DELETE /workspaces/{ws}Delete a workspace.
GET /workspaces/{ws}/collectionsList collections.
POST /workspaces/{ws}/collectionsCreate a collection.
GET /workspaces/{ws}/collections/{id}Read a collection.
DELETE /workspaces/{ws}/collections/{id}Delete a collection.

Memories

FieldValue
POST /workspaces/{ws}/memoriesImprint. Accepts an optional per-request chunker and chunker config.
GET /workspaces/{ws}/memoriesList memories, optionally filtered by collection_id. limit defaults to 50.
GET /workspaces/{ws}/memories/{id}Look up a Memory with its Cells.
PUT /workspaces/{ws}/memories/{id}Replace content. Requires a watermark.
PATCH /workspaces/{ws}/memories/{id}Apply diff operations. Requires a watermark.
DELETE /workspaces/{ws}/memories/{id}Forget. ?redact_audit=true also redacts ledger metadata where the ledger supports it.
POST /workspaces/{ws}/memories/{id}:appendAppend to content.
GET /workspaces/{ws}/memories/{id}@{watermark}Read the Memory as it stood at a past watermark.
GET /workspaces/{ws}/memories/{id}/watermarksWatermark history over a fixed seven-day window.
PUT /workspaces/{ws}/memories/{id}/tags/{key}Upsert a tag. POST behaves identically.
DELETE /workspaces/{ws}/memories/{id}/tags/{key}Delete a tag.

Graph

FieldValue
GET /workspaces/{ws}/memories/{id}/edgesList a Memory's edges, filtered by direction and type.
POST /workspaces/{ws}/memories/{id}/edgesCreate an edge from this Memory.
POST /workspaces/{ws}/edges/:batchCreate many edges in one call. Returns per-edge status with ok and failed counts.
DELETE /workspaces/{ws}/edges/{id}Unlink. Rejects synthetic edges.
POST /workspaces/{ws}/graph/neighborsOne-hop neighbours with direction, type, and k.
POST /workspaces/{ws}/graph/traverseBreadth-first traversal returning layers.
GET /workspaces/{ws}/graph/statsNode count and edge count by type.

Note the slash in /edges/:batch. Batch edge creation is addressed as its own path segment — /edges/:batch. Written without the slash, as /edges:batch, the request returns 404 not_found.

Recall, Agents, and Audit

FieldValue
POST /workspaces/{ws}/recallRun a recall query.
GET /workspaces/{ws}/recall/pinsList saved queries.
POST /workspaces/{ws}/recall/pinsSave a query. mode defaults to hybrid and k to 10.
DELETE /workspaces/{ws}/recall/pins/{id}Delete a saved query.
GET /workspaces/{ws}/agentsList agents.
POST /workspaces/{ws}/agentsRegister an agent.
GET /workspaces/{ws}/agents/{id}Read an agent.
DELETE /workspaces/{ws}/agents/{id}Deactivate an agent.
GET /workspaces/{ws}/ledgerQuery the audit ledger. Returns 501 if the configured ledger cannot query.

Ledger queries accept since, until, actor, agent_id, memory_id, edge_id, op (comma-separated), limit, and since_ledger_id for cursor paging.

Operational Endpoints

These sit outside /v1.

FieldValue
GET /healthzLiveness. Returns 200 whenever the process is up.
GET /readyzReadiness. Pings the metadata, vector, and ledger adapters.

These are ordinary non-/ui paths, so they require the bearer token when an API key is configured. A probe that omits it receives 401.

The MCP Server

memora-core mcp speaks JSON-RPC 2.0 over stdio. Setting mcp_enable on a running server additionally mounts a WebSocket endpoint at /mcp. The server advertises protocol version 2024-11-05 and implements tools/list and tools/call. Twenty-five tools are exposed.

SectionDescription
Workspacesmemora_create_workspace, memora_get_workspace, memora_list_workspaces, memora_update_workspace, memora_delete_workspace
Collectionsmemora_create_collection, memora_list_collections, memora_delete_collection
Memoriesmemora_imprint, memora_lookup, memora_update, memora_patch, memora_append, memora_forget, memora_list_memories, memora_get_watermark_history
Recallmemora_recall, memora_pin, memora_unpin
Graphmemora_link, memora_unlink, memora_neighbors, memora_traverse
Agentsmemora_register_agent, memora_list_agents

The stdio transport is unauthenticated unless you give it a key. With no key configured it treats its caller as trusted — it only talks to the process that started it — and logs a warning saying so. Passing --api-key, or setting MEMORA_API_KEY, makes the initialize handshake require that key and rejects every other method until the handshake succeeds.

There is no MCP tool for graph statistics or for querying the ledger; both are REST-only. Everything else in the tool list maps onto the REST verb of the same name.

The Go SDK

pkg/client is the Go client the CLI is built on, and it can be imported directly. Transport is REST.

import (
    "context"

    "github.com/axiom-studio/memora/pkg/client"
    "github.com/axiom-studio/memora/pkg/types/api"
)

c := client.New("http://localhost:7777", apiKey)
c.AgentID = "agent_my_service"

res, err := c.Imprint(ctx, workspaceID, api.ImprintRequest{
    Content: "Customer wants the enterprise plan.",
})

New returns a client with a 30-second timeout. Endpoint, APIKey, AgentID, Workspace, and HTTPClient are all exported, so the HTTP client can be replaced for connection pooling, tracing, or tests. Every method takes the workspace as an explicit argument; the Workspace field is a convenience holder for callers that want one place to keep it, not an implicit default.

SectionDescription
MemoriesImprint, Lookup, Update, Patch, Append, Forget, ListMemories, WatermarkHistory
RecallRecall, CreatePin, ListPins, DeletePin
GraphLink, Unlink, Neighbors, Traverse, GraphStats
ContainersCreateWorkspace, GetWorkspace, ListWorkspaces, DeleteWorkspace, CreateCollection, ListCollections
IdentityRegisterAgent, ListAgents
AuditLedgerQuery
HealthHealth, Ready

Handling Errors

Non-2xx responses come back as a *client.APIError carrying the status, the decoded envelope, and the raw body. Two helpers cover the cases worth branching on:

res, err := c.Patch(ctx, workspaceID, memoryID, watermark, req)
if client.IsCASErr(err) {
    // Someone else wrote first. Re-read and decide.
}

var apiErr *client.APIError
if errors.As(err, &apiErr) && apiErr.IsNotFound() {
    // The Memory is gone.
}

The SDK sets Authorization, Memora-Agent-Id, and If-Match from the client's fields and method arguments. It does not set Memora-Identity-Provider, so SDK writes are always verified by the default opaque provider.

Error Codes

Every error response carries an error_code. Client faults are distinguished from server faults, so a 5xx always indicates a Memora problem rather than a bad request.

StatusDescription
invalid_input400 — malformed body, an unknown field, an unknown recall mode, or a missing required field.
patch_anchor_not_found400 — a patch old_string does not appear in the current content.
graph_traverse_depth_exceeded400 — the requested traversal depth exceeds the graph adapter's cap, which is 3 in the SQLite graph store.
missing_agent_id400 — a write arrived without the Memora-Agent-Id header.
unauthorized401 — missing or invalid bearer token.
agent_verification_failed401 — the identity provider rejected the agent.
not_found404 — the workspace, collection, memory, edge, or agent does not exist.
method_not_allowed405 — the endpoint exists but not for this HTTP method.
already_exists409 — the record already exists.
already_linked_via_synthetic409 — an auto-generated edge already joins these Memories.
cannot_unlink_synthetic_edge409 — vector_neighbor edges cannot be removed by hand.
not_empty409 — the container still holds records.
cas_conflict412 — the supplied watermark does not match the current head.
quota_exceeded429 — a configured limit was hit.
internal_error500 — an unclassified server fault.
capability_unavailable501 — the configured adapter does not implement the operation. Most often a missing GraphStore, or a LedgerStore that cannot be queried.

capability_unavailable is the one to expect during deployment rather than at runtime: it means the request is well-formed but the storage seam behind it was never configured. See Adapters for which operations depend on which seam.