Structure report
| Root type | — |
| Top-level keys | — |
| Total values | — |
| Maximum depth | — |
| Size | — |
Validation runs in your browser. Your JSON is never uploaded.
A validator answers one question: will this document parse as JSON? That sounds narrow, and it is exactly why the tool is useful. Formatting a broken document produces either garbage or a crash, whereas validation tells you the precise rule that was broken and where.
This one goes further than a yes or no. It reports the parser error with a line and column, and when the document is valid it describes its shape — root type, top-level keys, total value count and maximum nesting depth.
How to use this tool
- Paste the JSON you want to check into the box. It can be a fragment or a whole file.
- Click Validate. Valid input produces a confirmation and a structure report; invalid input produces the parser message instead.
- Read the error position carefully. The parser reports where it stopped, which is usually one or two characters after the real mistake — an unclosed brace, a missing comma or a stray quote.
- Click Validate & format to check the document and rewrite it with clean indentation in a single step.
- Load invalid sample shows a deliberately broken document, which is the quickest way to see what the error output looks like.
The JSON grammar in full, and where it surprises people
JSON is defined by RFC 8259, and the grammar is small enough to describe completely. A value is an object, an array, a string, a number, true, false or null. That is the entire language. Everything people find surprising comes from the gap between this and JavaScript object literals, which look nearly identical and permit far more.
The rules that catch people out:
- Keys must be double-quoted strings.
{name: "Ada"}is valid JavaScript and invalid JSON. The same applies to unquoted numeric-looking keys. - Strings must use double quotes. Single quotes are not an alternative in JSON, at any nesting level.
- No trailing commas. Neither after the last object member nor after the last array element.
- No comments. Not
//, not/* */. Formats that allow them are distinct specifications. - No
undefined,NaNorInfinity. These are JavaScript values with no JSON representation. Usenull, or serialise them as strings if they must survive the round trip. - Numbers may not have leading zeros or a leading plus.
007and+1are both rejected;7and1are fine. - Control characters must be escaped. A raw newline or tab inside a string is illegal and must be written
\nor\t. - A document is a single value. Two objects side by side is not one JSON document — that is JSON Lines, a different format.
Notice that valid JSON is always valid JavaScript when placed in an expression position, but not the reverse. The subset runs one way, and that asymmetry is the source of most confusion.
Reading a parser error correctly
Browser parsers produce messages like Unexpected token } in JSON at position 412 or Expected double-quoted property name. These are accurate but easy to misread, for one structural reason: the parser fails at the first character it cannot reconcile with the grammar, and that is frequently the character after the actual defect.
Take {"a": 1,}. The trailing comma is the mistake, but a parser scanning for the next property name finds the closing brace instead, so it reports an error at the brace. The same happens with a missing comma: the parser reads two values where the grammar permits only one, and reports an error on the second value rather than on the absent separator.
The practical technique is to look just before the reported position. Scan backwards for the nearest ,, } or ] and inspect that neighbourhood. In practice this resolves the error within seconds, and it is far faster than reading the document from the start.
Some messages are more literal. Unexpected end of JSON input means a bracket or brace was never closed, and counting opening against closing delimiters will find it. Bad control character in string literal almost always means a real newline or tab was pasted inside a string, usually from a spreadsheet or a chat message.
What a valid document does not tell you
This is the limitation worth internalising. Syntax validity and schema correctness are entirely different properties, and a validator only checks the first.
All of the following are perfectly valid JSON:
- An object where a field you require is absent.
{"price": "free"}when your code expects a number.{"price": 12.5}when your code expects an integer number of cents.{"items": {}}when your code iteratesitemsas an array.- A document that parses but whose nested structure is one level shallower than your code assumes.
- An empty object
{}, which is valid and almost never what the caller wanted.
Enforcing those constraints is the job of a schema — JSON Schema, a TypeScript interface, a Pydantic model, a Zod schema. This tool cannot do that, but the structure report narrows the gap: if you expect an array of twenty objects and the report says the root is an object, you have found a real problem without writing a schema.
JSON Lines, JSON5 and other lookalikes
Several formats resemble JSON closely enough to be pasted into a JSON tool by mistake. Knowing which one you have saves a lot of confusion:
JSON Lines (NDJSON) is one complete JSON document per line, commonly used for logs and streamed data. It is not a single JSON document, so a validator will report an error at the start of the second line. Wrapping the records in an array, with commas between lines, converts it to something this tool will accept.
JSON5 relaxes the grammar deliberately: it allows comments, single-quoted strings, trailing commas, unquoted keys and hexadecimal numbers. It is popular for human-edited configuration files precisely because those allowances reduce mistakes. It is not JSON, and a JSON parser will reject it.
JSONC is JSON with comments permitted, used by editors such as VS Code for settings files. Stripping the comments produces valid JSON.
JavaScript object output from console.log is the most common false alarm. Browsers render nested objects with single quotes and may hide deep values behind an ellipsis, so what you copied is a human-readable rendering rather than JSON. Use JSON.stringify(value, null, 2) or copy the response from the network panel instead.
Which JSON tool for which job
| Situation | Tool | Why |
|---|---|---|
| The document will not parse and you need the reason | JSON Validator | Reports the parser error with line and column |
| The document is valid but unreadable | JSON Formatter | Restores indentation without altering the data |
| You need to understand a nested structure | JSON Viewer | Builds a collapsible tree instead of a wall of text |
| The payload is too large to ship | JSON Minifier | Removes whitespace and reports the saving |
| The JSON is the payload of a token | JWT Decoder | Decodes base64url segments and explains the claims |