A collection's schema is { fields: [ … ] }. Each field has a name (the key stored in entry
data), a type, and optional properties. All field definitions share a common base:
{
"name": "string", // required — key in entry.data (1–100 chars)
"type": "…", // required — one of the types below
"label": "Display label", // optional — display label (max 200 chars)
"help": "Helper text", // optional — helper text under the field (max 500 chars)
"required": true
}Type-specific options are:
min / max (text length, number range, or group item count),
pattern (regex, for text), options (for select/multiselect),
relationCollectionId + multiple (for relation), and fields (for group).
NOTE
A collection schema is limited to a maximum of 100 fields in total. The CORS allowlist (allowedOrigins under settings) supports up to 50 origins, with each origin restricted to 255 characters max.
| Type | Data stored in entry.data |
Validation |
|---|---|---|
text |
string | optional min/max length, optional pattern regex |
textarea |
string | optional min/max length |
richtext |
sanitized HTML string | max ~50 KB; sanitized at write time |
number |
number | optional min/max value |
boolean |
boolean / string / number | coerced |
date |
string | ISO date string |
select |
string | must be one of options (single choice) |
multiselect |
string[] | each value one of options |
tags |
string[] | free-form values (no owner-defined options), max 50 × 60 chars |
url |
string | must be a valid URL |
email |
string | must be a valid email |
image |
FileRef object | presence required if required; see Uploads |
file |
FileRef object | presence required if required; see Uploads |
relation |
entry id string, or string[] if multiple |
target entry must exist and belong to the declared target collection |
group |
array of objects | repeating sub-fields; optional min/max item count |
NOTE
All of the above constraints (required, min/max, pattern, options, email/url format,
relation target) are enforced at write time when you create or update an entry. A value that
violates its field's schema is rejected with 422 and a Field "<path>": <message> error rather
than stored as-is. Undeclared extra keys are still accepted and kept.
Text family
text, textarea, url, email, date, richtext store a string. text supports a pattern
regex constraint:
{ "name": "phone", "type": "text", "pattern": "^[+0-9 ]+$" }Number & boolean
{ "name": "price", "type": "number", "min": 0, "max": 100000 }boolean accepts true/false, or a string/number that coerces.
Select types
select stores one value; multiselect stores an array — both constrained to the owner-defined
options list once provided:
{
"name": "role",
"type": "select",
"options": ["Engineer", "Designer", "Sales"]
}tags is deliberately different: free-form values the publisher types in, so it has no options.
Images & files
image and file fields store a FileRef object, not a string:
{
"__file": true,
"mediaId": "media_…",
"name": "ada.jpg",
"size": 204123,
"type": "image/jpeg",
"url": "https://cdn.vlozi.app/…/ada.jpg"
}The value is produced by the upload endpoint before the
entry is saved. When required, the field must be present and non-empty.
Relations
A relation field links an entry to the entries of another collection (self-reference allowed).
It stores an entry id (or an array of ids when multiple is true):
{
"name": "featuredProduct",
"type": "relation",
"relationCollectionId": "col_products",
"multiple": false
}At save time the service verifies each referenced entry exists and belongs to the declared
target collection — a row from the wrong collection is a 422. The target does not need to be
published yet (you can wire a relation while still drafting the target).
At public read time, set ?populate=true to resolve each relation into the referenced entry's
public shape: { id, label, data, publishedAt }. See
Embed & relations for the exact shape and rules.
Groups
A group field holds a repeating list of sub-fields — useful for complex, nested content:
{
"name": "awards",
"type": "group",
"fields": [
{ "name": "year", "type": "number" },
{ "name": "title", "type": "text" }
]
}- Groups can nest (a sub-field can itself be a
group), up to 3 levels deep. - A group field can have at most 30 sub-fields defined in its schema.
- Each level may cap its item count with
min/max. - There is a global safety cap of 1000 group items total across every nested level in one entry —
beyond that, excess items are silently dropped. Per-level
max(default 200) also applies. - A
groupneeds at least one sub-field.
TIP
Prefer a relation over deeper group nesting for anything past a couple of levels — relations
already support arbitrary chain depth and let the same data be reused and edited in one place.