Skip to main content

Documentation

Model your first record type

Define the shape of a real document - nested, repeating sections included - publish it, and change it later without migrating by hand.

Before you begin

By the end of this page you will have a record type that stores real data, with a REST API and working screens, and you will have changed its shape once without migrating anything by hand.

You will need: an account with permission to manage schemas, and one real document to model. Use a real one — an actual invoice, claim or intake form. Modelling an imagined example is how you end up with a shape that does not survive contact with the business.

Step 1 — Name the thing you keep

A record type is a kind of thing: invoice, claim, supplier. Its code is lowercase with underscores, and it is permanent — the API path is built from it, so choose the noun the business already uses rather than an abbreviation you will have to explain.

Record types can be arranged in a parent and child hierarchy if that reflects how you actually think about them. If you are unsure, keep it flat; you are not locked out of changing this later.

Step 2 — Build the shape from sections

A schema is a named shape for that record type, built from sections. This is the part worth slowing down for, because it is where most systems force a compromise and this one does not.

A section can contain other sections, and a section can repeat. So an invoice with a header, an address block and any number of line items — each line item carrying its own nested breakdown — is modelled as exactly that. You do not flatten it into columns, and you do not give up validation by dropping it into a free-form blob.

Model the document the way it actually reads. If the paper form has a table that grows, that is a repeating section.

Field types

Nine types are available, and they are the real list:

TypeUse it for
textShort single-line values
long textParagraphs and notes
whole numberCounts, quantities
decimalMoney, measurements
true/falseFlags
dateCalendar dates
date and timeTimestamps
timeTimes of day
structured dataNested values with no fixed shape
A choice field is not a tenth type. It is one of the nine above — usually text — presented as a select, with its options coming from a fixed list or a live source. If you try to create a field whose type is select, the API refuses it.

Each field also carries how it should be presented — around thirty presentation types, including rich text, markdown, tags, phone, cascading select, and file, image and PDF uploads with their own permitted types, size caps and multi-file limits. This is why the form is usable without anyone writing form code: the field already knows how it wants to look.

Per field you can also set: required, unique, searchable, indexed, a default value, and validation rules.

A guardrail you will meet: system field names are reserved. If you try to add a field called id, guid, created_at or similar, it is refused rather than silently shadowing the record's own identifiers.

Choice lists that stay current

A choice list can be fixed, or it can read live from one of four sources: another record type, another field's list, a registered database, or a REST endpoint. You can preview what a source returns before you save the field.

Pointing a choice list at another record type is how relationships are expressed here. Because it resolves at read time, it reflects the data as it is now — not a copy taken when the field was defined.

Long lists load as you type rather than being fetched up front, so a supplier list with thousands of entries does not slow the form down.

Two shortcuts

  • Start from a ready-made structure — address, company, contact, invoice or payment — and adapt it.
  • Start from what you already have. Paste a sample document and the shape is inferred for you, or point at an existing database, pick a table, follow its relationships, and preview before creating anything.

Step 3 — Publish a version

A schema has exactly one editable draft plus every version you have published.

Publishing freezes the version. Records pin to it, integrations read it, and running workflows follow the one they started on. That is what makes the next step safe.

Step 4 — Use it

The moment you publish, the record type has:

  • its own REST URL space — list, read, create, update, delete, bulk and search
  • a schema endpoint per published version, which is how clients and forms stay in step with the model
  • generated screens: a form that handles nested and repeating sections, and a table with server-side paging, sorting, typed filters and saved per-person layouts

No code generation, no redeploy. See The generated API for the developer-facing detail.

Step 5 — Change the shape

This is the step the product exists for, so try it deliberately: add a required field to a schema that already has records.

Analyse before you publish. You are told which changes are breaking, which need data migrated, and which operations keep working. The detected changes include a field added, removed, retyped, or made required or optional.

Then migrate the data. A migration plan is generated with a column map you review before running. Migrations are classified by risk — a no-op, a mechanical copy, a conversion that may lose precision, or one needing a transformation you supply (validated before it runs).

The detail that matters in practice: rows that fail to convert are quarantined individually. One bad row does not stop the migration and is not silently dropped — it is set aside for you to look at.

Once the data has moved on, you can archive the superseded version. That is refused if it would lose rows you have not migrated.

What else you get per schema

Switch these on where they earn it:

  • Record history — a snapshot per write, to a depth you choose, with restore to any retained point. The restore is itself recorded, and identifiers and audit columns are never overwritten by one.
  • Controlled publishing — a record change can wait for a chosen time, or wait for an approver, before it goes live.
  • Full-text search with per-field weighting, and duplicate detection with rules and a similarity threshold that are versioned alongside the schema.
  • Its own database — a busy schema can be pinned to separate provisioned capacity without moving everything else.

Where to go next