Content model

Field types

The eleven field types, their options, and how values are stored.


Every field has name, type, and label, and may set help, required (checked when publishing, so drafts may be incomplete), hidden (not shown in the admin form), and unique (unique within the collection and locale). The type decides validation, filtering, search, and the admin widget.

  • text: a string. Options { multiline?, maxLength? }. Indexed for search.

  • richtext: TipTap JSON (an object or its JSON string). Indexed as plain text.

  • number: options { integer?, min?, max? }.

  • boolean

  • date: an ISO string. Option { withTime? }.

  • select: options { choices: [{ value, label }], multiple? }.

  • tags: a list of strings, trimmed and de-duplicated by the engine. GET /:collection/_tags?field= lists the tags in use with counts.

  • media: a media id, or a list with { multiple: true }.

  • relation: the id of a document in { collection }, or a list with multiple. Expand with ?include=field; access to the target is checked per field.

  • json: any JSON. { schema } names a zod schema the host registered in createCMS({ jsonSchemas }).

  • spec: a json-render spec, checked by the host's site.specValidator.

Documents

Field values live under data and never mix with system fields. Unknown keys are rejected.

{
  "id": "…",
  "collection": "posts",
  "status": "draft",               // draft | in_review | published
  "hasUnpublishedChanges": false,
  "locale": "en",
  "translationKey": "…",
  "data": { "title": "Hello", "slug": "hello" },
  "createdBy": "…", "updatedBy": "…",
  "createdAt": "…", "updatedAt": "…",
  "publishedAt": null
}