JSON Schema examples

JSON Schema examples

Cloud_Edition_button.webp

This page provides five JSON Schema validation examples, illustrating use cases such as conditional and alternative field requirements (anyOf and oneOf), schema reuse with references, supporting multiple valid formats for a field, and combining $ref with other validation rules. These examples demonstrate validation patterns and logic that go beyond the standard UI.

See:

  • JSON Schema reference - For details about formal definitions, interoperability considerations, keyword behaviors, and advanced topics.

  • JSON Schema keywords and types - For quick-reference tables and practical guidance on JSON Schema keywords and formats.

Examples

Example 1: Conditional field requirement with anyOf and oneOf

Note!
While anyOf and oneOf may look similar, there is an important difference:

  • anyOf: The record is valid if it matches at least one of the specified rules, even if it matches more than one.

  • oneOf: The record is valid only if it matches exactly one of the specified rules. If it matches more than one rule, validation will fail.

Example - Scenario
A user profile must include at least one contact method: either a mobile number or an email address.

Schema (replace RULE with either anyOf or oneOf):

{ "properties": { "mobile": { "type": "string", "pattern": "^\\+?\\d{10,15}$" }, "email": { "type": "string", "format": "email" } }, "RULE": [ { "required": ["mobile"] }, { "required": ["email"] } ] }

Using anyOf

Schema:

{ "properties": { "mobile": { "type": "string", "pattern": "^\\+?\\d{10,15}$" }, "email": { "type": "string", "format": "email" } }, "anyOf": [ { "required": ["mobile"] }, { "required": ["email"] } ] }

Valid records:

{ "mobile": "+447700900123" }
{ "email": "user@sample.com" }
{ "mobile": "+464388900187", "email": "user2@sample.com" }

(All valid: at least one contact method is present)

Invalid record:

{ "username": "jsmith" }

(Invalid: neither mobile nor email present)

Using oneOf

Schema:

{ "properties": { "mobile": { "type": "string", "pattern": "^\\+?\\d{10,15}$" }, "email": { "type": "string", "format": "email" } }, "oneOf": [ { "required": ["mobile"] }, { "required": ["email"] } ] }

Valid records:

{ "mobile": "+447700900123" }
{ "email": "user@sample.com" }

(Valid: exactly one contact method is present)

Invalid records:

{ "mobile": "+464388900187", "email": "user2@sample.com" }

(Invalid: both contact methods are present, so both rules match — not allowed with oneOf)

{ "username": "jsmith" }

(Invalid: neither contact method is present)

Hint!
When using oneOf, ensure that each rule is mutually exclusive, meaning no single value can match more than one rule. If rules overlap, for example, both rules could match the value 10, the value will be considered invalid because oneOf requires that exactly one rule matches.

If you want to allow values that match multiple rules, use anyOf instead.

Example 2: Schema reuse with $ref and $id - recommended

Example - Scenario
You want to ensure both kWhCharged and kWhEstimated are non-negative integers (0 or greater), using $id for a more readable and reusable schema definition.

Schema:

{ "$defs": { "nonNegativeInt": { "$id": "nonNegativeInt", "type": "integer", "minimum": 0 } }, "properties": { "kWhCharged": { "$ref": "nonNegativeInt" }, "kWhEstimated": { "$ref": "nonNegativeInt" } } }

Valid record:

{ "kWhCharged": 12, "kWhEstimated": 0 }

Invalid record:

{ "kWhCharged": -5, "kWhEstimated": 20 }

(Fails: kWhCharged is less than 0)

Example 3: Schema reuse with $ref (definitions) - legacy

Note!
The $defs and $id approach is recommended for new schemas as it is more readable and aligns with current JSON Schema standards. The older ‘definitions’ pattern is still supported for compatibility with existing schemas.

Example - Scenario
You want to ensure both kWhCharged and kWhEstimated are non-negative integers (0 or greater).

Schema:

{ "definitions": { "nonNegativeInt": { "type": "integer", "minimum": 0 } }, "properties": { "kWhCharged": { "$ref": "#/definitions/nonNegativeInt" }, "kWhEstimated": { "$ref": "#/definitions/nonNegativeInt" } } }

Valid record:

{ "kWhCharged": 12, "kWhEstimated": 0 }

Invalid record:

{ "kWhCharged": -5, "kWhEstimated": 20 }

(Fails: kWhCharged is less than 0)

Example 4: Multiple formats allowed with anyOf

Example - Scenario
A product ID can be either a code (a string of 3 uppercase letters and 3 digits) or an integer from 1000 to 9999.

Schema:

{ "properties": { "productId": { "anyOf": [ { "type": "string", "pattern": "^[A-Z]{3}\\d{3}$" }, { "type": "integer", "minimum": 1000, "maximum": 9999 } ] } } }

Valid record:

{ "productId": "ABC123" }

or

{ "productId": 4567 }

Invalid record:

{ "productId": "abc123" }

(Fails: string does not match pattern; not an integer in range)

Example 5: Combining $ref with other rules (double schema with $ref)

Example - Scenario
A limit field can be either a positive number (reusing a definition) or the string "unlimited".

Schema:

{ "definitions": { "positiveNumber": { "type": "number", "minimum": 0 } }, "properties": { "limit": { "anyOf": [ { "$ref": "#/definitions/positiveNumber" }, { "type": "string", "enum": ["unlimited"] } ] } } }

Valid record:

{ "limit": 50 }

or

{ "limit": "unlimited" }

Invalid record:

{ "limit": -5 }

(Fails: not a positive number nor "unlimited")

Reference links

For more details on using JSON Schema, see JSON Schema reference.