> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usenexio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Records overview

> Understand Records, the plane and family registry behind it, how a typed read is authorized for a person, and what you need before your first call.

**Records** is the platform's typed, authorized read and write layer over a connected system of record. A system of record is the operational system a business runs on. Nexio reads it where you replicate it, in your own warehouse, at request time, under your own access rules, and records the governed writes an application makes beside it in a ledger. Two ideas carry the whole layer:

* A **record family** (family, for short) is a typed set of records with a key and a parent: the record it attaches to, such as a `client` or a `policy`. Reference tables and organization-wide (`org` grain) families have no parent.
* The **access plane** applies your access rules to each person before any query runs, under the `lit` [posture](/data-services/scope#posture) ([Access plane](/data-services/access)).

Routes live under `/api/v1/records`, and a scoped key needs the `records:` capabilities, or `actions:read` and `actions:write` for the action ledger routes. The earlier prefix `/api/v1/book`, the `book:` capabilities and the `X-Nexio-Book-*` headers keep working as aliases.

What Records can read is not a fixed list of business objects. It is a registry of **planes** and **families**:

* A **plane** is one registered source area of a system of record, such as one schema of its warehouse replica. Each plane has a stable key, for example `book` or `rawams_claims`.
* A **family** is one named dataset on a plane. It declares its columns and their types, and a serve grain that says how its rows are bounded to a person. A family is addressed as `{plane}/{family}`.

Nexio registers planes and families for each system-of-record type it supports. The registry is fixed in code: a new plane or family arrives in a Nexio release, and no organization defines its own. The first, and today the only, system-of-record type contributes 14 planes and 103 families; the list is on [Families and the generic read](/data-services/families#the-registry-today).

Records is not an [Engine](/engines/overview) and creates no [Runs](/engines/runs). A read is one synchronous request and one answer. There is nothing to poll.

## How a read works

Every read runs the same five steps:

```text theme={null}
caller intent -> resolved authority -> bounded population -> bounded read -> result and evidence
```

1. **Caller intent.** Your server sends a request with the organization's API key and, when the read is for a person, the person it acts for ([Authority and scope](/data-services/scope)).
2. **Resolved authority.** Nexio resolves that person's scope before it builds any query. Under the `lit` [posture](/data-services/scope#posture) the scope comes from your system of record's own access records ([Access plane](/data-services/access)); under `dark` and `shadow` it comes from the organization's identity mapping.
3. **Bounded population.** The scope becomes predicates on the query, so the population is exactly the rows the person may open. Your filters then narrow it; they can never widen it.
4. **Bounded read.** Nexio reads your warehouse live, at request time, under a statement time budget; many statements also carry a row ceiling.
5. **Result and evidence.** A JSON read carries the rows plus a `serving` block (which connection answered, and when the read ran) and a `scope` block (what scope and selection the rows were served at). Responses under `/api/v1/records` carry an `X-Nexio-Engine-Build` header when the build is stamped, and reads that need `records:read` carry a `Server-Timing` header. If the answer is partial, unavailable or refused, it says so ([Completeness and errors](/data-services/completeness)). A few responses omit a block; the list is [Which responses carry each block](/data-services/completeness#which-responses-carry-each-block).

## Typed, authorized, scoped to a person

* **Typed.** A family serves the column set it declares, in a fixed order. On the generic family read, numeric columns are exact decimal text, never floats.
* **Authorized.** A key reaches Records only with the right capability, and the person's entitlement, derived from your own systems, decides which datasets and fields they may read ([Access plane](/data-services/access)).
* **Scoped to a person.** A read made for a person is bounded to the rows that person may open. A keyed read of a record outside that scope answers 404, exactly like a key that does not exist.

## The generic family read is the core contract

`GET /api/v1/records/families/{plane}/{family}` reads any registered family by name, as columns and rows, under the family's serve grain and the person's scope. No per-family code stands behind it: the route's contracts are built from the registry itself, so a family added to the registry is readable through this route in the release that adds it, unless the registry marks the family as served only by a dedicated read. Today 100 of the 103 families are readable here. An unregistered pair answers 404. This is the one read whose shape follows the registry rather than a fixed business object, so it is the contract to build on. [Families and the generic read](/data-services/families) documents it.

Beside it, a connected system type can also have dedicated routes: registers (paged, filterable lists with totals and facets), keyed reads of one record and its sub-resources, composite reads that compose many families in one call, and document content. They are hand-written for that system type's entities, and the set is defined per system type. The mechanics they share are documented here: [Registers and pagination](/data-services/registers), [Completeness and errors](/data-services/completeness) and [Authority and scope](/data-services/scope).

## Where the data comes from

* **Connected records are not stored in Nexio's database to serve reads.** Reads query your warehouse at request time and are not held to a fixed instant; a few lookups are held in server memory for a short time. Two reads seconds apart can see different data, and so can two statements inside one response when the source changes between them ([Completeness and errors](/data-services/completeness#when-the-data-was-read-the-serving-block)). The notes, tasks and statuses an application records are the exception: they live in Nexio's action ledger and are read from there ([Writes and the action ledger](/data-services/writes)).
* **A connection qualifies** when it is an active Snowflake data connection that binds the datasets the system-of-record type requires. With one qualifying connection, reads use it without further input. With several, send `connection_id` on every read, or the request answers 400 `book_connection_ambiguous`. With none, reads answer 409 `book_unavailable` and [`/records/status`](/data-services/completeness#preflight-with-the-status-read) reports `has_published: false`. Nexio configures the connection with you; see [Connections](/connections/overview).

## Vocabulary

| Term                | Meaning                                                                                           | Defined on                                                                                      |
| ------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Plane               | One registered source area of a system of record, with a stable key.                              | [Families and the generic read](/data-services/families)                                        |
| Family              | One named dataset on a plane, with declared columns and a serve grain.                            | [Families and the generic read](/data-services/families)                                        |
| Serve grain         | How a family's rows are bounded to a person: `policy`, `client`, `table` or `org`.                | [Families and the generic read](/data-services/families#serve-grains)                           |
| Register            | A paged, filterable list over one kind of record, usually with totals and facets.                 | [Registers and pagination](/data-services/registers)                                            |
| Composite read      | One call that composes many families under one authority, with an outcome per family.             | [Completeness and errors](/data-services/completeness#per-family-coverage)                      |
| Scope and selection | The rows a person may read, resolved before the query, and a request-level narrowing inside it.   | [Authority and scope](/data-services/scope)                                                     |
| Seat                | A person's derived authority in one organization.                                                 | [Access plane](/data-services/access)                                                           |
| Acting principal    | The person a trusted server reads or writes for.                                                  | [Authority and scope](/data-services/scope)                                                     |
| Current read        | A read that queries the warehouse's current data at request time; `serving.as_of` is when it ran. | [Completeness and errors](/data-services/completeness#when-the-data-was-read-the-serving-block) |
| Action ledger       | The append-only record of the governed writes your people issue, kept per organization.           | [Writes and the action ledger](/data-services/writes)                                           |

## Who calls it

A trusted server-side application acting for a person. The application authenticates the person, then calls Nexio with the organization's key and names the person in `X-Nexio-Acting-Principal`. The API sends no CORS headers, so browsers cannot call it directly.

| Routes                                                   | Credential                                                       |
| -------------------------------------------------------- | ---------------------------------------------------------------- |
| Reads under `/api/v1/records`                            | The organization's live key, or a scoped key with `records:read` |
| `GET /records/actions`, `/workflows`, `/notes`, `/tasks` | Live key, or `actions:read`                                      |
| `POST /records/actions`                                  | Live key, or `actions:write`                                     |
| `/api/v1/graph`                                          | Live key, or `graph:read`                                        |

A sandbox or test organization key gets 403 `scoped_key_required` on every Records route. Keys and capabilities are described on [Authentication and access](/authentication).

## Writes

Writes are governed commands (notes, tasks, statuses) recorded in Nexio's action ledger. Nothing is written back to the system of record today; the routes that would do so answer 403 `overlay_read_only`. See [Writes and the action ledger](/data-services/writes).

Analyses (`/api/v1/records/analyses`), which run agent-authored read statements under the requesting person's own warehouse identity, are built, not yet enabled; Nexio turns them on per organization.

## Application records

Data your application keeps for itself, beside the connected records, goes in [Application records](/data-services/app-records).

## Your first read

1. Ask Nexio to configure the connection to your warehouse replica, and get a key with `records:read`.
2. Call [`GET /api/v1/records/status`](/data-services/completeness#preflight-with-the-status-read) with the person's principal and email. Check `has_published` and `scope.refused`.
3. Pick a family from [the registry](/data-services/families#the-registry-today) and read its first page with [the generic family read](/data-services/families#read-a-family).
4. Follow `page.next_cursor` until it is `null`.

## Next

<CardGroup cols={2}>
  <Card title="Families and the generic read" href="/data-services/families">Read any registered family by name.</Card>
  <Card title="Authority and scope" href="/data-services/scope">Read on behalf of a person.</Card>
  <Card title="Registers and pagination" href="/data-services/registers">Page through a scoped list.</Card>
  <Card title="Completeness and errors" href="/data-services/completeness">Tell every outcome apart.</Card>
</CardGroup>
