Data model reference

Exhaustive reference for records, schemas, documents, folders, lookups, references, and version history: methods, parameters, field types, validation rules, limits, envelope shape, error codes, and an honest "Notes & limits" for each area.

This page does not reproduce the raw endpoint reference — the full request/response shapes are in the generated API reference (OpenAPI / Scalar). Method names below are the Node SDK sub-client methods. The spec is currently at 0.27.0. PATCH and create-by-typeName-alone require SDK 0.26+ (bundled in the CLI and MCP server); all other calls also work on a 0.23 client.

Conventions

The list envelope (FC-01)

List, lookup, and version endpoints return a paginated envelope:

{ "data": [ /* items */ ], "nextCursor": "opaque-string-or-null" }

Drain it by feeding nextCursor back as startFrom until it is null. The cursor is opaque — never construct or offset it. search.content and usage endpoints are not enveloped (they return their own shapes).

Identifiers

typeName, field ids, and lookup field names share one grammar: ^[A-Za-z0-9_-]{1,64}$ — letters (any case), digits, underscore, hyphen; 1–64 characters. camelCase, snake_case, PascalCase, and kebab-case are all valid. The names userId, orgId, and clientId are reserved and may not be redeclared as lookup fields.

Timestamps

Creation and modification timestamps are returned as ISO-8601 UTC strings.

Optimistic concurrency

Records, documents, and folders accept an optional expectedVersion on update/patch. Supply the version you last read; the write is rejected with 409 VERSION_CONFLICT if the entity changed since, leaving it untouched. Omit it for last-write-wins.


Schemas — client.schemas.*

MethodPurpose
createSchema(body)Create a schema.
getSchema({ id })Fetch by id.
updateSchema({ id, body })PUT full-replace (no PATCH).
deleteSchema({ id })Delete.
listSchemas({ startFrom?, limit?, surface? })List (FC-01 envelope).
getSchemaVersions({ id })Version history (FC-01 envelope).

Schema fields

FieldTypeRequiredNotes
typeNamestringyesImmutable after create. Identifier grammar. Unique per tenant+context.
displayNamestringyesHuman-readable name.
descriptionstringno
fieldsFieldDef[]noOmit for a bare schema (no validation).
lookupFieldsLookupDef[]noMax 10 (partner-declared); see lookup notes.
renderHintsmap keyed by fieldIdnoUI hints; does not affect storage/validation.
capabilitiesmap<string,boolean>noauditHistory (default true).
indexModeenumnoHYBRID | SEMANTIC | TEXT | NONE. Type-level default for instances. Omit = no default.
storageProfileenumnoSTANDARD (default) | LOW_LATENCY | LARGE_PAYLOAD.
allowedSurfacesstring[]yesNon-empty. Any of record, document, user, org, client.
activebooleannoDefault true. Inactive schemas reject new record creation.
userId / orgId / clientIdstringnoOwnership defaults for the schema itself.

FieldDef

FieldTypeNotes
fieldIdstringRequired. Identifier grammar.
fieldTypeenumstring | number | boolean | date | enum | array | object | reference.
requiredbooleanEnforced on create.
searchablebooleanField text enters the full-text search lane.
filterablebooleanField available as a search filter (no relevance influence).
descriptionstring
validationobjectValidation rules (below).
enumValuesarrayAllowed values for enum fields.
sensitivebooleanRedact-at-write + search-exclusion + read-masking + blind-indexed lookup.
targetTypeNamestringreference only: the type pointed at (required for references).
targetFieldstringreference only: target lookup field to resolve against (default externalId; must be a unique lookup on the target).
cardinalityenumreference only: one (default) | many.
targetSurfaceenumreference only (required for references): surface the target lives on — record/document/user/org/client.

Validation rules (the validation object)

required, minLength, maxLength, min, max, pattern, email, url, phone, step, multipleOf, minItems, maxItems. Rules are enforced at record write; a violation returns a 400 with a readable message before the record is persisted.

LookupDef

A lookup field is either a bare field name string, or { fieldName, unique }. unique: true enforces one record per value per tenant+context.

RenderHintDef

label, widget (text | textarea | select | date | checkbox), order, section, helpText, displayField (marks the headline field; at most one per schema).

