Early developmentNot everything described here has shipped yet.

Skip to content

Schema JSON Format

Schemas are stored as the JSON content of pages in the Schema namespace (7474), and returned 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

json
{
  "description": "Optional description of the schema",
  "propertyDefinitions": {
    "<property-name>": { ... },
    "<property-name>": { ... }
  }
}
FieldTypeRequiredDescription
descriptionstringNoHuman-readable description of the schema
propertyDefinitionsobjectYesMap of property names to property definition objects

Property Definition

Every property definition carries the common fields below plus the type-specific fields for its type.

Common Fields

FieldTypeRequiredDefaultDescription
typestringYes-The property type. See Property Types.
descriptionstringNo""Human-readable description of the property
requiredboolean or objectNofalseWhether a value is required. Accepts a severity.
defaultvariesNonullDefault 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:

json
{
  "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. Every other Constraint carries its value under value, including options, whose value is the options array.

The Constraints that accept a severity are required, minimum, maximum, minLength, maxLength, uniqueItems, and options. 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, multiple, relation, and targetSchema, 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.

FieldTypeDefaultDescription
multiplebooleanfalseAllow multiple values
uniqueItemsbooleanfalseReject duplicate values (only with multiple)
minLengthnumbernullMinimum trimmed length of each value
maxLengthnumbernullMaximum trimmed length of each value
json
{
  "type": "text",
  "multiple": true,
  "uniqueItems": true,
  "maxLength": 50
}

URL (url)

URL values.

FieldTypeDefaultDescription
multiplebooleanfalseAllow multiple values
uniqueItemsbooleanfalseReject duplicate values (only with multiple)

Number (number)

Numeric values (integer or float).

FieldTypeDefaultDescription
precisionnumbernullNumber of decimal places for display
minimumnumbernullMinimum allowed value (inclusive)
maximumnumbernullMaximum allowed value (inclusive)
json
{
  "type": "number",
  "minimum": 0,
  "maximum": 100,
  "precision": 2
}

Select (select)

A fixed set of options the user picks from.

json
{
  "type": "select",
  "options": [
    { "id": "opt_draft",    "label": "Draft" },
    { "id": "opt_review",   "label": "Review" },
    { "id": "opt_approved", "label": "Approved" }
  ]
}
FieldTypeDefaultDescription
optionsSelectOption[][]The allowed options to choose from
multiplebooleanfalseAllow selecting more than one

Each SelectOption:

FieldTypeRequiredDescription
idstringYesStable identifier, unique within the property. Statements store this.
labelstringYesDisplay 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.

FieldTypeRequiredDefaultDescription
relationstringYes-The relation type name
targetSchemastringYes-Name of the Schema that target Subjects must follow
multiplebooleanNofalseAllow multiple relations
json
{
  "type": "relation",
  "relation": "Has product",
  "targetSchema": "Product",
  "multiple": true
}

Boolean (boolean)

A true/false value. No type-specific fields; default may be true, false, or null (no default).

json
{
  "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.

FieldTypeDefaultDescription
minimumstringnullEarliest allowed date
maximumstringnullLatest 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.

FieldTypeDefaultDescription
minimumstringnullEarliest allowed datetime
maximumstringnullLatest 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. There is no write endpoint; create or edit a Schema by editing its page in the Schema namespace.

Complete Example

A "Company" schema with various property types:

json
{
  "description": "A business entity",
  "propertyDefinitions": {
    "Founded at": {
      "type": "number",
      "description": "Year the company was founded"
    },
    "Websites": {
      "type": "url",
      "multiple": true
    },
    "Main product": {
      "type": "relation",
      "relation": "Has main product",
      "targetSchema": "Product"
    },
    "Products": {
      "type": "relation",
      "relation": "Has product",
      "targetSchema": "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
    }
  }
}