Model and records
Open in
Model and records keeps each Customer's Things: their fields, Relationships, state, full history, files and content. Search, views and metrics are projections, rebuilt from the record and never written.
Capability families
| Family | What it does |
|---|---|
| Things and fields | Each Noun as typed fields with keys, so a record answers at its id and at its !# key |
| Relationships | Links read from either side, with how many each side holds and what a delete does to the other side |
| State | Each Thing's place in its lifecycle, kept on the record and moved only by its Verbs |
| Provenance | Who wrote each value and on what basis: Stated, Inferred or Observed; Observed wins for facts |
| History | Every change as an Event, a read of any record as it stood at any moment, and soft delete with restore |
| Customer fields and Nouns | Fields and Nouns a Customer adds in its own Namespace, inside the limits your file sets |
| Import, export and bulk | Records in and out in bulk, each row checked; a whole Namespace out in an open format |
| Files and documents | Files and media kept with their record; documents generated from records and a template |
| Authored content | Drafts, versions, review and publishing; editions and access tiers, the core of the Content pattern |
| Working together | Comments, mentions, assignment and presence on any record |
| Projections | Search by words and by meaning that respects permissions, views as data, metrics and roll-ups |
Each Customer's records live in its own Namespace: the unit of residency, backup, export and deletion.
Lifecycles and states
| Thing | States | What moves it |
|---|---|---|
| A record | live, deleted, restored | DELETE keeps it; POST / brings it back; only an erase, under its legal rule, removes it |
| A Thing's lifecycle | As the file declares it: opened, qualified, won, lost | Its moves, each guarded by its state and its Role |
| A content item | drafted, reviewed, published, withdrawn | Its author, its reviewer, its schedule; each published version is kept |
| An edition | scheduled, sending, sent | Its schedule; it reaches entitled members only, with a delivery state per member |
| A file | uploading, stored, attached | The upload, a scan, the record it attaches to |
| An import | uploaded, checked, then committed or rejected | Each row is checked first, and a rejected row carries its Problem |
| An export | requested, building, ready, expired | The Customer, or its agent; the link expires, the export is kept |
| A projection | building, current, behind | The Events it reads; a reply says how far behind it is |
Every record move writes its Event: created, updated, deleted and restored, and each lifecycle move its own past form.
What you declare, what the platform does
| You declare | The platform does |
|---|---|
| Nouns, fields, types and keys | Create, get, list, update, delete and restore on each Noun, in each Customer's Namespace, typed on every Interface |
Relationships, with -> and <- | The read from either side: GET /companies/ |
| A lifecycle, as moves | The state on the record, 409 wrong_state with allowed on a wrong move |
A field with a from | The value from its Source or Verb, stamped with its Provenance |
A file field | Upload, storage, a scan, renditions, and a link that respects permissions |
| Views and metrics | Each kept as data, rebuilt from the record, answered over every Interface |
| Nothing else | History, as-of reads, import, export, bulk, search, comments, mentions, assignment and presence |
Example
A proposal kept with each Deal, a view of open Deals, and a metric of won value by month.
import { define } from 'apis.dev'
/** Deals for each Customer, kicked off when won. */
export default define({
name: 'pipeline', domain: 'pipeline.apis.dev',
…
Company: { name: 'string', domain: 'url!#', deals: '<-Deal.company' },
Deal: {
title: 'string', amount: 'decimal(12, 2)', company: '->Company.deals',
proposal: 'file? ', // kept with the record
stage: { open: [], qualify: 'opened', win: 'qualified', lose: ['opened', 'qualified'] },
},
views: { open: { Deal: { stage: ['opened', 'qualified'] }, sort: '-amount' } },
metrics: { won: { sum: 'Deal.amount', where: { stage: 'won' }, by: 'month' } },
offer: { Team: { month: 49, seats: 5, seat: 9 }, 'Deal.open': 0.001 },
})The record as it stood at any moment is one read, at no charge.
HTTP/1.1 200 OK
X-Cost: price= 0, currency= "USD"
X-Request-Id: req_4b8e2a71c90d3f56e1a7
{
"id": "deal_1",
"title": "Pilot",
"amount": "5000.00",
"company": "company_1",
"stage": "opened",
"createdAt": "2026-10-24T09: 10: 00Z",
"updatedAt": "2026-10-24T09: 10: 00Z",
"asOf": "2026-10-24T09: 15: 00Z"
}That is GET /deals/, as getDeal over MCP with at and pipeline deals get deal_1 --at in the CLI.
Contracts with the other subsystems
| Subsystem | What it gives this one | What this one gives back |
|---|---|---|
| Definition and compile | The shape: Nouns, fields, keys, Relationships, lifecycles, renames | The live record each migration is checked against |
| Identity, access and policy | A mask per principal on every field and record | Records, state and Relationships, which the one decision reads |
| Data and Sources | Values from Mappings and Integrations, with their Provenance and licence terms | Fields to write back to a Customer's system; licence terms kept on each value, honoured on export |
| Runtime | The only writes, through one commit gate: the fact, its Event, its meter line and its audit entry together | The record a Verb reads, and the Events every projection and Watch is built on |
| Work | Case files, privilege classes, retention and legal hold | A hold that stops a delete and an erase; a class an ethical wall hides |
| Commerce | Access tiers as Entitlements; a price per read | The read a Meter counts once |
| Interfaces and distribution | Every call that reads or writes | Schemas for OpenAPI, MCP and the SDK; a docs page per Noun; views and forms for the UI contracts |
| Trust and operations | Residency, backups, encryption | Each Namespace to export, restore or erase as one |
What Customers and their agents meet
- A member's day. Create a record, relate it to another, search, move it on, delete one by mistake and restore it, over any Interface.
- Nothing is lost. Every record keeps its history. A read with
atanswers it as it stood, and the change feed reads every change in order. - Their own shape. A Customer's admin adds a field or a Noun in their own Namespace, and it appears on their own Interfaces only.
- Search that respects Roles. A search, a view or a metric never shows what the member may not see. An empty result says why.
- An agent at work. An agent drafts a post, sends it for review, publishes it on approval, and reads each version back.
- Nothing locked in. Export answers the whole Namespace in an open format, files included, at any time.
Every read is rebuilt from one record that only Verbs write, so a search, a view and a reply always agree.