Schema versioning

schemaVersion is a public revision counter: 1 on create, prior + 1 on each update. Records and documents are stamped with the governing schemaVersion at write and keep that value even after the schema evolves. getSchemaVersions returns the immutable version-row history (same envelope and row shape as record versions).

Notes & limits — schemas

  • No PATCH. Schemas are PUT-replace only. Collection fields (fields, lookupFields, renderHints, capabilities) are replaced in full on update — supply the complete intended set; omitted scalar fields are preserved.
  • typeName is immutable after creation.
  • Creating a schema is idempotent by typeName. Re-issuing createSchema for a typeName that already exists returns the existing schema rather than failing, so a provisioning step that runs twice is safe. To change a schema, update it (PUT-replace).
  • A bare schema runs no payload validation; all string values are still text-indexed for search when its index mode permits.
  • Schema-field reference targets are declarable today; write-time existence/type enforcement of references is not yet active — a reference field carries the link but is not yet validated against the target on write.

Records — client.records.*

MethodPurpose
createRecord(body)Create. typeName and/or schemaId (see below).
getRecord({ id })Fetch by id (always full payload).
updateRecord({ id, body })PUT — replace mutable fields; payload replaced in full.
patchRecord({ id, body })PATCH (RFC 7386). SDK 0.26+.
deleteRecord({ id })Hard delete (+ tombstone).
listRecords({ type, userId?, orgId?, clientId?, startFrom?, limit?, includePayload? })List (FC-01 envelope).
lookupRecords({ type, field, value? | from?+to? | prefix?, startFrom?, limit?, includePayload? })Lookup, one mode (FC-01 envelope).
lookupRecordsByBody({ ... })Body-based lookup (sensitive-safe).
getRecordVersions({ id })Version history (FC-01 envelope).
getRecordTombstone({ id })Tombstone for a deleted record.

Create / update fields (RecordRequest)

FieldTypeNotes
typeNamestringThe record type. See type-identification below. Immutable; ignored on update.
schemaIdstringSchema to validate against. See below. Immutable; ignored on update.
payloadobjectValidated against the schema. On PUT, replaces the stored payload in full.
statusstringLifecycle/workflow status (default ACTIVE).
folderIdstringGroup with a folder. Cannot currently be cleared once set.
userId / orgId / clientIdstringOwnership (Vectros UUIDs). Subject to token identity auto-assign.
externalIdstringStable partner id. Immutable. Unique within tenant+context+typeName (idempotent create). Max 256 chars.
indexModeenumPer-record override: HYBRID/SEMANTIC/TEXT/NONE. Immutable after create.
expectedVersionnumberOptimistic concurrency. Ignored on create.

Type identification (SDK 0.26+ either-or): provide typeName or schemaId (at least one). With only typeName, the server resolves the schema (record type is unique per tenant+context). With only schemaId, it resolves the type from the schema. With both, they must agree. A 0.23 client always sends both.

RecordResponse (selected fields)

id, typeName, schemaId, schemaVersion, externalId, payload, payloadExternalized, payloadBytes, status, folderId, userId, orgId, clientId, indexStatus (PENDING_INDEX | INDEXED | FAILED, null for store-only), indexMode, createdBy, createdAt, updatedAt, version.

For an externalized (large) payload, list/lookup responses return only the indexed projection and set payloadExternalized: true; fetch the full payload via by-id GET or pass includePayload: true on the list/lookup call.

Automatic ownership lookups

Every record is automatically lookup-indexed by userId, orgId, and clientId without declaring them and without counting against the 10-field cap — so listRecords({ type, userId }) (etc.) resolve directly.

Notes & limits — records

  • PUT replaces the payload in full — it is not deep-merged. Use PATCH (0.26+) for a true partial payload update.
  • PATCH patchable keys: payload, status, folderId, userId, orgId, clientId, expectedVersion. Immutable keys (typeName, schemaId, externalId, indexMode) are rejected if present. Within payload, a key set to null is deleted; a top-level patchable field (such as status or folderId) set to null is not a delete — it is rejected with 400. Clearing a top-level field is not supported.
  • typeName is immutable after creation. To change a record's type, write a new record and delete the old one.
  • folderId cannot currently be cleared once set.
  • Delete is hard delete — there is no soft-delete status that lingers in the index.
  • Batch write / lookup / get are reserved and not yet implemented (they return a 501 not_implemented). Do not depend on them.

