json

FormatValidateConvert

Start over?

This clears both panes. Unsaved changes in either document are lost.

Replace that document?

This writes the matches into the other pane. What is there now is lost.

Load JSON from a URL

Your browser fetches it directly — the request goes to that site, never to us.

    ↑ ↓ to move · Enter to run · Esc to close

    Keyboard shortcuts

    Send feedback

    Questions, bug reports and feature requests are all welcome. A bug report is easiest to act on with the shape of the document that caused it — never send anything confidential.

    Email us

    Contact page, in a new tab, so this page stays as it is.

    Settings

    Indent

    Format and Sort keys write it, and Tab in Code view types it.

    Code text size
    14 px

    Code view and generated code.

    Wrap long lines
    Left pane opens in
    Right pane opens in

    In a new tab and after New. A view you choose in a pane is still remembered.

    JSON Schema Validator

    On the left pane · one documentOn one document
    0
    0

    About the validator

    JSON Schema Validator: check a document against a schema.

    Your document never leaves the browser.

    Put a JSON document on the left and a draft-07 JSON Schema on the right, and see what fails and where, marked on the document itself — in your browser, with nothing uploaded and no remote reference fetched. Already have a document open and want a schema drafted from it? Open the JSON editor and take Generate → JSON Schema → Validate with this, which lands you back here with both panes filled.

    What a schema checks that a parser cannot

    1

    Schema

    {
      "type": "object",
      "required": ["name", "age"],
      "properties": {
        "name": { "type": "string" },
        "age": {
          "type": "integer",
          "minimum": 18
        }
      }
    }
    2

    Document

    {
      "name": 7,
      "age": 16
    }
    3

    Failures

    $.name  Expected a string, found a number.
    $.age  Must be at least 18.

    A parser answers one question, and it is the smaller one: is this text JSON at all. It will accept an id that arrived as the string “42” where a number was meant, a record whose postcode is missing, a status field holding a word your service has never heard of, and a bare object where your code expects an array of them. All four parse, and all four break something further down.

    A JSON Schema is where you write down what the document is supposed to contain — which properties are required, what type each value takes, how long a string may be, which of a fixed set of words a field may hold. Checking a document against one turns the answer from “yes, that is JSON” into “yes, that is what you were expecting” — or into a list of the exact places where it is not.

    draft-07, and what happens to a 2020-12 schema

    1

    Schema

    {
      "$schema":
        "https://json-schema.org/draft/2020-12/schema",
      "type": "object"
    }
    2

    Draft

    2020-12, read as draft-07

    The evaluator here implements draft-07, the draft most schemas in circulation are still written against. It was built for this site rather than pulled in as a package, and it runs inside the tab.

    A schema declaring a later draft is not turned away. When its $schema names the 2020-12 or 2019-09 meta-schema, it is read in draft-07-compatible mode and the verdict is labelled 2020-12, read as draft-07, so the label itself tells you which rules were applied; anything whose meaning is particular to those drafts, prefixItems and the later sense of items among them, is counted as unchecked rather than assumed to pass. When $schema holds an address the panel does not recognise, the label instead reads draft-07, assumed, and the strip under the verdict names the value your schema declared.

    Why “not fully checked” is an answer and not an evasion

    1

    Schema

    {"x-check":true}
    2

    Verdict

    Not fully checked · 1 keyword at 1 location
    3

    Not checked

    Keyword x-check is not implemented.

    A validator that meets a keyword it has not implemented has two options: pass over it and report success, which is the common choice, or tell you. Reporting success is much the worse, because it produces a clean verdict over a schema only partly read, and which part went unread is exactly what you are not told.

    This panel therefore has a third verdict beside valid and invalid. Not fully checked means that nothing failed and that something could not be judged; it names what, counts how often that happened, and marks each occurrence on the schema pane — on the schema, because a keyword that was never evaluated has no place in your data to point at. Eight reasons produce it, in three groups. Not implemented: format, the content keywords, and any other assertion outside the supported set. Out of draft: a keyword whose meaning belongs to 2019-09 or 2020-12. And the evaluator’s own ceilings: a reference to a schema on another host, nesting deeper than the depth guard permits, a run that reached twenty million keyword checks, and a decimal too large to compare digit for digit.

    That last group deserves its own sentence, because it is the one most tools get wrong quietly. When the evaluator runs into its own depth or step ceiling it stops, says so, and counts the stop like any other gap, instead of handing back whichever answer it happened to hold at that moment as though the work had finished.

    All four verdicts, worked through on one document: Why a JSON Schema check says “not fully checked”.

    No remote $ref is ever fetched

    1

    Schema

    {
      "$ref": "https://x.test/a.json"
    }
    2

    Verdict

    Not fully checked · 1 keyword at 1 location
    3

    Not checked

    Remote reference "https://x.test/a.json" was not loaded.

    Schemas refer to one another. When yours points at an address schema hosted at some URL, a conventional validator goes out and downloads it before carrying on. This page does not, for the same reason it has no upload button: there is no server on our side, and a request to resolve that reference would carry the shape of your schema — frequently an internal hostname, and a path that says more about your systems than you would choose to publish — out of the browser.

    Instead the reference becomes one of the unchecked entries above, with the address it names shown, so the verdict stays honest about the part of your schema that was not applied: neither downloaded, nor treated as satisfied. References within the schema itself resolve normally and are evaluated in full; one that points at nothing, or that circles back to itself without moving into the data, is reported as a schema error rather than allowed to pass.

    How to use this page

    The page opens on two panes with the mode already set to Schema: the document you are checking on the left, the schema it must satisfy on the right. Paste into either, use Open in a pane’s toolbar to read a file from disk, drop a file onto the pane, or pull one in From URL…. No schema yet? Take Generate → JSON Schema → Validate with this, which drafts one from your document and fills the right-hand pane for you to tighten by hand; one undo puts it back.

    From there it is live. The verdict sits on the band between the panes and re-runs as you type; when a document is heavy enough that re-running would interrupt your typing, the panel steps down to running on request and says so in words. Each failure names the property that broke a rule and the rule it broke, and choosing one jumps the document to that value, marked in place, in whichever view the pane is showing — Code underlines the span, Tree tints the row, Table the cell, Graph the node. Fix the value, or loosen the rule on the right.

    FAQ

    Frequently asked questions

    Didn’t find your answer?Write to us on the contact page →
    Which draft of JSON Schema does this support?

    draft-07, implemented here by hand. A schema declaring 2019-09 or 2020-12 is still read, in draft-07-compatible mode, and labelled 2020-12, read as draft-07 so you know which rules ran; keywords belonging only to those drafts are counted as unchecked rather than waved through. If $schema names something unrecognised, the label reads draft-07, assumed and the line beneath repeats what your schema declared.

    Why does it say “not fully checked” instead of valid? Is that a bug?

    No, it is the point. The verdict means two things at once: no failure was found, and at least one keyword could not be evaluated. A tool that dropped the second half would show you a green tick over a schema it had only partly read. Every unchecked keyword is named, counted and marked on the schema pane, so you can judge whether the gap matters here.

    Do my schema or my data ever leave the browser?

    Neither ever does. The evaluator is JavaScript that arrived with the page and runs on your own machine, there is no backend to send anything to, and once the tab has loaded it keeps working with the network off. That holds for a reference to a schema on the web too: it is reported, with its address, rather than fetched.

    Can I edit the schema on this page?

    Yes — the right-hand pane is an ordinary editor, the same one as the left. Type in it, format it, fold it, undo a change, open a .json file into it or paste one, and the verdict re-runs as you go. Both panes are kept in this tab across a reload, so a schema you are refining survives the night.