Schema JSON Format
Schemas are stored as the JSON content of pages in the Schema namespace (7474), and returned and accepted by the Schema REST endpoints. For terms like Schema and Property Definition, see the Glossary. A machine-readable JSON Schema for this format is at schemaContentSchema.json; it checks structure only. Per-type value constraints (options, ranges, string formats, uniqueItems) are enforced server-side and reported as validation codes.
Top-Level Structure
{
"description": "Optional description of the schema",
"propertyDefinitions": {
"<property-name>": { ... },
"<property-name>": { ... }
}
}| Field | Type | Required | Description |
|---|---|---|---|
description | string | No | Human-readable description of the schema |
subjectsAreDependent | boolean | No | Whether the Schema's Subjects are Dependent Subjects. Set when the Schema is created: a save that changes it is refused. Omitted when false. |
propertyDefinitions | object | Yes | Map of property names to property definition objects |
Schema references
Wherever a Schema is named — a Subject's schema field, an entry of a relation property's targetSchemas — the value is a reference.
A string names a Schema of this wiki by its page title in the Schema namespace, without the namespace prefix. Any spelling of that title is stored as the title itself — person as Person, Person_name as Person name — so a reference read back can differ from the one written.
A Schema from another Source (ADR 023) is an object instead:
{ "source": "otherwiki", "name": "Company" }source is a source key, written as for a Subject ID. Naming this wiki's own Source is the same reference as the bare name, and is stored as the bare name.
A reference to a Source this wiki does not have resolves to no Schema, reported as schema-not-found.
Property Definition
Every property definition carries the common fields below plus the type-specific fields for its type.
Common Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
type | string | Yes | - | The property type. See Property Types. |
description | string | No | "" | Human-readable description of the property |
required | boolean or object | No | false | Whether a value is required. Accepts a severity. |
default | varies | No | null | Default value when none is provided |
Constraint severity
Every Constraint carries a severity of error or warning, which decides whether violating it can block a write. Write a Constraint either as the bare value, which keeps the default warning, or as an object carrying the severity:
{
"type": "number",
"required": { "severity": "error" },
"minimum": 0,
"maximum": { "value": 100, "severity": "error" }
}Boolean Constraints (required, uniqueItems) take no value in the object form — writing the object at all implies true. multiple constrains when it is false, so its object form carries "value": false. Every other Constraint carries its value under value, including options, whose value is the options array.
The Constraints that accept a severity are required, multiple, minimum, maximum, minLength, maxLength, uniqueItems, and options. Only select, relation and monolingualText check multiple, so a severity on it is inert elsewhere. Severity is a Constraint concept, so it does not apply to Display Attributes such as precision, where it is discarded, nor to the shape-declaring fields type and targetSchemas, where it is rejected when the Schema is saved.
Canonical output emits the bare form whenever the severity is the default, so a Schema that sets no severities round-trips unchanged. Which violation each Constraint produces, and the fixed severities of the codes no Constraint backs, are covered in Validation codes.
Property Types
Text (text)
Plain text values.
| Field | Type | Default | Description |
|---|---|---|---|
multiple | boolean or object | false | Allow multiple values |
uniqueItems | boolean | false | Reject duplicate values (only with multiple) |
minLength | number | null | Minimum trimmed length of each value |
maxLength | number | null | Maximum trimmed length of each value |
{
"type": "text",
"multiple": true,
"uniqueItems": true,
"maxLength": 50
}Text with language (monolingualText)
Text values that each carry the language they are in (ADR 34).
| Field | Type | Default | Description |
|---|---|---|---|
multiple | boolean or object | false | Allow multiple values |
uniqueItems | boolean | false | Reject duplicates, comparing text and language together (only with multiple) |
minLength | number | null | Minimum trimmed length of each text |
maxLength | number | null | Maximum trimmed length of each text |
{
"type": "monolingualText",
"multiple": true,
"uniqueItems": true
}URL (url)
URL values.
| Field | Type | Default | Description |
|---|---|---|---|
multiple | boolean or object | false | Allow multiple values |
uniqueItems | boolean | false | Reject duplicate values (only with multiple) |
Number (number)
Numeric values (integer or float).
| Field | Type | Default | Description |
|---|---|---|---|
precision | number | null | Number of decimal places for display |
minimum | number | null | Minimum allowed value (inclusive) |
maximum | number | null | Maximum allowed value (inclusive) |
{
"type": "number",
"minimum": 0,
"maximum": 100,
"precision": 2
}Select (select)
A fixed set of options the user picks from.
{
"type": "select",
"options": [
{ "id": "opt_draft", "label": "Draft" },
{ "id": "opt_review", "label": "Review" },
{ "id": "opt_approved", "label": "Approved" }
]
}| Field | Type | Default | Description |
|---|---|---|---|
options | SelectOption[] | [] | The allowed options to choose from |
multiple | boolean or object | false | Allow selecting more than one |
Each SelectOption:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Stable identifier, unique within the property. Statements store this. |
label | string | Yes | Display text, unique (case-insensitive, trimmed) within the property. |
On write, a Statement value may be an option id, a label (case-insensitive, trimmed), or a { "id", "label" } object; a mismatched id/label is rejected. Reads and display resolve stored ids back to labels via the current Schema.
Relation (relation)
References to other Subjects.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
targetSchemas | array | Yes | - | One or more distinct references to the Schemas a target Subject may follow |
multiple | boolean or object | No | false | Allow multiple relations |
{
"type": "relation",
"targetSchemas": [ "Person", "Group" ],
"multiple": true
}Either all target Schemas of a relation property declare their Subjects dependent or none does; a save that mixes them is refused. Target Schemas that do not exist, or that you may not read, do not count.
Boolean (boolean)
A true/false value. No type-specific fields; default may be true, false, or null (no default).
{
"type": "boolean",
"default": false
}Date (date)
A calendar date, stored as a strict ISO 8601 YYYY-MM-DD string (no time or timezone; see invalid-date). minimum, maximum, and any default use the same format.
| Field | Type | Default | Description |
|---|---|---|---|
minimum | string | null | Earliest allowed date |
maximum | string | null | Latest allowed date |
DateTime (dateTime)
A date and time, stored as a strict ISO 8601 / xsd:dateTime string with an explicit timezone offset or Z (e.g. 2025-06-15T14:30:00Z; see invalid-datetime). minimum, maximum, and any default use the same format.
| Field | Type | Default | Description |
|---|---|---|---|
minimum | string | null | Earliest allowed datetime |
maximum | string | null | Latest allowed datetime |
REST API
GET /neowiki/v0/schema/{schemaName} wraps this format as { "schema": ... }, or { "schema": null } when the Schema does not exist or you may not read it.
PUT /neowiki/v0/schema/{schemaName} replaces the whole Schema without checking for changes made since you read it. It takes the Schema and an optional comment, used as the edit summary:
{ "schema": { "description": "...", "propertyDefinitions": { ... } }, "comment": "Add a Website property" }It answers with { "schema": ... }, the saved Schema in the same form as GET. An invalid schema is rejected with 400, the reason in messageTranslations.
Complete Example
A "Company" schema with various property types:
{
"description": "A business entity",
"propertyDefinitions": {
"Founded at": {
"type": "number",
"description": "Year the company was founded"
},
"Websites": {
"type": "url",
"multiple": true
},
"Main product": {
"type": "relation",
"targetSchemas": [ "Product" ]
},
"Products": {
"type": "relation",
"targetSchemas": [ "Product" ],
"multiple": true
},
"Status": {
"type": "select",
"options": [
{ "id": "opt_active", "label": "Active" },
{ "id": "opt_inactive", "label": "Inactive" },
{ "id": "opt_acquired", "label": "Acquired" },
{ "id": "opt_dissolved", "label": "Dissolved" }
],
"required": true
},
"World domination progress": {
"type": "number",
"minimum": 0,
"maximum": 100,
"default": 0
}
}
}Related Documentation
- Subject Format — format for the Subject data that follows Schemas.