JSON Schema validator
Developer tools
Loading
Loading tool
The tool is loaded only when you open it.
All processing for this tool happens in your browser. Your input is not sent to a server.
About this tool
This tool supports a bounded subset of the selected JSON Schema dialect; unsupported features are explicitly rejected. Check a JSON document against a schema using an explicitly selected Draft 7, 2019-09 or 2020-12 engine. A disposable browser worker parses, compiles and validates both inputs locally, with a two-second deadline that includes startup. Results distinguish invalid data from an unusable schema, unsupported features and an incomplete run. Diagnostic reports include document paths, schema paths and keyword names; they exclude raw values and exception messages, but property names can still reveal sensitive information.
Common uses
- Check sample API payloads for required properties, types and array constraints before integrating a schema.
- Compare dialect behavior without downloading a remote schema or running server-side validation.
- Share a small diagnostic report after reviewing its property-name paths for private information.
How to use it
- 1.Choose the dialect used by your schema. If $schema is present, it must match that selection. The example menu supplies complete schema/document pairs and selects the appropriate dialect.
- 2.Paste a strict JSON schema object or boolean in the first editor, and any JSON value in the document editor. Click Validate; editing either field, changing dialect, loading an example or clearing inputs cancels the previous run and clears its results.
- 3.Read the result status first. For an invalid document, inspect each keyword, document JSON Pointer and schema path. A required-property error points to the containing object; no missing-property value is exported. Copy or download the diagnostic JSON only after reviewing its paths. Timeout, cancellation and safety-limit results do not establish whether a document is valid.
Executable schema and document examples
Valid object
{
"draft": "draft7",
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer",
"minimum": 0
}
},
"required": [
"name"
],
"additionalProperties": false
},
"instance": {
"name": "Avery",
"age": 28
}
}{
"status": "valid",
"keywords": []
}The name is present and both values have the required types. additionalProperties: false would reject an extra property. The input example describes the three UI fields; enter schema and instance separately.
Missing required property
{
"draft": "draft7",
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer",
"minimum": 0
}
},
"required": [
"name"
],
"additionalProperties": false
},
"instance": {
"age": 28
}
}{
"status": "invalid",
"keywords": [
"required"
]
}age is optional, but name is required. The document fails required at the containing object, whose JSON Pointer is the empty string.
String instead of integer
{
"draft": "draft7",
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer",
"minimum": 0
}
},
"required": [
"name"
],
"additionalProperties": false
},
"instance": {
"name": "Avery",
"age": "28"
}
}{
"status": "invalid",
"keywords": [
"type"
]
}The age value is a JSON string, so it fails type at /age. No type coercion changes it to a number.
Duplicate array items
{
"draft": "2019-09",
"schema": {
"type": "array",
"items": {
"type": "integer"
},
"minItems": 2,
"uniqueItems": true
},
"instance": [
1,
1
]
}{
"status": "invalid",
"keywords": [
"uniqueItems"
]
}Both entries are integers and the array has two items, but uniqueItems rejects the duplicate. The diagnostic keyword is uniqueItems.
Local $defs reference
{
"draft": "2020-12",
"schema": {
"$defs": {
"positive": {
"type": "integer",
"minimum": 1
}
},
"type": "object",
"properties": {
"count": {
"$ref": "#/$defs/positive"
}
},
"required": [
"count"
]
},
"instance": {
"count": 3
}
}{
"status": "valid",
"keywords": []
}count resolves to the local #/$defs/positive schema and its value satisfies integer and minimum. No network lookup is needed.
Draft 7 ignores $ref sibling assertions
{
"draft": "draft7",
"schema": {
"$ref": "#/definitions/value",
"definitions": {
"value": {
"type": "string"
}
},
"minLength": 3
},
"instance": "ok"
}{
"status": "valid",
"keywords": []
}Draft 7 uses the referenced string schema and ignores minLength alongside $ref. The two-character document is valid. Compare the next example using identical schema and data.
2020-12 evaluates $ref sibling assertions
{
"draft": "2020-12",
"schema": {
"$ref": "#/definitions/value",
"definitions": {
"value": {
"type": "string"
}
},
"minLength": 3
},
"instance": "ok"
}{
"status": "invalid",
"keywords": [
"minLength"
]
}In 2020-12, minLength next to $ref is also evaluated. The same two-character document fails minLength. definitions is retained here so the example can use the same local reference in both drafts.
Common validation mistakes
- Selecting 2020-12 for a schema that declares Draft 7, or assuming the tool auto-detects the dialect.
- Expecting properties alone to require a property: use required to require its presence.
- Expecting the string "28" to satisfy type: integer; the tool never coerces input types.
- Using an external $ref URL or an unknown extension keyword and assuming it was checked.
- Treating a format annotation as a format assertion, or a timeout as a valid result.
- Sharing a paths-only report without checking the property names it exposes.
Limits and notes
- The supported dialects are Draft 7, 2019-09 and 2020-12. $schema declarations must match the selected dialect. Only fragment references beginning with # are accepted, and they must resolve inside the supplied schema. External schemas are never fetched. Unknown/custom keywords, custom dialects, $vocabulary, $async and OpenAPI nullable are unsupported. A __proto__ entry in a schema map is also rejected because of an engine limitation; document keys remain ordinary input data. Nested $id resources are unsupported; a root $id is allowed. unevaluatedItems and unevaluatedProperties are explicitly unsupported because this local engine does not handle all of its interactions reliably. $dynamicRef, $dynamicAnchor, $recursiveRef and $recursiveAnchor are also unsupported; ordinary local $ref recursion is supported. Percent-encoded slashes (%2F) in reference fragments are unsupported because of engine ambiguity. Use the JSON Pointer escape ~1 for a slash inside a property name. Arrays in dependencies or dependentRequired cannot contain an empty-string property name; required arrays can.
- format is annotation-only in this tool: format: "email" does not reject an invalid email string. No type coercion, default insertion or additional-property removal is performed. A passing result covers the selected dialect and these local checks, not application business rules or a different validator’s configuration.
- Each input is capped at 200,000 UTF-8 bytes, depth 64 and 20,000 JSON values. Regular-expression patterns are capped at 512 characters. Compilation and validation run in a disposable worker with a 2,000 ms deadline including worker startup. Large schemas, recursive references or expensive regular expressions may stop at a limit or time out; no passing result is inferred. The two-second deadline is a browser timer: background-tab scheduling can delay termination. A worker isolates UI execution, not memory usage. Additional complexity limits allow at most 512 schema objects and 512 entries in each direct schema-child list. The conservative estimated-work budget is document JSON value count multiplied by schema object count, capped at 200,000. Errors are nonexhaustive: the validator reports the first failure per evaluated branch, so correcting one error may reveal another. Each run is additionally capped at 50,000 weighted validation work units. Charges account for direct schema-child count and current document collection width, bounding repeated or exponential reference work.
- Duplicate decoded object keys, unsafe integers, non-finite numeric overflow and nonzero underflow to zero are rejected before validation. Other decimals use JavaScript IEEE-754 numbers and can be rounded; this tool does not implement arbitrary-precision JSON arithmetic. Represent exact large identifiers as strings with a matching schema.
- At most 100 diagnostics are returned, with each path limited to 2,048 characters. A truncation notice means details were omitted. The report contains paths and keyword names rather than raw input values, validator parameters or raw parser errors. Paths may contain identifying property names; reports are not anonymized. Inputs are processed in the loaded page and are not uploaded or persistently stored. Cancelling, replacing a run, changing inputs or leaving the tool terminates its worker. Clipboard copies and downloaded files are outside the page’s control. This is a bounded local implementation, not a claim of unrestricted JSON Schema conformance.
Frequently asked questions
Why can the same schema behave differently between drafts?
Keyword semantics evolve. In Draft 7, sibling assertions beside $ref are ignored; in 2019-09 and 2020-12 they are evaluated. The paired examples use the same $ref and minLength schema with "ok": Draft 7 passes, while 2020-12 fails minLength. Tuple syntax also differs: older drafts use an items array, while 2020-12 uses prefixItems.
Does a format: email or date-time rule validate the string here?
No. This tool intentionally treats format as annotation in every selectable dialect. A string can pass even when it is not a valid email address or date-time. If your production validator asserts formats, its result may differ; test there as well.
What is the difference between invalid data and an invalid schema?
Invalid means the document was checked and failed one or more schema assertions. Schema-invalid means the schema could not be parsed, accepted by its meta-schema or compiled. Unsupported, timeout, cancelled and limit outcomes are separate; none of them proves that the document passes or fails its intended schema. unevaluatedItems and unevaluatedProperties are explicitly rejected because the bundled engine can produce incorrect results for some annotation interactions. Use another validator with verified support when your schema requires them. The three dialect choices describe this tool’s bounded validation profile, not unrestricted vocabulary conformance. $dynamicRef, $dynamicAnchor, $recursiveRef and $recursiveAnchor are also unsupported; ordinary local $ref recursion is supported. This is a bounded subset of each selected dialect. Schemas are limited to 512 objects and 512 direct children per schema-child list, with document value count × schema object count capped at 200,000. Diagnostics show the first failure per evaluated branch rather than every violation. Each run is additionally capped at 50,000 weighted validation work units. Charges account for direct schema-child count and current document collection width, bounding repeated or exponential reference work.
Are exported diagnostics safe to publish without checking?
No. Raw values and exception text are omitted, but a property name can contain a person’s name, an identifier or a secret. Review both document and schema paths before sharing. An empty document path refers to the root; JSON Pointer escapes / as ~1 and ~ as ~0. Percent-encoded slashes (%2F) in reference fragments are unsupported because of engine ambiguity. Use the JSON Pointer escape ~1 for a slash inside a property name. Paths returned by referenced validators can be relative to the referenced schema target, rather than the original root.
- JSON Schema: dialect declaration
- JSON Schema: references and $ref siblings
- JSON Schema: array constraints and draft differences
- JSON Schema: object properties and required
- Ajv: JSON Schema support and dialects
- RFC 6901: JSON Pointer