Documents — client.documents.*

MethodPurpose
ingestDocument(body)Inline text ingest.
uploadDocument(body)Request a presigned upload URL (file path).
getDocument({ id })Fetch by id.
getDocumentText({ id })Retrieve stored raw text (requires storeText: true).
getDocumentDownloadUrl({ id })Presigned download URL for a file-backed document.
updateDocument({ id, body })PUT — full replace; text re-ingests.
patchDocument({ id, body })PATCH (RFC 7386). SDK 0.26+.
deleteDocument({ id })Hard delete (+ tombstone).
listDocuments({ userId?, orgId?, clientId?, startFrom?, limit? })List (FC-01 envelope).
lookupDocuments(...) / lookup-by-bodyLookup on a schema-bound document's lookup fields.
getDocumentVersions({ id })Version history (FC-01 envelope).

Ingest / update fields (DocumentRequest)

FieldTypeNotes
titlestringRequired.
textstringInline ingest body. Required on POST ingest; on PUT/PATCH it re-ingests write-through.
indexModeenumHYBRID/SEMANTIC/TEXT/NONE. Optional if the bound schema sets a default; otherwise required. Fixed at creation.
storeTextbooleanDefault false. When true, the raw text is retrievable via getDocumentText.
folderIdstringDefaults to the context root. Cannot be cleared once set.
payloadobjectStructured data (records parity). Validated + lookup-indexed when schemaId is set; undeclared keys pass through as free-form, filterable in search. Replaced in full on PUT.
schemaIdstringOptional schema to validate + lookup-index the payload against.
userId / orgId / clientIdstringOwnership (Vectros UUIDs).
externalIdstringStable partner id. Immutable. Unique within tenant+context (idempotent ingest). Max 256 chars.
expectedVersionnumberOptimistic concurrency. Ignored on create.

Upload handshake (uploadDocument)

uploadDocument returns uploadUrl and expiresAt. PUT the raw bytes to uploadUrl without an Authorization header, set Content-Type to the file's MIME type, then poll getDocument until status is INDEXED.

DocumentResponse (selected fields)

id, title, externalId, status (PENDING_UPLOAD | UPLOADED | EXTRACTING | PENDING_INDEX | INDEXED | STORED | FAILED), indexMode, storeText, folderId, payload, payloadExternalized, schemaId, schemaVersion, textBytes, userId, orgId, clientId, fileType, fileSize, createdAt, lastModified, version.

Notes & limits — documents

  • PUT replaces the payload in full; PATCH (0.26+) merges. PATCH patchable keys: title, text, storeText, folderId, schemaId, userId, orgId, clientId, payload, expectedVersion. indexMode and externalId are immutable and rejected.
  • An update re-runs the indexing pipeline; old content is removed from the index as the new content is written.
  • getDocumentText requires the document to have been ingested with storeText: true.
  • The presigned PUT must omit the Authorization header — the URL itself carries the grant.

Folders — client.folders.*

MethodPurpose
createFolder(body)Create (optionally under a parent).
getFolder({ id })Fetch by id.
updateFolder({ id, body })PUT — name/description/ownership.
patchFolder({ id, body })PATCH (RFC 7386). SDK 0.26+.
deleteFolder({ id })Delete (rejects non-empty).
listFolders({ userId?, orgId?, clientId?, startFrom?, limit? })List (FC-01 envelope).
getFolderVersions({ id })Version history (FC-01 envelope).

Create / update fields (FolderRequest)

FieldTypeNotes
namestringRequired.
descriptionstringOptional.
parentFolderIdstringApplied at create only; ignored on update. Omit to create under the context root.
slugstringStable, sibling-unique slug; derived from the name when omitted. Lowercase letters/digits/hyphens. Immutable.
userId / orgId / clientIdstringOwnership.
expectedVersionnumberOptimistic concurrency. Ignored on create.

FolderResponse (selected fields)

