One section per published schema. Click the URL to fetch the raw JSON Schema and validate against it directly.
Top-level brain health card. Counts of entities, contradictions, gaps, and a 0 to 100 composite score.
| Field | Type | Required | Description |
|---|
| score | integer | yes | no description |
| entity_count | integer | yes | no description |
| contradiction_count | integer | yes | no description |
| active_contradictions | integer | yes | no description |
| gap_count | integer | yes | no description |
| stale_count | integer | yes | no description |
| last_run | string | null | no | no description |
| run_count | integer | yes | no description |
| age_days | integer | yes | no description |
| audit_count | integer | yes | no description |
Example
{
"score": 92,
"entity_count": 47,
"contradiction_count": 2,
"active_contradictions": 1,
"gap_count": 3,
"stale_count": 0,
"last_run": "2026-04-29T14:22:10+00:00",
"run_count": 12,
"age_days": 41,
"audit_count": 12
}One data point per audit run for the dashboard sparkline. Sorted oldest to newest.
| Field | Type | Required | Description |
|---|
| history | array | no | no description |
Example
{
"history": [
{
"run_id": "run_abc123",
"started_at": "2026-04-29T14:22:10+00:00",
"score": 92,
"entity_count": 47
}
]
}Ranked search hits with provenance and a coarse workspace health number. Use the answer field as a tight one-sentence summary; fall back to entity.description for the full context. Sprint 18 PR 4 + PR 5 (2026-05-30): /query accepts a new optional request-time `as_of` query parameter (ISO 8601 timestamp) that hard filters chunk retrieval to documents whose `documents.created_at <= as_of` (an INGEST-time cap, distinct from the `since` / `until` authorship window). Opt-in and default-OFF; a request that omits `as_of` is byte for byte identical to the prior brain-v1.4 surface. The response body shape itself is unchanged by the PR 5 bump, so pre-v1.5 SDK clients that never pass `as_of` are completely unaffected; the bump is declared on the wire via the schema_version family at brain-v1.5/query.json. A malformed `as_of` returns 422 at the route boundary. Contradiction-reasoning feature (brain-v1.6, 2026-06-03): /query also accepts a new optional `reason_contradictions` boolean query parameter. When true AND the operator kill-switch is enabled, an additive, post-ACL, never-cached pass attaches a per-result `contradiction` annotation and a top-level `contradiction_advisory` roll-up reasoning over the agent's both-sides-visible, scope + ACL + content-gated open contradictions. Both surfaces are READ-ONLY and never reorder results; they are absent by default (param off, kill-switch off, zero gated survivors, or model failure), so a request that omits `reason_contradictions` is byte for byte identical to the prior brain-v1.5 surface.
| Field | Type | Required | Description |
|---|
| query | string | yes | no description |
| results | array | no | no description |
| total_entities_searched | integer | yes | no description |
| workspace_health | integer | yes | no description |
| error | string | null | no | no description |
| chunk_citations | array | no | no description |
| contradiction_advisory | null | no | no description |
Example
{
"query": "what is the pricing",
"results": [
{
"entity": {
"id": "e_pricing",
"name": "Pricing",
"type": "price",
"description": "Tiered SaaS pricing structure.",
"properties": [
{
"key": "starter_plan",
"value": "$29 per user per month",
"value_type": null,
"confidence": "verified",
"source": "pricing.md"
}
],
"source_documents": [
"pricing.md"
]
},
"relevance": 2,
"answer": "starter_plan: $29 per user per month",
"confidence": "verified",
"source": "pricing.md",
"last_verified": "2026-04-29T14:22:10+00:00"
}
],
"total_entities_searched": 47,
"workspace_health": 92
}Verified facts, prices, and metrics ordered by confidence.
| Field | Type | Required | Description |
|---|
| facts | array | no | no description |
| count | integer | yes | no description |
Example
{
"facts": [],
"count": 0
}Entities of type policy.
| Field | Type | Required | Description |
|---|
| policies | array | no | no description |
| count | integer | yes | no description |
Example
{
"policies": [],
"count": 0
}Entities of type process or service. The agent can execute these as runnable workflows.
| Field | Type | Required | Description |
|---|
| playbooks | array | no | no description |
| count | integer | yes | no description |
Example
{
"playbooks": [],
"count": 0
}Free-form gap descriptions surfaced by the ontology engine.
| Field | Type | Required | Description |
|---|
| gaps | array | no | no description |
| count | integer | yes | no description |
Example
{
"gaps": [
"No documentation for the refund policy.",
"Pricing tier names are inconsistent across two sources."
],
"count": 2
}Entities present in earlier audit runs that did not appear in the most recent run. Used by the inbox triage flow.
| Field | Type | Required | Description |
|---|
| disappeared | array | no | no description |
| count | integer | yes | no description |
Example
{
"disappeared": [
{
"natural_key": "policy:refund",
"name": "Refund policy",
"type": "policy",
"last_seen": "2026-04-22T10:00:00+00:00"
}
],
"count": 1
}Body for POST /api/brain/{workspace_token}/disappeared/archive and POST /api/brain/{workspace_token}/disappeared/mark-expected. natural_key identifies the entity to act on.
| Field | Type | Required | Description |
|---|
| natural_key | string | yes | no description |
Example
{
"natural_key": "policies/refund-policy.md"
}Returned when a disappeared entity has been archived. The entity is removed from the active brain but retained in history.
| Field | Type | Required | Description |
|---|
| archived | boolean | yes | no description |
Example
{
"archived": true
}Returned when a disappeared entity is marked as expected. Future absences of this entity will not raise alerts.
| Field | Type | Required | Description |
|---|
| marked_expected | boolean | yes | no description |
Example
{
"marked_expected": true
}Body for POST /api/brain/{workspace_token}/feedback. feedback_type is one of wrong, incomplete, outdated, correct.
| Field | Type | Required | Description |
|---|
| question | string | yes | no description |
| answer_given | string | yes | no description |
| correct_answer | string | null | no | no description |
| feedback_type | string | yes | One of: wrong, incomplete, outdated, correct |
| source | string | no | no description |
Example
{
"question": "what is our refund policy",
"answer_given": "Refunds are available within 14 days.",
"correct_answer": "Refunds are available within 30 days.",
"feedback_type": "wrong",
"source": "agent"
}Returned after recording a feedback event. Reports any trust state changes and whether a contradiction node was created.
| Field | Type | Required | Description |
|---|
| feedback_id | string | yes | no description |
| feedback_type | string | yes | no description |
| implicated_entity_count | integer | yes | no description |
| contradiction_created | boolean | yes | no description |
| trust_changes | array | no | no description |
| message | string | yes | no description |
Example
{
"feedback_id": "fb_abc123",
"feedback_type": "wrong",
"implicated_entity_count": 1,
"contradiction_created": true,
"trust_changes": [
{
"natural_key": "policy:refund",
"old_state": "verified",
"new_state": "low_trust"
}
],
"message": "Recorded as wrong. 1 entity flagged. Visit /inbox to review."
}Aggregate feedback stats. Surfaces accuracy, trend, the most flagged entities, and the most recent events.
| Field | Type | Required | Description |
|---|
| totals | ref: FeedbackTotals | yes | no description |
| accuracy_pct | integer | null | no | no description |
| trend | string | yes | no description |
| most_flagged_entities | array | no | no description |
| recent_feedback | array | no | no description |
Example
{
"totals": {
"wrong": 3,
"incomplete": 1,
"outdated": 0,
"correct": 12,
"all": 16
},
"accuracy_pct": 75,
"trend": "improving",
"most_flagged_entities": [],
"recent_feedback": []
}Data for the Monday digest email. Email delivery is stubbed (see DECISIONS.md D4); this endpoint returns the data a cron job would render.
| Field | Type | Required | Description |
|---|
| subject | string | yes | no description |
| period_start | string | yes | no description |
| questions_answered | integer | yes | no description |
| wrong_flagged | integer | yes | no description |
| correct_confirmed | integer | yes | no description |
| accuracy_pct | integer | null | no | no description |
| unresolved_contradictions | integer | yes | no description |
| trend | string | yes | no description |
| action_needed | boolean | yes | no description |
| delivery_method | string | yes | no description |
Example
{
"subject": "Your company brain last week",
"period_start": "2026-04-22T00:00:00+00:00",
"questions_answered": 16,
"wrong_flagged": 4,
"correct_confirmed": 12,
"accuracy_pct": 75,
"unresolved_contradictions": 1,
"trend": "improving",
"action_needed": true,
"delivery_method": "data only to email stubbed (see DECISIONS.md D4)"
}Workspace-scoped schema discovery. Lists every published schema for the brain API with its absolute URL.
| Field | Type | Required | Description |
|---|
| schemas | array | no | no description |
Example
{
"schemas": [
{
"name": "health",
"version": "v1",
"url": "https://ceadr.ai/schemas/brain-v1/health.json"
}
]
}Bearer scoped audit trail list response.
Returned by GET /api/brain/{workspace_token}/audit-trail. Cursor
pagination is identical to the admin gated /audit endpoint;
clients can reuse the same opaque cursor handling. ``schema_version``
is the brain-v1 minor version pin and is bumped on a breaking
change.
| Field | Type | Required | Description |
|---|
| entries | array | no | no description |
| next_cursor | string | null | no | no description |
| schema_version | string | no | no description |
Bearer scoped contradictions list. Filtered by the bearer's
workspace and document ACLs; documents the bearer cannot see are
omitted entirely (both sides must be visible for the row to land).
| Field | Type | Required | Description |
|---|
| contradictions | array | no | no description |
| total_visible | integer | yes | no description |
| denied_count | integer | no | no description |
| schema_version | string | no | no description |
Entity trust history surface. Combines ER + survivorship into one
governance grade view that a compliance officer can use to prove
"this is the trust trail behind the merged record".
ACL contract (pre merge ACL fix, 2026 to 05 to 21):
``survivorship_decisions`` rows carry per document data
(``winning_source_document`` plus ``winning_value`` and the
dissenting counterparts). The handler resolves each row's
``winning_doc_id`` plus ``dissenting_doc_id`` against
``acl_repo.filtered_document_ids`` so a row whose winning OR
dissenting document is not visible to the bearer is dropped
wholesale. ``merge_events`` rows carry only entity ids plus
source kind sets so they pass through unchanged. ``total_visible``
counts the surfaced ``survivorship_decisions`` after ACL filter;
``denied_count`` records the dropped count so an agent can detect
governance pressure without leaking which documents were hidden.
Workspaces without ACL rows pass through unchanged (default allow).
| Field | Type | Required | Description |
|---|
| entity_natural_key | string | yes | no description |
| entity_name | string | null | no | no description |
| entity_type | string | null | no | no description |
| entity_id | string | null | no | no description |
| merge_events | array | no | no description |
| survivorship_decisions | array | no | no description |
| total_visible | integer | no | no description |
| denied_count | integer | no | no description |
| schema_version | string | no | no description |
Aggregate governance state for the workspace. Powers a single
agent call that proves "here is the governance posture of the
knowledge surface you can read".
All counts are workspace scoped and reflect what is on disk at
read time. ``backend_ok`` is True when every underlying repo read
returned successfully; False signals at least one repo degraded to
its fail-open zero. The agent can use this to detect governance
coverage outages without 5xx'ing the read.
| Field | Type | Required | Description |
|---|
| document_acls_count | integer | yes | no description |
| documents_with_acls | integer | yes | no description |
| scope_policies_count | integer | yes | no description |
| documents_with_scope_chain | integer | yes | no description |
| document_labels_count | integer | yes | no description |
| documents_with_labels | integer | yes | no description |
| label_buckets | array | no | no description |
| backend_ok | boolean | no | no description |
| schema_version | string | no | no description |
Field-level lineage for one entity, extended with the ER trust
trail (Surface the Moat 5/6, 2026-05-20). Both ``merge_events`` and
``survivorship_decisions`` are additive; clients that ignore them
keep working unchanged.
Pre merge ACL fix (2026 to 05 to 21): ``survivorship_decisions``
rows carry per document data (``winning_source_document`` plus
``winning_value`` and dissenting counterparts) so the lineage
handler filters them against ``acl_repo.filtered_document_ids``
under the same ``CEADR_BRAIN_ENTITY_ACL_ENFORCED`` flag that
gates the existing per document field filter. Rows whose winning
OR dissenting document is denied are dropped wholesale and
counted in ``survivorship_denied_count``. ``merge_events`` carry
only entity ids plus source kind sets so they pass through
unfiltered. ``schema_version`` bumped to ``brain-v1.1`` for the
additive count field so clients pinned to ``1.0`` can detect the
surface change.
| Field | Type | Required | Description |
|---|
| entity_id | string | yes | no description |
| entity_name | string | yes | no description |
| entity_type | string | yes | no description |
| source_kinds | array | no | no description |
| properties | array | no | no description |
| relationships | array | no | no description |
| merge_events | array | no | no description |
| survivorship_decisions | array | no | no description |
| total_visible | integer | no | no description |
| survivorship_denied_count | integer | no | no description |
| schema_version | string | no | no description |
Bearer scoped corrections history.
Rows are ACL filtered on document_external_id; rows the bearer
cannot see are omitted entirely. ``denied_count`` records the
drop so an agent can detect governance pressure without leaking
which documents were hidden.
| Field | Type | Required | Description |
|---|
| corrections | array | no | no description |
| total_visible | integer | yes | no description |
| denied_count | integer | no | no description |
| schema_version | string | no | no description |
Bearer scoped, workspace-wide merge events list.
Entity-ACL filtered UNCONDITIONALLY (not gated behind
``CEADR_BRAIN_ENTITY_ACL_ENFORCED``, diverging from /lineage): an
event whose canonical OR merged entity has no ACL-visible document
is dropped wholesale. ``denied_count`` records the drop so an agent
can detect governance pressure without leaking which entities were
hidden.
| Field | Type | Required | Description |
|---|
| merge_events | array | no | no description |
| total_visible | integer | yes | no description |
| denied_count | integer | no | no description |
| schema_version | string | no | no description |
Forensic JSON for a single doc_id. Bearer callable, ACL
filtered, carrying a Query Proof tuple from
:func:`src.brain_api.query_proof_signer.sign_query_proof`.
``proof_signature`` is an HMAC keyed with a secret only Ceadr
holds, so a customer cannot check it independently.
POST /audit/verify accepts /query proofs only, so there is no
customer facing check for a /why proof today.
Sprint 3 PR 3 ships this under ``brain-v1.3``. The proof tuple
(``proof_id``, ``proof_signature``, ``proof_signing_key_id``) is
populated from the per request ``audit_log`` row appended for
the /why call, identical to the Sprint 2 PR A Query Proof
contract on /query.
Cross workspace doc_ids and doc_ids the bearer cannot see
collapse to HTTP 404 (single response code, per Julian Q2
default OK and spec §7 item 2) to avoid the workspace existence
leak a 403 discriminating between "exists but denied" and "does
not exist" would surface.
| Field | Type | Required | Description |
|---|
| doc_id | string | yes | no description |
| workspace_id | string | yes | no description |
| explain | ref: BrainWhyExplainBlock | yes | no description |
| proof_id | string | null | no | no description |
| proof_signature | string | null | no | no description |
| proof_signing_key_id | string | null | no | no description |
| schema_version | string | no | no description |
Bearer POST /api/brain/{token}/flag-contradiction response.
Ontology Sprint 3 Slice 1 (the ACTING half). An agent flags an
engine-detected contradiction for human adjudication. The flag is a
pending-review item that applies NOTHING; a workspace member resolves
it in /inbox (acknowledge or dismiss only in Slice 1). The response
carries the created flag id + a fixed ``pending_review`` status so the
agent knows the flag is queued, not applied.
Pinned under ``brain-v1.6`` (the live schema tier; not a /query bump
since the /query shape is unchanged, but the NEW bearer route pins its
own response schema per the /why + /merge-events precedent). A
``schemas/brain-v1.6/flag-contradiction.json`` file + a drift guard
lock the shape.
| Field | Type | Required | Description |
|---|
| flag_id | string | yes | no description |
| status | string | no | no description |
| schema_version | string | no | no description |