Defining a schema for a record type
Collections let you define what the metadata of a record type should look like. You register a type (for example customers) as a collection, attach a JSON Schema for its metadata, and choose how strictly Runtype validates writes: not at all, with warnings, or by rejecting nonconforming writes. Registering a collection changes nothing until you opt in, so you can adopt schemas gradually on a live workspace.
What a collection is
A collection is a registration for one record type. Its slug matches the record type field, and it carries:
- A display name, description, and icon for the dashboard.
- An optional metadata schema describing the fields records of this type should have.
- A validation mode:
off(default),warn, orenforce. - A schema version and history: every schema change bumps the version and appends a history entry.
Records of a type with no collection, or a collection without a schema, behave exactly as before.
The schema dialect
Collection schemas use a constrained subset of JSON Schema so they stay predictable and portable:
- The root is an
objectwith namedpropertiesand an optionalrequiredlist. - Property types:
string,number,boolean,array, andobject. - One level of nesting: an
objectproperty can have scalar properties, but not deeper objects. - Strings support
enumand aformat(for exampledate-time,email,uri). - Not supported:
$ref,oneOf,pattern, and other advanced keywords. Schemas using them are rejected with per-issue details.
Validation modes
In warn and enforce mode, conforming writes stamp the record with schemaValid: true. You can filter records by the stamp with the schemaValid pseudo-field in record filters to find nonconforming records.
Recommended adoption path
For a type that already has records, move through the modes in order:
- Register the collection. Creation defaults to mode
off, so nothing changes. - Infer a schema from your data. Runtype samples the most recently updated records and proposes a schema with per-field confidence. Nothing is saved.
- Save the schema in
warnmode. Writes keep succeeding; nonconforming ones returnschemaWarningsand stampschemaValid: false. - Dry-run existing records. The validate-existing check reports how many current records would fail, with examples, without writing anything.
- Switch to
enforce. The update response includes anenforceChecksummary of existing records so you can confirm the flip is safe. From then on, bad writes fail with a 422.
Working with collections
Collections are available from every Runtype surface. The examples below walk the adoption path for a customers type.
REST
The response proposes a schema plus a fields array with each field’s type, confidence, presence, and sample values. Review it, then save it:
Once enforcing, a nonconforming record write returns:
SDK
CLI
MCP
Agents connected to the Runtype MCP server can manage collections with the list_collections, get_collection, create_collection, update_collection, delete_collection, infer_collection_schema, validate_collection_records, and get_collection_types tools. The same operations are available as runtype.listCollections(...) and friends in Code Mode.
Generating TypeScript types for a collection
Once a collection has a schema, Runtype can generate TypeScript declarations for it so record metadata is typed end to end.
REST
GET /v1/collections/types.d.ts returns a text/plain declaration file with one interface per schematized collection, plus a declare module '@runtypelabs/sdk' block that augments the SDK’s RecordCollections map.
CLI
Commit the generated file, then regenerate it in CI and diff it against the committed copy to catch collection-schema drift (the same idea as any other generated artifact):
Typed record access
Add the generated file to your project. TypeScript picks up .d.ts files inside your tsconfig include paths automatically, and the declare module block augments the SDK by declaration merging. Then scope record operations to a collection with client.records.from(slug), and metadata is typed to that collection’s schema:
Unregistered slugs fall back to Record<string, unknown>, so from() is always usable. Agents can fetch the same declarations with the get_collection_types MCP tool or runtype.getCollectionTypegen() in Code Mode.
Once a collection has a schema, agents pick up its field names automatically: the runtype://records/collections MCP resource exposes every collection’s schema, and the built-in runtype_record_upsert, runtype_record_get, and runtype_record_list tool descriptions are annotated with each schematized collection’s field names, types, and required flags.
Evolving a schema
Schema updates are classified when you save them:
- Additive changes (new optional fields, widened enums) are always allowed.
- Breaking changes (removing a field, adding a required field, narrowing a type or enum) are rejected while the resulting mode is
enforce, with codeBREAKING_SCHEMA_CHANGE_REQUIRES_WARN_MODE. Drop towarn, migrate your records, then re-enforce.
Every schema change bumps schemaVersion and appends to the history, which you can read with includeHistory=true on the get endpoint.
Collection slugs are immutable. To rename a type you register a new collection and migrate records to the new type.
Deleting a collection
Deleting a collection removes the registration only. Records of the type are not touched; they revert to schemaless behavior. Deleting records is a separate, explicit operation.
Deleting a collection permanently discards its schema and version history.
Next steps
- Filtering and searching records: find nonconforming records with the
schemaValidfilter field - Creating and managing records: create the records your collections govern
- Using records in flows: read and write validated records from flow steps