JSON Schema Validator

Paste a JSON Schema and the JSON it should describe, or open the two files, and get every mismatch with its line and column, its path and the schema rule behind it. The check runs inside your browser: neither file is sent anywhere.

JSON Schema Validator

or drop a file here. It stays on this device.

How it works

  1. Paste the schema on the left and the JSON to check on the right, or open the two files (a file named like a schema, or containing "$schema", goes to the schema side; drop a file on an editor to choose the side yourself).
  2. Decide whether "format" keywords such as date, email or uuid should be checked.
  3. Press Validate. The check runs in the background, so the page stays usable; Stop checking ends it, and it stops by itself after 2 minutes. A valid document says so; a schema that relies on something this tool does not check (a keyword it does not support, a format it does not know, or another file or URL, which it never fetches) gives Not fully validated instead; otherwise every problem is listed with line:column, path, message and rule (a rule that no value reaches, with its place in the schema), and selecting a location jumps to it in the editor. Download the report as JSON.

Questions

Which schema keywords are supported?

The validation keywords of draft 2020-12 and draft-07: type, enum, const; properties, patternProperties, additionalProperties, required, propertyNames, minProperties, maxProperties, dependentRequired, dependentSchemas and the older dependencies; items, prefixItems, additionalItems, contains, minContains, maxContains, minItems, maxItems, uniqueItems; minimum, maximum, exclusiveMinimum, exclusiveMaximum (number or the draft-4 boolean form), multipleOf; minLength, maxLength, pattern, format; allOf, anyOf, oneOf, not, if, then, else; and $ref to the schema's own parts by pointer (#/$defs/..., #/definitions/...), by $anchor or by $id, each resolved against the $id of the part it sits in, including recursive ones. Boolean schemas work. Numbers are compared exactly as written, however many digits or however large the exponent: 9007199254740993 is above a maximum of 9007199254740992, 1e400 is a number and never equals null, and 1.0 equals 1. unevaluatedProperties, unevaluatedItems, $dynamicRef and the older $recursiveRef are not supported. When one of them could change the result for your JSON, including inside not, anyOf, oneOf, if or contains, the result says Not fully validated rather than Valid, or than a problem it cannot prove, and names it, because the JSON may still not match (the report gives valid as null and complete as false); with problems found, it says there may be more. $dynamicAnchor and contentSchema, which cannot change the outcome, are only noted. References to other files or URLs are never fetched: such a $ref is named in the notes, and wherever it could decide the outcome, even inside not, anyOf, oneOf, if or contains, the result says Not fully validated (the report gives $ref under unchecked), so paste the referenced definitions into this schema (under $defs, with their $id if they refer to each other by it) to check them. A part of the schema that cannot be applied at all, such as a $ref to a place the schema does not have or with a broken %-escape, a pattern that is not a valid regular expression, a keyword whose value JSON Schema does not allow, or a reference loop through not that the result depends on, is reported as a problem at the value it applies to, wherever it sits: not, anyOf, oneOf, if and contains never turn it into a match. Such a part is reported even where no value of the JSON reaches it (a loop aside, which only a value can show): "type": "strng" under a property the JSON does not have, for one, is reported once, as a problem of the schema itself, with its place in the schema instead of a place in the JSON.

Which formats are checked?

When the box is ticked: date, time, date-time, email, uuid, ipv4, ipv6, hostname, uri, uri-reference and regex, with practical rather than exhaustive rules (an email must look like name@host.tld, a uri needs a scheme and must parse). Any other format name is noted, and because it cannot be checked the result says Not fully validated rather than Valid wherever that format could decide it. Untick the box to treat every format as an annotation, which is what the JSON Schema standard does by default.

How are problems located?

The JSON to check is parsed by this tool, keeping the position of every value, so each problem carries the line and column of the offending value and its JSON Pointer path (for example /items/2/price). A problem about a missing property points at the object that should contain it. A rule of the schema that no value of the JSON reaches has no place in the JSON: its row gives the rule's place in the schema instead (for example #/properties/name/type), and the report gives it no line or column. Invalid JSON on either side is reported with its line and column and the cursor moves there. Duplicate keys are allowed, as in JSON.parse (the last one wins), and mentioned in the notes.

How big can the files be?

Up to 32 MB per side. The check runs in the background, so the page never freezes: on a fast computer a 5 MB document with a typical schema takes about 2 seconds and a 32 MB one about 15, and a slower computer can take several times as long. Stop checking ends a check at any time, and a check stops by itself after 2 minutes, saying nothing about the JSON. Checking also stops at the first problem past 1,000: the result then says 1,000+ problems, the report download lists those 1,000 and says truncated, and the table shows the first 500. A JSON nested several hundred levels deep under a schema that refers to itself can be too deep for the browser to check; the page then says so and where, instead of a result.

Does it work offline?

Once the page has loaded, yes: checking sends and fetches nothing, so you can disconnect and keep working. A check that is stopped is replaced by a second copy of the checker, loaded with the page; after a second stopped check, the page needs the connection to load the checker again.

Is my text uploaded?

No. The page loads a small script into your browser and every operation runs on your device. You can check this yourself in the browser's network panel: after the page has loaded there are no upload requests. Closing the tab discards the text.

Do I need an account or to pay?

No. These basic tools are free and add nothing to your data. The only limits are the tool's own: files up to 32 MB each; a check stops after 2 minutes; checking stops after 1,000 problems, which the report lists, and the table shows the first 500. Within them, the practical limit is your device's memory.

What does this page keep in my browser?

Nothing you open or type. While the tab is open, the tool pages keep a short list of the steps taken in it, in the tab's session storage: the step (page opened, started, succeeded, first success, used again or failed), the tool's name, the time, how many files were used and, for a failure, an error code; never a file name, the contents of a file or your text. It holds at most the latest 200 steps, and the browser deletes it when the tab closes. The page never sends it. Where a Report a problem button is shown, you can attach the last 20 steps to your report; nothing is attached unless you tick that box. In local storage the page keeps only choices you made: a Light or Dark theme until you choose System again, the language you picked with the EN / 中文 switch if it differs from your browser's language, and this tool in your recently used list if you switched that list on at the tools page.

Questions or problems

Found a problem or missing feature? Tell us. Please describe the steps; do not send confidential data.