> For the complete documentation index, see [llms.txt](https://docs.robotmoney.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.robotmoney.com/platform/wiki-api.md).

# Wiki API

This page is optional for headless integrations.

Natural-language and structured access to the tenant's memory graph. The Wiki is downstream of Ledger and sanctioned Policy read projections. Narrative, evidence-cited recall. It is never the source of truth for balances, transactions, or permissions.

| Operation                        | Endpoint                                   |
| -------------------------------- | ------------------------------------------ |
| Ask a natural-language question  | `POST /v1/wiki/question`                   |
| Get suggested questions          | `GET /v1/wiki/suggested-questions`         |
| Get persisted assistant records  | `GET /v1/assistant/questions`              |
| Search entities                  | `GET /v1/wiki/search`                      |
| Get an entity                    | `GET /v1/wiki/entity/{entity_id}`          |
| Evidence chain for an entity     | `GET /v1/wiki/entity/{entity_id}/evidence` |
| Temporal history for an entity   | `GET /v1/wiki/entity/{entity_id}/history`  |
| Annotate (human correction)      | `POST /v1/wiki/annotate`                   |
| Get the entity-kind JSON Schemas | `GET /v1/wiki/schema`                      |
| List memory pages                | `GET /v1/memory/pages`                     |
| Get a memory page                | `GET /v1/memory/pages/{slug_or_id}`        |
| Regenerate a memory page         | `POST /v1/memory/regenerate`               |
| Search memory pages              | `GET /v1/memory/search`                    |

### Ask a Question

```http
POST /v1/wiki/question
Authorization: Bearer <token>
Content-Type: application/json

{
  "question":             "What did we spend on AWS last quarter, by environment?",
  "as_of":                "2026-03-31T23:59:59Z",
  "max_evidence_depth":   3
}
```

```json
{
  "question": "How many transactions do I have in June 2026?",
  "answered": true,
  "answer": "You have 19 transactions in June 2026.",
  "evidence": [
    {
      "entityType": "transaction",
      "entityId": "tx_01HQ7K3AAAAAAAAAAAAAAAAAAAA",
      "excerpt": "outflow 500.00 USD on 2026-06-12 cp=cp_example vendor payment"
    }
  ],
  "model": "structured-ledger-query",
  "usage": { "inputTokens": 0, "outputTokens": 0 }
}
```

`question` is 1–2000 chars. `max_evidence_depth` defaults to 3 (max 5). Transaction count, sum, and average questions with an unambiguous transaction scope run as deterministic Ledger queries. Listing questions with an explicit `show`, `list`, or `display` intent plus a recency, count, or date bound also route deterministically: transactions and cash flow return transaction rows, while invoice listings return invoice rows. Deterministic active-policy condition questions use a sanitized Policy read projection. Other questions use the LLM path and may incur per-call costs. `answered` is the machine-readable result status: `true` means the response is grounded or deterministic; `false` means `answer` is a refusal rather than an answer. Every response carries cited Ledger or Policy evidence.

### Suggested Questions

```http
GET /v1/wiki/suggested-questions
Authorization: Bearer <token>
```

```json
{
  "suggestions": [
    {
      "intent_id": "transaction_listing",
      "display_text": "Show my last 10 transactions",
      "usage_rank_score": 4
    }
  ]
}
```

This endpoint requires `wiki:read`. It returns only deterministic questions that are eligible against the calling tenant's current Ledger data. An intent with no matching rows is omitted. `usage_rank_score` is the calling tenant's all-time invocation count for that intent, so clients can rank suggestions without sharing usage data between tenants. The deterministic intent registry is the single source for both question execution and this endpoint, so a suggestion cannot advertise a question that the grounded Q\&A layer cannot answer.

`GET /v1/assistant/questions` is a separate, legacy persisted-record feed. It returns rows from `assistant_questions` and does not evaluate deterministic intent eligibility. Clients that need tenant-aware question suggestions must use `GET /v1/wiki/suggested-questions`.

### Search Entities

```http
GET /v1/wiki/search?kind=policy&q=wire&limit=10
Authorization: Bearer <token>
```

```json
{
  "results": [
    {
      "id": "ent_policy_v4",
      "kind": "policy",
      "attributes": { "name": "Wire approval policy v4" },
      "valid_from": "2025-01-15",
      "valid_to": null,
      "provenance": "human_confirmed",
      "confidence": 1.0,
      "source_evidence": ["raw_8231"]
    }
  ],
  "next_cursor": null
}
```

Query params: `kind` (`policy | agent`), `q` (full-text), `semantic` (pgvector), `since`, `until`, `limit` (default 50, max 500), `cursor`. Pass `semantic=<string>` to run a pgvector similarity search instead of (or in addition to) full-text.

Wiki search returns only Wiki-resident kinds. The four Ledger kinds (`account`, `counterparty`, `transaction`, `obligation`) are rejected with `request_params_invalid` and a redirect hint to the corresponding `/v1/ledger/*` endpoint, since financial truth lives in the Ledger, not the Wiki.

### Get an Entity

```http
GET /v1/wiki/entity/{entity_id}?include_neighbors=true&as_of=2026-03-31T23:59:59Z
Authorization: Bearer <token>
```

```json
{
  "entity": {
    "id": "cp_aws",
    "kind": "counterparty",
    "attributes": { "name": "Amazon Web Services", "tax_id": "..." },
    "valid_from": "2025-01-15",
    "valid_to": null,
    "provenance": "extracted",
    "confidence": 0.97,
    "source_evidence": ["raw_8231"]
  },
  "neighbors": [
    { "relation": { "type": "billed_via" }, "entity": { "id": "acct_aws_main", "kind": "account" } }
  ]
}
```

`as_of` enables bitemporal reads. The entity as it was known at that moment.

### Evidence Chain

The full provenance trail behind a Wiki entity:

```http
GET /v1/wiki/entity/{entity_id}/evidence
Authorization: Bearer <token>
```

```json
{
  "entity_id": "cp_aws",
  "chain": [
    {
      "version_valid_from": "2026-05-28T12:00:00.000Z",
      "provenance": "document_extracted",
      "confidence": 0.98,
      "source_evidence": ["rp_001"]
    }
  ]
}
```

### Temporal History

Every version of the entity, oldest first:

```http
GET /v1/wiki/entity/{entity_id}/history
Authorization: Bearer <token>
```

```json
{
  "entity_id": "cp_aws",
  "versions": [
    { "id": "cp_aws", "valid_from": "2025-01-15", "valid_to": "2025-06-01", "attributes": {...} },
    { "id": "cp_aws", "valid_from": "2025-06-01", "valid_to": null,         "attributes": {...} }
  ]
}
```

### Annotate (Human Correction)

A human can correct a Wiki entity or relation; the annotation is applied as a **new temporal version** with `provenance: "human_confirmed"` rather than mutating the prior row.

```http
POST /v1/wiki/annotate
Authorization: Bearer <token>
Content-Type: application/json

{
  "target": "entity",
  "entity_id": "ent_01J0000000000000000000000A",
  "kind": "policy",
  "attributes": { "name": "Updated policy name" },
  "confidence": 1
}
```

The body is `oneOf`: an `EntityAnnotation` with `target: "entity"`, optional `entity_id`, required `kind` (`policy` or `agent`), `attributes`, and optional `confidence`; or a `RelationAnnotation` with `target: "relation"`, required `src`, `dst`, and `kind`, plus `attributes` and optional `confidence`.

```json
{ "annotation_id": "ann_001", "new_version_id": "cp_aws_v3" }
```

### Get the Entity-Kind Schemas

The JSON Schema(s) describing every Wiki entity kind:

```http
GET /v1/wiki/schema?kind=entity/counterparty
Authorization: Bearer <token>
```

`kind` must be prefixed `entity/` or `relation/`; an unprefixed value returns `400 request_params_invalid`. The response uses the same prefixed keys, such as `{ "entity/counterparty": <JSON Schema document> }`. Omit `kind` for the full set of prefixed entity and relation schemas.

### Memory Pages

Memory pages are pre-rendered narrative views (Markdown) over the Ledger graph. "the AWS page," "Q1 cash flow," "vendor X relationship." Browsable and searchable.

```http
GET /v1/memory/pages?page_type=counterparty&q=AWS
Authorization: Bearer <token>
```

```json
{
  "pages": [
    {
      "id": "wp_001",
      "page_type": "counterparty",
      "subject_id": "cp_aws",
      "slug": "amazon-web-services",
      "body_md": "# Amazon Web Services\n...",
      "rendered_at": "2026-05-28T11:00:00Z",
      "source_revision": "rev_4127"
    }
  ]
}
```

`page_type` enum: `account | counterparty | obligation | invoice | agent | policy | monthly_summary | cash_flow`.

| Page type         | Subject                                                              |
| ----------------- | -------------------------------------------------------------------- |
| `account`         | One Ledger account and its balances, transactions, and evidence      |
| `counterparty`    | One customer, vendor, merchant, bank, wallet, or related party       |
| `obligation`      | One payable, receivable, payroll, tax, subscription, loan, or bill   |
| `invoice`         | One invoice-shaped receivable with linked documents and transactions |
| `agent`           | One agent definition or run context page                             |
| `policy`          | One policy document or active-policy summary                         |
| `monthly_summary` | One month of tenant cash movement, balances, invoices, and bills     |
| `cash_flow`       | A cash-flow period or forecast page                                  |

These are the same page types proposal evidence may cite as `wiki_entity` targets. Ledger-backed evidence is still resolved through the Ledger evidence resolver first; Wiki pages provide narrative context, not financial truth.

Get one page by slug or id:

```http
GET /v1/memory/pages/{slug_or_id}
Authorization: Bearer <token>
```

Regenerate a page (after the underlying Ledger has changed):

```http
POST /v1/memory/regenerate
Authorization: Bearer <token>
Content-Type: application/json

{ "slug_or_id": "amazon-web-services" }
```

Search memory pages by content:

```http
GET /v1/memory/search?q=cloud%20overspend&limit=20
Authorization: Bearer <token>
```

```json
{
  "results": [
    { "page": { "id": "wp_001", "slug": "amazon-web-services", ... }, "score": 0.91 }
  ]
}
```

### Provenance Fields

\| Field | Description | | ----------------- | --------------------------------------------------- | -------- | --------- | --------------- | ------------------ | | `evidence_path` | Ledger and Raw refs the answer depends on (Q\&A) | | `source_evidence` | Raw refs the entity was extracted from (entity get) | | `provenance` | `extracted | inferred | ambiguous | human_confirmed | agent_contributed` | | `confidence` | Calibrated 0 to 1 score |

### What's Next

<table data-view="cards"><thead><tr><th></th><th></th><th data-type="content-ref"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>🧠 The Wiki</strong></td><td>The conceptual model.</td><td><a href="/platform/the-wiki.md">The Wiki</a></td><td></td></tr></tbody></table>
