Developer tools

JSON Schema validator

Check a JSON document against a JSON Schema (draft 2020-12 subset) and get a table of every error with its location, plus a list of any keyword that was not checked.

JSON Schema validator
Esc to restore

Your inputs

A draft 2020-12 schema. Up to 1 MB. References to other documents are listed, never fetched. Nothing is uploaded.

The JSON value to validate. Up to 1 MB.

Only these nine formats are checked; any other format is listed as not checked.

Results update as you type. Larger files run when you press Update result.

Your result

Your result will appear here.

More actions

Your inputs stay in this browser. Nothing is uploaded or saved.

A clear answer. Here’s how.

Checks a JSON document against a JSON Schema with a validator written by hand for a subset of draft 2020-12; nothing is generated or evaluated from your schema. Enforced keywords: type (including lists of types, and 1.0 counts as an integer), enum, const, properties, required, additionalProperties, patternProperties, propertyNames, minProperties, maxProperties, items, prefixItems, minItems, maxItems, uniqueItems, contains with minContains and maxContains, minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, minLength and maxLength (counted in code points), pattern, allOf, anyOf, oneOf, not, if, then, else, dependentRequired, dependentSchemas, unevaluatedProperties, unevaluatedItems, and $ref, $dynamicRef, $defs, $id, $anchor and $dynamicAnchor within the pasted schema. Numbers keep their written digits and are compared as exact decimals, so 19.99 is a multiple of 0.01, 1 equals 1.0, and objects are equal whatever their key order. A pattern is run by a matcher that parses the expression itself and cannot backtrack catastrophically; it reads the subset the specification recommends plus escapes, classes and \p{…}, and a pattern that uses lookahead, lookbehind or a backreference is listed as not checked. Remote references are never fetched and are listed as not checked. Formats are checked only if you ask: date, date-time, time, email, hostname, ipv4, ipv6, uuid and uri (international host names with xn-- labels are checked only as ASCII, not against IDNA rules). Every keyword the tool does not enforce is listed in the table as Not checked: content keywords, leftovers from older drafts such as dependencies and additionalItems, formats it does not know, unknown keywords (often a spelling mistake) and a $schema that names another dialect; the headline then says the document is valid against the checked keywords instead of simply valid. The validator passes every test it is given from the draft 2020-12 JSON Schema Test Suite: 1,864 tests in 430 groups (the keyword files, the reference tests with the suite’s own remote documents supplied by the test, the nine optional format files and eleven optional files on numbers, regular expressions, ids and anchors). Not run: the two files and one reference group that validate against the meta-schema, the 38 internationalised host name tests, and two optional files about draft-07 keywords and custom meta-schemas. It does not check the schema against the meta-schema, so a wrong keyword value is reported only where this tool reads it. Limits: 1,000,000 characters per input, 100 levels of nesting, 6,000,000 evaluation steps (a schema whose branches fan out into the same definitions can multiply the work, and is stopped with a message), 1,000 errors collected and 200 shown.

How this is checked

5 reference checks passed These 5 cases were run when this page was built, on 20 October 2026, and all reproduce within the stated tolerance. The same cases are part of the automated tests that run on every change to Toolmoz. Engine version 1.

