The /v1 surface is the canonical agent-facing memory interface: observation-shaped writes and staged context retrieval through Executor. Revise and forget are internal reasoner work, not extra agent calls.

In GEM notation (Mt = (Dt, St, Pt)), POST /v1/ingest advances Dt, POST /v1/query evaluates St over that store, and the reasoner’s revise/forget hooks apply Pt after responses return.

POST /v1/ingest semantics

Placement Required fields Behavior
new_topic title recommended Creates topic with generated UUID, optional fields and edges, embedding from title+summary.
extend_topic topic_id Appends/updates fields and edges on existing topic; refreshes embedding from existing title+summary.
version_field topic_id and exactly one field Appends one revision entry to one field on existing topic; refreshes embedding.

POST /v1/query semantics

  • Always embeds query text first.
  • Stage-aware bundle assembly (semantic, structural, temporal).
  • Per-returned-topic salience bump and topic history append (query_bump reason).
  • Response includes machine-friendly candidates and a lightweight summary text block.

Ingest and query sequence

ingest:
  validate request -> apply placement transition -> write topic/field/edge updates
  -> return IngestResponse(topic_id, applied, version_ids, optional similar_topic_ids)
  -> schedule reasoner ingest_complete

query:
  validate request -> semantic candidate selection
  -> optional structural + temporal expansion
  -> salience touch side-effect
  -> return QueryResponse(query, candidates, summary_text)
  -> schedule reasoner query_complete

SDK usage (MemoryClient)

from memstate.client import MemoryClient

client = MemoryClient(base_url="http://127.0.0.1:8765", api_key=None)

ing = client.ingest({
  "placement": "new_topic",
  "title": "Project Atlas",
  "summary": "Migration plan",
  "fields": [{"name": "status", "value": "active", "field_type": "string"}]
})

res = client.query({
  "q": "what is project atlas status",
  "stages": ["semantic", "structural", "temporal"],
  "explain": True,
  "top_k": 5
})

When to use high-level API

  • Automation pipelines that want stable, validated memory semantics.
  • Integrations that should not manipulate low-level graph primitives directly.
  • Workflows where you need the current explicit ingest payload and staged query behavior documented in one place.

Related low-level surfaces