# Schema Reference

The **schema** is a [JSON Schema](https://json-schema.org/) document that describes the shape of the data your form collects. JSON Forms uses the schema both to pick an appropriate renderer for each property and to validate what customers enter.

This page is a practical tour of JSON Schema as applied to JSON Forms in Prismatic. It covers the types, keywords, and patterns you'll reach for most often, along with notes on how each one influences the generated form. The [JSON Schema specification](https://json-schema.org/) is authoritative for any keyword that isn't called out here.

## Top-level shape[​](#top-level-shape "Direct link to Top-level shape")

A JSON Forms schema is almost always an object with a `properties` map:

Schema shape

```json
{
  "type": "object",
  "properties": {
    "companyName": { "type": "string" },
    "numEmployees": { "type": "integer" }
  },
  "required": ["companyName"]
}

```

The top-level `type` can also be `"array"` when the entire form collects a list of items.

## Supported types[​](#supported-types "Direct link to Supported types")

| `type`    | Default renderer | Notes                                                                                                                                                  |
| --------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `string`  | Text input       | See [formats](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/schema.md#formats) for date, time, password, and so on          |
| `integer` | Number input     | Whole numbers only                                                                                                                                     |
| `number`  | Number input     | Decimal numbers                                                                                                                                        |
| `boolean` | Checkbox         | Set `options.toggle` on the UI schema element to render as a switch                                                                                    |
| `object`  | Nested group     | Typically used to compose form sections                                                                                                                |
| `array`   | Table layout     | Array of objects; Prismatic defaults to a [table layout](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/renderers.md#arrays) |

See the [renderers reference](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/renderers.md) for a complete type-to-renderer mapping.

## Nested objects[​](#nested-objects "Direct link to Nested objects")

Objects nest inside other objects with their own `properties` and `required` arrays. The generated form data preserves the shape exactly - if the schema has a `company` object with `name` and `headcount` properties, the form data will have a `company` object with `name` and `headcount` properties:

Nested object

```json
{
  "type": "object",
  "properties": {
    "company": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "headcount": { "type": "integer" }
      },
      "required": ["name"]
    }
  }
}

```

Nested objects render inline inside their parent layout by default. Wrap them in a [`Group`](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/ui-schema.md#group) in the UI schema to add a visible label and container. For shapes reused in more than one place, see [References with `$ref`](#references-with-ref).

## Formats[​](#formats "Direct link to Formats")

Set `format` on a string property to pick a specialized renderer, a validator, or both.

Prismatic supports these formats:

### `date`[​](#date "Direct link to date")

**Renderer:** Date picker

**Accepted values:** ISO 8601 date strings in `YYYY-MM-DD` form, such as `2026-04-21`.

Use with `formatMinimum` and `formatMaximum` to constrain the selectable range.

### `time`[​](#time "Direct link to time")

**Renderer:** Time picker

**Accepted values:** ISO 8601 time strings in `HH:mm:ss` form, such as `14:30:00`. Fractional seconds (`HH:mm:ss.sss`) and an optional timezone suffix (`Z` or `±HH:mm`) are also accepted.

### `date-time`[​](#date-time "Direct link to date-time")

**Renderer:** Date-and-time picker

**Accepted values:** Full ISO 8601 timestamps combining a date and time with a `T` separator and a timezone suffix, such as `2026-04-21T14:30:00Z`.

### `password`[​](#password "Direct link to password")

**Renderer:** Masked text input

**Accepted values:** Any string. This format affects presentation only - it does not validate content.

### `email`[​](#email "Direct link to email")

**Renderer:** Text input

**Accepted values:** A standard email address in `local-part@domain` form, such as `alex@example.com`.

### `uri`[​](#uri "Direct link to uri")

**Renderer:** Text input

**Accepted values:** An absolute URI that includes a scheme, such as `https://example.com/widgets/42`. Relative URIs are rejected.

### `ipv4`[​](#ipv4 "Direct link to ipv4")

**Renderer:** Text input

**Accepted values:** Four dot-separated integers from `0` to `255`, such as `192.0.2.1`.

### Example[​](#example "Direct link to Example")

Date and password formats

```json
{
  "type": "object",
  "properties": {
    "startDate": { "type": "string", "format": "date" },
    "apiKey": { "type": "string", "format": "password" }
  }
}

```

## Validation keywords[​](#validation-keywords "Direct link to Validation keywords")

Prismatic validates user input against the standard JSON Schema validation keywords. The following are the ones you'll use most often:

| Keyword                                             | Applies to             | Description                                            |
| --------------------------------------------------- | ---------------------- | ------------------------------------------------------ |
| `required`                                          | `object`               | Array of property names that must be present           |
| `minLength` / `maxLength`                           | `string`               | Minimum and maximum string length                      |
| `pattern`                                           | `string`               | Regular expression the input must match                |
| `minimum` / `maximum`                               | `integer`, `number`    | Numeric bounds                                         |
| `exclusiveMinimum` / `exclusiveMaximum`             | `integer`, `number`    | Exclusive numeric bounds                               |
| `multipleOf`                                        | `integer`, `number`    | Value must be a multiple of this number                |
| `formatMinimum` / `formatMaximum`                   | `string` with `format` | Inclusive bounds for date, time, and date-time formats |
| `formatExclusiveMinimum` / `formatExclusiveMaximum` | `string` with `format` | Exclusive bounds for date, time, and date-time formats |
| `minItems` / `maxItems`                             | `array`                | Bounds on the number of items                          |
| `uniqueItems`                                       | `array`                | When `true`, all items must be unique                  |

Validation runs continuously as the customer types. You can change when errors display with the **Validation Mode** setting on the config variable - see [Validation mode](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/ui-schema.md#validation-mode).

For validation that the schema alone can't express, see [JSON Form Validation](https://prismatic.io/docs/integrations/data-sources/json-forms/form-validation.md).

## Default values and pre-filling the form[​](#default-values-and-pre-filling-the-form "Direct link to Default values and pre-filling the form")

To pre-fill a form with initial values, return a `data` property alongside `schema` and `uiSchema` from your data source:

Data source return value with pre-filled data

```json
{
  "schema": {
    /* ... */
  },
  "uiSchema": {
    /* ... */
  },
  "data": {
    "region": "us-east-1",
    "retryCount": 3,
    "enableCache": true
  }
}

```

See [Pre-filling forms with default data](https://prismatic.io/docs/integrations/data-sources/json-forms/using-json-forms.md#pre-filling-forms-with-default-data) for the full pattern.

The schema's `default` keyword is an annotation - it describes what a property's default value would be, but doesn't pre-populate the form. Return `data` from your data source whenever you want the form to open with values already filled in.

## Fixed values with `const`[​](#fixed-values-with-const "Direct link to fixed-values-with-const")

`const` asserts that a property holds a specific value. Its primary use in JSON Forms is inside a `oneOf` array to build dropdowns where the displayed label and the stored value differ:

const inside oneOf

```json
{
  "continent": {
    "type": "string",
    "oneOf": [
      { "title": "North America", "const": "NA" },
      { "title": "Europe", "const": "EU" }
    ]
  }
}

```

See [Dropdowns with `enum` and `oneOf`](#dropdowns-with-enum-and-oneof) for the full pattern.

## Dropdowns with `enum` and `oneOf`[​](#dropdowns-with-enum-and-oneof "Direct link to dropdowns-with-enum-and-oneof")

Two schema patterns produce dropdown menus:

* **`enum`** - a flat array of string values. The customer sees the same value that the config variable stores.
* **`oneOf`** - an array of `{ "title": ..., "const": ... }` objects. The customer sees the `title`; the config variable stores the `const`.

enum

```json
{
  "continent": {
    "type": "string",
    "enum": ["North America", "Europe", "Asia"]
  }
}

```

oneOf with custom values

```json
{
  "continent": {
    "type": "string",
    "oneOf": [
      { "title": "North America", "const": "NA" },
      { "title": "Europe", "const": "EU" },
      { "title": "Asia", "const": "AS" }
    ]
  }
}

```

Use `oneOf` whenever the display label and stored value need to differ, or when you're populating the list from a third-party API and want to store a stable ID.

Add [`options.autocomplete: true`](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/options.md#autocomplete) to the UI schema element to render a `oneOf` dropdown as a type-ahead.

## Arrays[​](#arrays "Direct link to Arrays")

Arrays let the customer add one or more items with the same structure:

Array of objects

```json
{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "channel": { "type": "string" },
      "notification": { "type": "string", "enum": ["Created", "Updated"] }
    },
    "required": ["channel", "notification"]
  }
}

```

By default, arrays render as a [table](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/renderers.md#arrays). Use [`options.layout`](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/options.md#layout) to switch to an accordion instead, or use the [`ListWithDetail`](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/ui-schema.md#listwithdetail) UI type for a master-detail layout.

`minItems`, `maxItems`, and `uniqueItems` apply to the array itself. Validation keywords on `items` apply to each array entry.

## References with `$ref`[​](#references-with-ref "Direct link to references-with-ref")

Prismatic resolves every `$ref` in your schema before rendering the form. This lets you reuse subschemas without worrying about whether a specific renderer resolves references on its own.

Schema with a shared subschema

```json
{
  "type": "object",
  "definitions": {
    "address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" }
      },
      "required": ["street", "city"]
    }
  },
  "properties": {
    "billing": { "$ref": "#/definitions/address" },
    "shipping": { "$ref": "#/definitions/address" }
  }
}

```

## Descriptions and titles[​](#descriptions-and-titles "Direct link to Descriptions and titles")

Both `description` and `title` on a property surface in the UI:

* **`description`** appears as helper text beneath the input.
* **`title`** overrides the auto-generated label (otherwise derived from the property name).

The UI schema's `label` takes precedence over the schema's `title` when both are set. Descriptions show even when the input is not focused unless you set [`options.showUnfocusedDescription: false`](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/options.md#showunfocuseddescription).

## Required fields[​](#required-fields "Direct link to Required fields")

Mark required fields in the parent object's `required` array, not on the field itself:

required

```json
{
  "type": "object",
  "properties": {
    "companyName": { "type": "string" },
    "companyDescription": { "type": "string" }
  },
  "required": ["companyName"]
}

```

Required fields display an asterisk next to their label. Set [`options.hideRequiredAsterisk: true`](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/options.md#hiderequiredasterisk) on a control or layout to suppress the asterisk for that element.

## Composing schemas with `allOf`, `anyOf`, `oneOf`, and `not`[​](#composing-schemas-with-allof-anyof-oneof-and-not "Direct link to composing-schemas-with-allof-anyof-oneof-and-not")

The composition keywords let you validate against multiple subschemas and pull properties from them into the form. JSON Forms walks into these subschemas when a UI schema control scopes a property defined inside one of them, so a property declared inside an `allOf` branch renders just like a top-level property would:

Property defined inside allOf

```json
{
  "type": "object",
  "allOf": [
    {
      "properties": {
        "accountId": { "type": "string" }
      }
    }
  ],
  "properties": {
    "accountName": { "type": "string" }
  }
}

```

UI schema referencing the allOf-defined property

```json
{
  "type": "VerticalLayout",
  "elements": [
    { "type": "Control", "scope": "#/properties/accountName" },
    { "type": "Control", "scope": "#/properties/accountId" }
  ]
}

```

Both controls render, and customer input for `accountId` flows into the form data as expected.

| Keyword | Validation | Renders properties from the subschema?                                                                                                                                                                       |
| ------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `allOf` | Yes        | Yes - scope controls to `#/properties/<name>` and the property resolves.                                                                                                                                     |
| `anyOf` | Yes        | Yes - same resolution as `allOf`.                                                                                                                                                                            |
| `oneOf` | Yes        | Yes for full subschemas *and* in the [dropdown pattern](#dropdowns-with-enum-and-oneof) (`{ "title", "const" }` entries on a string property).                                                               |
| `not`   | Yes        | Not applicable - `not` forbids a shape and doesn't contribute properties. Most useful inside [UI rule conditions](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/rules.md#schema). |

Keep in mind: JSON Forms renders every control the UI schema declares regardless of whether the condition's data matches. Composition keywords influence *validation*, not visibility. For show/hide behavior, use [UI rules](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/rules.md).

For example, `not` inside a rule condition expresses "show this element when the country is anything other than the US":

not in a UI rule

```json
{
  "rule": {
    "effect": "SHOW",
    "condition": {
      "scope": "#/properties/country",
      "schema": {
        "not": { "const": "United States" }
      }
    }
  }
}

```

## Conditional validation with `if` / `then` / `else`[​](#conditional-validation-with-if--then--else "Direct link to conditional-validation-with-if--then--else")

`if` / `then` / `else` lets you apply different validation rules depending on the form data:

Conditional validation

```json
{
  "type": "object",
  "properties": {
    "tier": { "type": "string", "enum": ["free", "paid"] },
    "promoCode": { "type": "string" }
  },
  "if": { "properties": { "tier": { "const": "paid" } } },
  "then": { "required": ["promoCode"] }
}

```

Properties declared inside `then` or `else` subschemas resolve the same way `allOf` properties do - scope a control to `#/properties/<name>` and it renders. What `if` / `then` / `else` *doesn't* do is hide controls based on the condition; every control the UI schema declares stays visible. For conditional visibility, use [UI rules](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/rules.md) instead.

## Keywords Prismatic handles differently[​](#keywords-prismatic-handles-differently "Direct link to Keywords Prismatic handles differently")

A few JSON Schema keywords are worth calling out because their effect on the form isn't obvious:

* **`additionalProperties`** - Prismatic only renders controls for properties you declare in `properties` (or reach through composition keywords), so schema-level `additionalProperties: false` doesn't change the UI. AJV still enforces it during validation when the form data contains keys the schema doesn't cover.
* **`readOnly`** - schema-level `readOnly: true` disables the input control, so the customer can see the value but not edit it. You can also set [`options.readonly`](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/options.md#readonly) on a UI schema element to apply the same effect, including to layouts so an entire group becomes non-editable.
* **`writeOnly`** - Prismatic doesn't use `writeOnly` as a rendering hint. If you need a masked input, use [`"format": "password"`](#password) instead.

## Related pages[​](#related-pages "Direct link to Related pages")

* [UI schema reference](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/ui-schema.md)
* [Renderers reference](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/renderers.md)
* [Options reference](https://prismatic.io/docs/integrations/data-sources/json-forms/reference/options.md)
* [JSON Schema specification](https://json-schema.org/)
