Skip to content

Schema JSON Format

This document describes the JSON format used to store Schema data on pages in the Schema namespace (7474) and returned by the REST API.

For definitions of terms like Schema and Property Definition, see the Glossary.

A JSON Schema for validation is available at src/Persistence/MediaWiki/schemaContentSchema.json.

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

Each property definition in propertyDefinitions has common fields and type-specific fields.

Common Fields

All property types share these fields:

FieldTypeRequiredDefaultDescription
typestringYes-The property type. See Property Types below.
descriptionstringNo""Human-readable description of the property
requiredbooleanNofalseWhether a value is required for this property
defaultvariesNonullDefault value when none is provided

Property Types

Text (text)

Plain text values.

json
{
  "type": "text"
}
FieldTypeDefaultDescription
multiplebooleanfalseAllow multiple values
uniqueItemsbooleanfalseRequire unique values (only meaningful when multiple is true)

Example with options:

json
{
  "type": "text",
  "multiple": true,
  "uniqueItems": true,
  "required": true,
  "description": "Tags for this item"
}

URL (url)

URL values.

json
{
  "type": "url"
}
FieldTypeDefaultDescription
multiplebooleanfalseAllow multiple values
uniqueItemsbooleanfalseRequire unique values

Number (number)

Numeric values (integer or float).

json
{
  "type": "number"
}
FieldTypeDefaultDescription
precisionnumbernullNumber of decimal places for display
minimumnumbernullMinimum allowed value
maximumnumbernullMaximum allowed value

Example with constraints:

json
{
  "type": "number",
  "minimum": 0,
  "maximum": 100,
  "precision": 2,
  "description": "Percentage value"
}

Select (select)

A fixed set of allowed options that users pick from. Each option has a stable ID; stored statement values reference the ID, so renaming an option's label does not break existing data.

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

Each SelectOption:

FieldTypeRequiredDescription
idstringYesStable identifier. Unique within the property. Statements store this.
labelstringYesHuman-readable display text. Unique (case-insensitive, trimmed) within the property.

Stored statement values for a select property are option IDs (not labels). Display and API reads resolve IDs to labels via the current Schema.

On write (create/replace statement), the API accepts either an option id or a label (case-insensitive, whitespace-trimmed). A { "id": ..., "label": ... } object is also accepted when consistent; mismatched id/label is rejected.

Example with multi-select:

json
{
  "type": "select",
  "options": [
    { "id": "opt_red",    "label": "Red" },
    { "id": "opt_green",  "label": "Green" },
    { "id": "opt_blue",   "label": "Blue" },
    { "id": "opt_yellow", "label": "Yellow" }
  ],
  "multiple": true,
  "required": true,
  "description": "Color tags"
}

Relation (relation)

References to other Subjects.

json
{
  "type": "relation",
  "relation": "Has author",
  "targetSchema": "Person"
}
FieldTypeRequiredDefaultDescription
relationstringYes-The relation type name (used in Neo4j as relationship type)
targetSchemastringYes-Name of the schema that target subjects must follow
multiplebooleanNofalseAllow multiple relations

Example:

json
{
  "type": "relation",
  "relation": "Has product",
  "targetSchema": "Product",
  "multiple": true,
  "description": "Products made by this company"
}

Boolean (boolean)

A true/false value, edited via a toggle switch and displayed as "Yes" or "No".

json
{
  "type": "boolean"
}

This type has no type-specific fields beyond the common fields. The default may be true, false, or null (no default).

Example:

json
{
  "type": "boolean",
  "default": false,
  "description": "Whether the company is publicly traded"
}

Reserved Property Types

The following types are defined in the JSON schema but not yet implemented:

  • email - Email addresses
  • phoneNumber - Phone numbers
  • date - Date values
  • time - Time values
  • dateTime - Combined date and time
  • duration - Time durations
  • currency - Monetary values
  • progress - Progress indicators

REST API

Reading Schemas

GET /rest.php/neowiki/v0/schema/{schemaName}

Returns the schema wrapped in a response object:

json
{
  "schema": {
    "description": "...",
    "propertyDefinitions": { ... }
  }
}

Returns {"schema": null} if the schema is not found.

Searching Schema Names

GET /rest.php/neowiki/v0/schema-names/{search}

Returns a list of schema names matching the search term.

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
    }
  }
}