Skip to content
Beta. This surface may change before GA; breaking changes are dated in the changelog.

Review

A Brain is either open — writes land immediately — or reviewed — writes stage until a human or a trusted service settles them. It is a property of the Brain, never of the caller.

One Brain · chain of custodyIllustrative lifecycle
01Sources
Records
Documents
Agent writes
02Review
ProposedHuman or policy decisionAccept · edit · reject
03Context
Accepted stateCited answer[1] source passage
04Receipt
Verifiedrcp_019fWhat the read consumed
Terminal window
curl -X PATCH "$API/v1/brains/tenant:acme" \
-H "authorization: Bearer $NICIA_KEY" \
-H "content-type: application/json" \
-d '{ "mode": "reviewed" }'

New Brains are open, because a Brain that stages everything answers nothing on its first day. Turn review on when the knowledge starts mattering — typically when an agent you did not write starts producing it, or when a customer will see the answers.

Nothing about how you write. The same call returns a different status:

{
"data": {
"change": {
"id": "chg_44a1e0",
"status": "staged",
"createdAt": "2026-08-14T10:59:41Z"
}
}
}

Branch on change.status, always:

Status Meaning
applied It landed. Readable now.
staged Waiting for a decision. Not readable yet.
rejected The Brain declined it. The request was fine; the content was not.

A rejection is a 200. The request was well-formed and the Brain made a decision — that is not an HTTP error.

Reads tell you the same thing from the other side: every /context response carries staged, so an empty answer distinguishes “nothing known” from “waiting on you.”

Terminal window
curl "$API/v1/brains/tenant:acme/changes?status=staged" \
-H "authorization: Bearer $NICIA_KEY"
{
"data": {
"changes": [
{
"id": "chg_44a1e0",
"status": "staged",
"author": {
"kind": "key",
"id": "key_7f3a1c",
"name": "support-agent"
},
"records": [
{
"id": "bob-smith",
"kind": "person",
"before": { "role": "Head of Platform" },
"after": { "role": "VP Platform" },
"evidence": [
{
"source": "zendesk:ticket:8821",
"quote": "Bob Smith, now VP Platform, confirmed…"
}
]
}
],
"createdAt": "2026-08-14T10:55:12Z"
}
],
"nextCursor": "eyJrIjoi…"
}
}

Every staged change carries the diff and the passage it came from, so a reviewer is deciding about evidence rather than about a model’s assertion.

Terminal window
curl -X POST "$API/v1/brains/tenant:acme/changes/chg_44a1e0/approve" \
-H "authorization: Bearer $NICIA_KEY"
curl -X POST "$API/v1/brains/tenant:acme/changes/chg_44a1e0/reject" \
-H "authorization: Bearer $NICIA_KEY" \
-H "content-type: application/json" \
-d '{ "reason": "Title is from a signature block, not a statement." }'

Approve part of a change by naming what you want:

Terminal window
-d '{ "records": ["bob-smith"], "fields": { "bob-smith": ["role"] } }'

Naming part of a change is a decision about the rest of it, too: any record — or, within a named record, any field — you did not name is declined in this same call. A partial approve settles the whole change at once, so this is final: the producer has to write again for anything declined.

Edit before approving when the substance is right and the wording is not:

Terminal window
curl -X POST "$API/v1/brains/tenant:acme/changes/chg_44a1e0/approve" \
-H "authorization: Bearer $NICIA_KEY" \
-H "content-type: application/json" \
-d '{ "edits": { "bob-smith": { "role": "VP, Platform Engineering" } } }'

The edit is attributed to you, not to the agent that proposed it.

Attribution is derived from the key that made the call — never from a field somebody filled in. “Who approved this” will be answered by the Brain, not by your logging.

Review is a checkpoint, not necessarily a human. A key with the review capability can settle changes, so you can put your own evaluator in front of the queue and only escalate what it is unsure about.

for await (const change of nicia.changes("tenant:acme", { status: "staged" })) {
const verdict = await myEvaluator(change);
if (verdict.confident) {
await nicia.approve("tenant:acme", change.id);
}
// leave the rest for a person
}

mode is the whole of it. A key cannot ask for its writes to skip review, and no request body can either — the Brain’s admission policy decides every write, whoever sent it. That is deliberate: an outcome a caller can select is an outcome an agent can select, and the point of reviewed is that nothing lands without a person.

So there is exactly one lever, and it is on the Brain:

mode What happens to a write
open It lands, and shows up in /changes
reviewed It stages, and waits for a decision

If you want a trusted pipeline writing straight in while agents are reviewed, give them separate Brains rather than separate trust levels inside one. A Brain is cheap, its handle is yours to choose, and two Brains with different modes say plainly what one Brain with per-caller exceptions only implies.

Register a webhook so a staged change reaches your queue instead of waiting to be polled:

Terminal window
curl -X POST "$API/v1/brains/tenant:acme/webhooks" \
-H "authorization: Bearer $NICIA_KEY" \
-H "content-type: application/json" \
-d '{ "url": "https://ops.example/nicia", "events": ["change.staged"] }'

See Webhooks for signature verification and delivery semantics.