gizmobench

JSON Schema Validator

Paste a schema on the left and the JSON you want checked on the right, and every failure is listed with its pointer in the document, its pointer in the schema and one sentence saying what is wrong. Validation is draft 2020-12, written into this page rather than delegated: it names the keywords it checked and, when your schema uses one it does not implement, it names that too. References resolve inside the schema you paste, so a $ref to an http or https URL is refused with the URL quoted back instead of being fetched, and a schema that refers to itself is followed to a bounded depth and then stopped.

Every failure appears here, with its path in the document and in the schema.

Draft
2020-12
Result
Waiting
Errors
waiting
Refs
Local only
  • id given as the string "42"schema wants an integer
    2 errors: the type and the missing email
  • A $ref to an https URLremote schema
    refused, nothing is fetched
  • A schema that refers to itselfrecursive $ref
    validated to a bounded depth, then stopped
A reference is resolved here or it is refused. A $ref to a pointer, to an $anchor or to an $id declared inside the schema you pasted resolves against that text. A $ref to an http or https URL is refused with the URL quoted back, because fetching it would send your schema somewhere and would let a stranger decide what your document is measured against. A schema that refers to itself is followed while the document keeps getting deeper, then stopped, and the result says so rather than claiming a clean bill of health it never earned.

Common questions

Which draft is this, and which keywords does it actually check?
Draft 2020-12. It checks type, enum, const, required and dependentRequired; the numeric bounds minimum, maximum, exclusiveMinimum, exclusiveMaximum and multipleOf; the string bounds minLength, maxLength and pattern; the array keywords prefixItems, items, contains, minContains, maxContains, minItems, maxItems and uniqueItems; the object keywords properties, patternProperties, additionalProperties, propertyNames, minProperties, maxProperties and dependentSchemas; and the applicators $ref, $defs, allOf, anyOf, oneOf, not and if/then/else, including boolean schemas. It does not implement $dynamicRef, $dynamicAnchor, unevaluatedProperties, unevaluatedItems, the contentEncoding family, or the draft-07 spellings definitions and dependencies. When your schema uses one of those, the page lists it under the result rather than passing over it in silence. It also lists any key in a schema position that is not a draft 2020-12 keyword at all: a misspelt "requird" is a valid annotation by the specification, so it constrains nothing and every document sails through, and that is worth being told.
Will it follow a $ref to another schema on the web?
No, and that is deliberate. A $ref to an http or https URL is refused before any keyword runs, with the URL quoted back and a suggestion: paste the target into $defs and point the $ref at it, for example "#/$defs/user". Nothing is requested from the network, so your schema is never sent anywhere and no stranger gets to decide what your document is measured against. A pointer such as "#/$defs/address", a "#name" reference to an $anchor, and a URL that the schema you pasted itself declares as an $id all resolve locally, because in each case the text is already in front of the checker.
What happens with a schema that refers to itself?
It is followed as long as the document keeps getting deeper, and then it stops. Three limits hold: 64 levels of the document, 250,000 keyword checks, and a guard that refuses to re-enter the same subschema at the same position in the document, which is what catches a schema whose root is simply {"$ref": "#"}. When a limit stops the run the result reads Bounded rather than Valid, and the reason is printed under the stage. Nothing below the limit was checked, and calling that valid would be the one dishonest answer available.
Why is it complaining about my schema instead of checking my document?
Because a schema with a mistake in it usually asserts nothing, and a document sailing through such a schema is worse than an error message. The schema is read first: a type that is not one of the seven JSON Schema types, a required that is not an array of names, a multipleOf of zero, a pattern that is not a valid regular expression, or a subschema that is a number rather than an object all stop the run and name both the keyword and the place in the schema where it sits, so you can go straight to it.
What do the two paths under each error mean?
The first is a JSON pointer into your document and the second is a JSON pointer into your schema. An error reading /id, must be integer, schema: /properties/id/type says the value at /id in the document broke the type keyword at /properties/id/type in the schema. The root of a document has an empty pointer, which reads as nothing at all, so it is printed as (root). Errors come deepest first: a child's failure is listed above the parent's missing-property failure.
Is there a size limit, and how many errors will it list?
Each box takes up to 1,000,000 characters, roughly a megabyte of JSON, and anything longer is refused with the size it received rather than being quietly cut short. The list stops at the first 200 errors and says that more are waiting past that point, so a document with thousands of failures still renders instantly. The Copy button puts the whole report on your clipboard as plain text, paths included.
Does it check format, like email or date-time?
No. In draft 2020-12 format is an annotation by default rather than an assertion, so a string marked "format": "email" is not rejected here for failing to look like an email. That is the specification's own default, and this page states it: whenever your schema uses format, the keyword is listed under the result as present and not checked, so you are never left guessing whether a constraint was applied.
Does my JSON leave the browser?
No. Both boxes are read and checked in your own browser, there is no account and nothing is uploaded, which matters because the document you want validated is usually a real API response or a production record. Your draft is remembered in this browser alone so the page opens where you left it, and the Start over button at the top of the page forgets it.

Validation runs in your browser against JSON Schema draft 2020-12, with the keywords implemented in this page: type, required, enum, const, the numeric, string, array and object bounds, and the $ref, $defs, allOf, anyOf, oneOf, not and if/then/else applicators. It does not assert format and does not implement $dynamicRef, unevaluatedProperties or unevaluatedItems, so every keyword it skipped is listed beside the result. References resolve inside the schema you paste and nowhere else: a $ref to an http or https URL is refused rather than fetched, the instance is followed 64 levels deep and no further, and error text is quoted back as text, never as markup.