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

Receipts

Every read — /context, /search, /query — returns a receipt id:

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
{
"data": {
"text": "Acme renewed at $120k for 24 months on 2026-03-14.",
"citations": [
{
"source": "hubspot:deal:412",
"slug": "brain-evidence-0dd3e2449851d9ba41924c42bd7a61375a8b78050bfe2ca7192eb918d626236a",
"quote": "Acme renewed at $120k for 24 months."
}
],
"staged": 0,
"warnings": [],
"receipt": "rcp_019ffefe",
"truncated": false
}
}

Log it next to whatever your agent said. It is the difference between “our model probably had the renewal note” and “here is the exact text it was given, at 11:02 on 14 August.”

A receipt belongs to the key that committed it. Fetch it with the same Brain key that made the read — not your management key, and not a second Brain key on the same Brain. Either of those gets a 404: a receipt records which credential a read was served under, and that binding is what makes it evidence rather than a log line anyone could have written.

Terminal window
curl "$API/v1/brains/tenant:acme/receipts/rcp_019ffefe" \
-H "authorization: Bearer $NICIA_BRAIN_KEY"
{
"data": {
"receipt": {
"id": "rcp_019ffefe",
"kind": "context",
"consumerId": "user:4471",
"key": { "id": "key_7f3a1c", "name": "Acme web app" },
"connectionId": "conn_7f3a1c",
"snapshot": {
"brainId": "brain_3a91c7",
"generation": "6f1e4d6b-9f0c-4a21-8f3e-1f1a2b3c4d5e",
"stateVersion": "sv_019ffefe",
"schemaVersion": "nicia-base",
"policyVersion": "pol_nicia_open"
},
"purpose": "ask",
"committedAt": "2026-08-14T11:02:44Z",
"items": [
{
"source": "hubspot:deal:412",
"version": 2,
"status": "active"
}
]
}
}
}

items pins the exact version of every source. If the document has been rewritten twice since, the receipt still resolves to the text that was actually shown.

Same scoping: the key that made the read is the key that can reconstruct it.

Terminal window
curl "$API/v1/brains/tenant:acme/receipts/rcp_019ffefe/now" \
-H "authorization: Bearer $NICIA_BRAIN_KEY"
{
"data": {
"changed": [
{
"source": "hubspot:deal:412",
"shownVersion": 2,
"currentVersion": 4,
"status": "superseded"
}
],
"unchanged": 3,
"deleted": 0
}
}

This answers the question that actually comes up in an incident: the agent told a customer $120k — was that wrong at the time, or has it changed since? Here it was right when it was said.

changed[] names versions rather than text. source plus currentVersion is the address of what the document says now: GET /documents/hubspot:deal:412 serves it. Re-sending a document under the same id counts — it replaces the document, and every receipt that cited the old version reports superseded from that moment. A cited source can also report held: under a legal hold, every item a receipt cited reports held rather than superseded or unchanged, so a hold is never mistaken for “nothing changed.”

Pass a consumerId on any read — /context, /search, or /query — and it is recorded on the receipt:

Terminal window
curl -X POST "$API/v1/brains/tenant:acme/context" \
-H "authorization: Bearer $NICIA_KEY" \
-H "content-type: application/json" \
-d '{ "prompt": "…", "consumerId": "user:4471" }'

consumerId is a label you choose — user:4471, job:nightly-scoring, session:abc — 1 to 512 characters; empty or longer is a 400 naming the field. It is correlation only. It never restricts what a call can reach, so scoping still comes from the key.

When something turns out to have been wrong, write the correction — same document id, or a new warranted fact — rather than quietly forgetting the old number. The next /context is current. The receipt from the old read is stale: GET /receipts/{id}/now reports superseded.

Then name who was told. eventId is the corrected change, not the correction — the original write, from History or from the write’s own change.id / outcome.eventIds:

Terminal window
curl "$API/v1/brains/tenant:acme/corrections/chg_44a1e0/affected-reads" \
-H "authorization: Bearer $NICIA_KEY"
{
"data": {
"observedConsumers": [
{
"connectionId": "conn_7f3a1c",
"consumerId": "user:4471",
"receiptId": "rcp_019ffefe",
"servedAt": "2026-08-14T11:02:44.000Z"
}
],
"candidateRuns": [],
"truncated": false
}
}

That is who was told: every receipted read of the superseded content. observedConsumers is receipt-backed and never claimed exhaustive. candidateRuns is the weaker list — runs the Brain was merely available to — and is never unioned in. truncated means the observed set is a floor.

The knowledge.corrected webhook and this endpoint both cap observedConsumers at 50. When truncated is true, the list is a floor; there is no continuation cursor yet. Subscribe per key or organization-wide. See the changelog.

A receipt records what was served; the context check grades it. In the product, open a served context and run the check: it reports where the sources behind that answer contradict each other (each contradiction finding is judged by a live model before it is shown), where the same wording was sent twice, and where the payload spent budget on words that carried no information.

The check is a report, run after the fact against a payload you already served — it is not a gate in the read path, and nothing blocks or rewrites an answer. It runs on the knowledge you have now, from the receipted reads you have already made: reads served over the API, over MCP, or under a Brain key. Reading a Brain by clicking around the console is not one of them and mints no receipt, so a Brain nobody has queried through a credential yet has nothing here to grade. Once one has, there is nothing to migrate before finding out what your agents are actually reading.

Receipts are retained indefinitely — nothing deletes one. They survive document deletion and Brain deletion, and outlive the Brain they are evidence about — an answer you gave a customer stays explainable after they churn. The full-Brain export bundle deliberately omits canonical read-receipt records; an exported receipt id is a locator, not verifiable provenance after migration.

  • Review — deciding what lands in the first place.
  • Context — where receipts come from.