Skip to content

Model and records

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

FamilyWhat it does
Things and fieldsEach Noun as typed fields with keys, so a record answers at its id and at its !# key
RelationshipsLinks read from either side, with how many each side holds and what a delete does to the other side
StateEach Thing's place in its lifecycle, kept on the record and moved only by its Verbs
ProvenanceWho wrote each value and on what basis: Stated, Inferred or Observed; Observed wins for facts
HistoryEvery change as an Event, a read of any record as it stood at any moment, and soft delete with restore
Customer fields and NounsFields and Nouns a Customer adds in its own Namespace, inside the limits your file sets
Import, export and bulkRecords in and out in bulk, each row checked; a whole Namespace out in an open format
Files and documentsFiles and media kept with their record; documents generated from records and a template
Authored contentDrafts, versions, review and publishing; editions and access tiers, the core of the Content pattern
Working togetherComments, mentions, assignment and presence on any record
ProjectionsSearch 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

ThingStatesWhat moves it
A recordlive, deleted, restoredDELETE keeps it; POST /{nouns}/{id}/restore brings it back; only an erase, under its legal rule, removes it
A Thing's lifecycleAs the file declares it: opened, qualified, won, lostIts moves, each guarded by its state and its Role
A content itemdrafted, reviewed, published, withdrawnIts author, its reviewer, its schedule; each published version is kept
An editionscheduled, sending, sentIts schedule; it reaches entitled members only, with a delivery state per member
A fileuploading, stored, attachedThe upload, a scan, the record it attaches to
An importuploaded, checked, then committed or rejectedEach row is checked first, and a rejected row carries its Problem
An exportrequested, building, ready, expiredThe Customer, or its agent; the link expires, the export is kept
A projectionbuilding, current, behindThe 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 declareThe platform does
Nouns, fields, types and keysCreate, 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/{id}/deals
A lifecycle, as movesThe state on the record, 409 wrong_state with allowed on a wrong move
A field with a fromThe value from its Source or Verb, stamped with its Provenance
A file fieldUpload, storage, a scan, renditions, and a link that respects permissions
Views and metricsEach kept as data, rebuilt from the record, answered over every Interface
Nothing elseHistory, 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.

definition.ts
16 lines
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.

Response
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/deal_1?at=2026-10-24T09:15:00Z, as getDeal over MCP with at and pipeline deals get deal_1 --at in the CLI.

Contracts with the other subsystems

SubsystemWhat it gives this oneWhat this one gives back
Definition and compileThe shape: Nouns, fields, keys, Relationships, lifecycles, renamesThe live record each migration is checked against
Identity, access and policyA mask per principal on every field and recordRecords, state and Relationships, which the one decision reads
Data and SourcesValues from Mappings and Integrations, with their Provenance and licence termsFields to write back to a Customer's system; licence terms kept on each value, honoured on export
RuntimeThe only writes, through one commit gate: the fact, its Event, its meter line and its audit entry togetherThe record a Verb reads, and the Events every projection and Watch is built on
WorkCase files, privilege classes, retention and legal holdA hold that stops a delete and an erase; a class an ethical wall hides
CommerceAccess tiers as Entitlements; a price per readThe read a Meter counts once
Interfaces and distributionEvery call that reads or writesSchemas for OpenAPI, MCP and the SDK; a docs page per Noun; views and forms for the UI contracts
Trust and operationsResidency, backups, encryptionEach 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 at answers 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.