See the checks and where each expected answer comes from
  1. Case 1

    Inputs
    JSON Schema { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/product.schema.json", "title": "Product", "description": "A product from Acme's catalog", "type": "object", "properties": { "productId": { "description": "The unique identifier for a product", "type": "integer" }, "productName": { "description": "Name of the product", "type": "string" }, "price": { "description": "The price of the product", "type": "number", "exclusiveMinimum": 0 }, "tags": { "description": "Tags for the product", "type": "array", "items": { "type": "string" }, "minItems": 1, "uniqueItems": true }, "dimensions": { "type": "object", "properties": { "length": { "type": "number" }, "width": { "type": "number" }, "height": { "type": "number" } }, "required": [ "length", "width", "height" ] } }, "required": [ "productId", "productName", "price" ] } JSON document to check { "productId": 1, "productName": "A green door", "price": 12.50, "tags": [ "home", "green" ] }
    Expected, and what Toolmoz gave
    Valid expected Yes, Toolmoz YesErrors expected 0, Toolmoz 0Keywords not checked expected 0, Toolmoz 0headline expected Valid: the document matches the schema, Toolmoz Valid: the document matches the schema
    Where the expected answer comes from
    JSON Schema tutorial, Creating your first schema: the example product at the top of the page is valid against the schema built up in the page (productId 1 is an integer, productName is a string, price 12.50 is above 0, tags has two different strings)
    Allowed difference
    exact
  2. Case 2

    Inputs
    JSON Schema { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/product.schema.json", "title": "Product", "description": "A product from Acme's catalog", "type": "object", "properties": { "productId": { "description": "The unique identifier for a product", "type": "integer" }, "productName": { "description": "Name of the product", "type": "string" }, "price": { "description": "The price of the product", "type": "number", "exclusiveMinimum": 0 }, "tags": { "description": "Tags for the product", "type": "array", "items": { "type": "string" }, "minItems": 1, "uniqueItems": true }, "dimensions": { "type": "object", "properties": { "length": { "type": "number" }, "width": { "type": "number" }, "height": { "type": "number" } }, "required": [ "length", "width", "height" ] } }, "required": [ "productId", "productName", "price" ] } JSON document to check { "productId": 1, "productName": "A green door", "price": 0, "tags": [ "home", "green", "home" ], "dimensions": { "length": 7.0, "width": 12.0, "height": 9.5 } }
    Expected, and what Toolmoz gave
    Valid expected No, Toolmoz NoErrors expected 2, Toolmoz 2headline expected Invalid: 2 errors, Toolmoz Invalid: 2 errors
    Where the expected answer comes from
    Worked by hand from the tutorial schema: price 0 fails exclusiveMinimum 0 (it must be above zero) and the tags home, green, home fail uniqueItems because the first and third are equal; every other keyword is satisfied
    Allowed difference
    exact
  3. Case 3

    Inputs
    JSON Schema { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/product.schema.json", "title": "Product", "description": "A product from Acme's catalog", "type": "object", "properties": { "productId": { "description": "The unique identifier for a product", "type": "integer" }, "productName": { "description": "Name of the product", "type": "string" }, "price": { "description": "The price of the product", "type": "number", "exclusiveMinimum": 0 }, "tags": { "description": "Tags for the product", "type": "array", "items": { "type": "string" }, "minItems": 1, "uniqueItems": true }, "dimensions": { "type": "object", "properties": { "length": { "type": "number" }, "width": { "type": "number" }, "height": { "type": "number" } }, "required": [ "length", "width", "height" ] } }, "required": [ "productId", "productName", "price" ] } JSON document to check { "productName": "A green door", "price": 12.5 }
    Expected, and what Toolmoz gave
    Valid expected No, Toolmoz NoErrors expected 1, Toolmoz 1
    Where the expected answer comes from
    The tutorial schema requires productId, productName and price; productId is missing, so exactly one error (required)
    Allowed difference
    exact
  4. Case 4

    Inputs
    JSON Schema { "items": { "multipleOf": 0.01 } }JSON document to check [ 19.99, 4.001 ]
    Expected, and what Toolmoz gave
    Valid expected No, Toolmoz NoErrors expected 1, Toolmoz 1
    Where the expected answer comes from
    Exact decimal arithmetic: 19.99 = 1999 × 0.01, a whole multiple; 4.001 = 400.1 × 0.01, not a whole multiple (binary floating point gets 19.99 wrong, which is why the tool does not use it)
    Allowed difference
    exact
  5. Case 5

    Inputs
    JSON Schema { "type": "object", "properties": { "a": { "$ref": "https://example.com/other.schema.json" } } }JSON document to check { "a": 1 }
    Expected, and what Toolmoz gave
    Valid expected Yes, against the checked keywords, Toolmoz Yes, against the checked keywordsErrors expected 0, Toolmoz 0Keywords not checked expected 1, Toolmoz 1headline expected Valid against the checked keywords (1 not checked), Toolmoz Valid against the checked keywords (1 not checked)
    Where the expected answer comes from
    By definition of the tool: a reference to another document is never fetched, so it is listed as not checked and nothing else in the schema can fail the value 1 (type object is satisfied by the document)
    Allowed difference
    exact

What this shows: the engine reproduces independently worked values for these cases. It does not prove every possible input is right. To test an answer you were given, see how to check a number; to see what is and is not checked across Toolmoz, see the accuracy ledger.

See a worked example

Worked example

A fixed demonstration, separate from the values you enter above.

JSON Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    },
    "tags": {
      "description": "Tags for the product",
      "type": "array",
      "items": {
        "type": "string"
      },
      "minItems": 1,
      "uniqueItems": true
    },
    "dimensions": {
      "type": "object",
      "properties": {
        "length": {
          "type": "number"
        },
        "width": {
          "type": "number"
        },
        "height": {
          "type": "number"
        }
      },
      "required": [ "length", "width", "height" ]
    }
  },
  "required": [ "productId", "productName", "price" ]
}
JSON document to check
{
  "productId": 1,
  "productName": "A green door",
  "price": 0,
  "tags": [ "home", "green", "home" ],
  "dimensions": { "length": 7.0, "width": 12.0, "height": 9.5 }
}
Check formats
No: formats are annotations (the 2020-12 default)

Example result

Example result
StatusWhere in the documentKeywordProblemWhere in the schemaLine
Error/priceexclusiveMinimumThe value is 0, but it must be greater than 0./properties/price/exclusiveMinimum4
Error/tagsuniqueItemsThe items at positions 0 and 2 are equal, but all items must be different./properties/tags/uniqueItems5

Draft 2020-12 rules, written by hand for this page (no code is generated from your schema). Numbers are compared as exact decimals, “pattern” runs in a linear-time matcher, and remote references are never fetched. Formats are not checked (in 2020-12 they are annotations unless you ask for them).