Browse the docs

Write a memory

Add something durable to company memory.

POST /api/v1/memories

Adds a statement to company memory. It is summarised, indexed and checked against existing memories like any other write, and it is attributed to the key by name.

Only a key the workspace owner marked trusted ("writes without review") adds memory directly. From any other key this call does not create a memory: it creates a proposal for a person to approve, and returns 202 with { "status": "pending_review", "candidateId": "…" }. See Agent memory.

Request

FieldTypeRequiredDescription
contentstringYesThe statement to remember. Up to 20000 characters
scopestringUnless the key can write to exactly one scopeThe scope it belongs in
titlestringNoA short title
sourceUrlstringNoLink to where this came from, for example the published post. Also the memory's identity, see below
tagsstring[]NoLabels for later filtering
curl https://<your-buddhi-host>/api/v1/memories \
  -H "Authorization: Bearer crtx_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "The spring campaign headline is \"Know what your company knows\".",
    "title": "Spring campaign headline",
    "scope": "marketing",
    "sourceUrl": "https://www.linkedin.com/posts/…",
    "tags": ["campaign", "spring"]
  }'

Response

201 Created from a trusted key. From an untrusted key, 202 Accepted:

{ "status": "pending_review", "candidateId": "7b2e…", "duplicate": false }

The rest of this page describes the trusted-key response.

201 Created

{
  "id": "9c4a…",
  "scope": "marketing",
  "conflicts": [
    {
      "id": "e71f…",
      "kind": "contradiction",
      "resolution": "unresolved",
      "applied": false
    }
  ]
}
FieldDescription
idThe new memory's id
scopeThe scope it was stored in
conflictsExisting memories this one contradicted or repeated. Empty when there were none
conflicts[].kindcontradiction, duplicate or stale
conflicts[].resolutionauthority or recency when settled automatically; unresolved when it needs the owner
conflicts[].appliedtrue when the new memory replaced the old one

Proposing with more detail

To propose a memory with a category, a confidence and the evidence behind it, use:

POST /api/v1/memory-candidates
FieldTypeRequiredDescription
contentstringYesThe knowledge to keep, as a standalone statement
titlestringNoA short title
categorystringNodecision, fact (default), customer_feedback, process, task or lesson
scopestringNoA suggestion. The reviewer decides. publishable is ignored
confidencenumberNo0 to 1
evidenceobjectNo{ "note": "…", "links": ["https://…"], "memoryIds": ["…"] }
runIdstringNoYour id for the session, to group proposals

It always returns a proposal, whether or not the key is trusted. GET /api/v1/memory-candidates?status=pending lists what the key has proposed and what became of each.

Sending the same thing twice

When you send a sourceUrl, it identifies the memory within its scope:

You sendResult
The same sourceUrl and the same content200 with the existing memory's id and "duplicate": true. Nothing new is stored
The same sourceUrl with changed content201; the new version replaces the old one, whose id is returned as replaced. The old version is kept as history
No sourceUrlAlways a new memory

So a write-back for a published post is safe to retry: give it the post's link.

Conflicts

Buddhi compares every new memory with similar existing ones.

  • Same scope, or a scope the key may write to: the usual rules apply. A senior author outranks a junior one, and between equals the newer statement wins. The loser is kept as history and no longer recalled.
  • A scope the key may not write to: nothing is replaced. Both memories stay in use, the conflict is recorded as unresolved, and the workspace owner chooses in Conflict Resolution.

So a marketing key that writes "the export feature ships Friday" cannot override engineering's "the export feature ships on the 20th".

What to write

Write what is durable and true for the company:

  • a headline, tagline or positioning that was approved
  • a post or campaign that was published, with its link
  • a decision made while producing content

Do not write drafts, rejected options or generated text nobody approved. Memory is what the company knows, and everything written here can come back as context for the next generation.

Errors specific to this endpoint

StatuscodeMeaning
400missing_contentcontent is empty
400content_too_longcontent is over 20000 characters
400missing_scopescope was omitted and the key can write to more than one scope. The message lists them
400invalid_tagstags is not a list of strings
403scope_not_writableThe key cannot write to that scope, or has read-only access to it