id, name, description, parentFolderId (null only for a true root), slug, depth (0 at root), isProtected, userId, orgId, clientId, createdAt, lastModified, version.

Notes & limits — folders

  • No move / reparent. parentFolderId is fixed at creation; there is no operation to relocate a folder in the hierarchy.
  • Delete rejects a non-empty folder with a 400 — remove children first.
  • The context root folder is protected (isProtected: true) and created lazily on first folder interaction. Unparented folders are placed under it, so a folder created without a parent still has a non-null parentFolderId (the root's id).
  • PATCH patchable keys: name, description, userId, orgId, clientId, expectedVersion. slug and parentFolderId are immutable and rejected.

Lookups & references

Lookup modes

Exactly one mode per call:

ModeParametersConstraints
exactvalueAny lookup field. Sensitive fields must use the body variant.
rangefrom + toBoth required. Inclusive, ascending. Non-sensitive fields only.
prefixprefixString, non-sensitive fields only. Ascending.

Supplying zero or more than one mode is a 400. Range with only one bound is a 400. Prefix on a non-string field is a 400.

Unique vs non-unique (enumeration)

  • A unique lookup field returns at most one record and is enforced unique on write.
  • A non-unique lookup field is an enumeration — it returns every record sharing the value, paginated via the { data, nextCursor } envelope.

Sensitive-field lookup (body variant)

For a sensitive field, the exact value must not travel in a URL. The GET lookup rejects value on a sensitive field and directs you to the body-based variant, where the value travels in the request body and is blind-indexed server-side. Range and prefix are not available on sensitive fields (a blind-indexed value has no usable order).

References

A reference field links to another record: it declares targetTypeName (required), targetField (default externalId; must be a unique lookup on the target), cardinality (one/many), and targetSurface. The platform can additionally maintain per-field reverse-reference rows (opt-in) to index the inverse direction.

Notes & limits — lookups & references

  • Partner-declared lookup fields are capped at 10 per schema (the three automatic ownership lookups do not count).
  • The reverse-reference list endpoint is not yet available — you cannot query back-references through the API today.
  • Reference targets are declarable now; write-time existence/type enforcement of a reference against its target is not yet active.

Version history — getRecordVersions / getDocumentVersions / getSchemaVersions / getFolderVersions

Each returns the FC-01 { data, nextCursor } envelope of immutable version rows for an audited entity.

Version-row fields

FieldTypeNotes
idstringVersion-row id.
changeTypeenumCREATE | UPDATE | DELETE.
previousContentstringJSON-stringified snapshot of the state prior to this change. Populated on UPDATE/DELETE; null on CREATE. JSON.parse to inspect.
previousVersionnumberVersion number before this change; null on CREATE.
changeReasonstringCaller-supplied or system-derived reason.
changedBystringId of the user / key responsible.
createdAtstringISO-8601 timestamp of the row.
changedFieldsobjectField-level diff: summary, changed field names, count, per-field old→new detail. Null on CREATE.

Audit capability & retention

  • Audit history is governed per schema by capabilities.auditHistory (default true). Setting it false stops recording the change-history trail for that type's data; it never deletes or affects the records/documents themselves. Tombstones on delete are recorded regardless.
  • Version rows are written asynchronously (typically 1–3 seconds after a write returns) — poll briefly if you read history immediately after a write.
  • Audit and version history are retained compliantly; heavy historical content is externalized to a write-once, retention-governed store, and the history forms a tamper-evident continuity chain. The full retention and integrity posture lives in ../operations-trust/compliance.md.

Errors

The platform returns a uniform error contract. Common cases for the data model:

StatusMeaning (data-model context)
400Validation error: schema-field violation, bad identifier, multiple/zero lookup modes, range/prefix on a sensitive field, prefix on a non-string field, delete of a non-empty folder, immutable field present in a PATCH, or a top-level field set to null in a PATCH.
404 / "not found"The entity does not exist, or belongs to another tenant/context, or is out of the caller's token scope — a single uniform shape (the message never distinguishes these).
409 VERSION_CONFLICTexpectedVersion did not match — the entity changed since you read it; it is left untouched.
501 not_implementedA reserved-but-unbuilt operation (batch record write/lookup/get).

Where to go next