What is JSON?
JSON (JavaScript Object Notation) is a lightweight text format for exchanging structured data. It represents data as nested objects and arrays of values, is readable by humans, and can be parsed by every mainstream programming language — which is why nearly every web API sends and receives JSON.
This guide covers the syntax you need to write valid JSON, the mistakes that produce "Unexpected token" errors, how to format, validate and convert JSON in your browser, and when another format is a better choice.
JSON syntax: the six value types
A JSON document is a single value. That value is usually an object or an array, but the standard (RFC 8259) allows any of six types at the top level.
- Object — an unordered set of key/value pairs inside braces: {"id": 7, "name": "Layla"}. Keys must be strings in double quotes.
- Array — an ordered list of values inside brackets: ["admin", "editor"].
- String — text in double quotes, with backslash escapes for quotes, backslashes and control characters: "line one\nline two".
- Number — an integer or decimal, optionally with an exponent: 42, -3.5, 1.2e10. No leading zeros, no hex, no NaN or Infinity.
- Boolean — the literals true and false (lower-case).
- null — the literal null, meaning "no value".
Part 1:{ "user": Part 1:{ "id": Part 4:7, "name": Part 3:"Layla", "active": Part 5:true }, "roles": Part 2:[ Part 3:"admin", Part 3:"editor" ], "lastLogin": Part 6:null, "balance": Part 4:1250.75 }
- 1ObjectKey/value pairs in braces. The outer one is the single top-level value;
useris an object nested in it - 2ArrayAn ordered list of values in brackets
- 3StringText in double quotes. Keys such as
"name"are strings too - 4NumberAn integer or a decimal, optionally with an exponent
- 5Boolean
trueorfalse, lower-case - 6
nullThe literalnull: no value
The sample of this section, one value per line; every value is unchanged.
Text version
{
"user": { "id": 7, "name": "Layla", "active": true },
"roles": ["admin", "editor"],
"lastLogin": null,
"balance": 1250.75
}The rules that cause most JSON errors
JSON looks like JavaScript but is much stricter. Almost every "Unexpected token" or "Unexpected end of JSON input" error comes from one of these rules.
- Keys and strings use double quotes only. 'single quotes' are invalid.
- No trailing commas: [1, 2, 3,] and {"a": 1,} are errors.
- No comments. Neither // nor /* */ is allowed anywhere in the document.
- Keys must be quoted: {name: "Layla"} is JavaScript, not JSON.
- Numbers cannot have leading zeros (007) or a trailing decimal point (5.).
- The document must contain exactly one top-level value — two objects side by side are not valid JSON (that is JSON Lines).
- Encoding is UTF-8. A byte-order mark at the start of the file will break many parsers.
How to format (pretty-print) JSON
APIs usually send JSON minified — every space and line break removed — because it is smaller. Formatting adds the indentation back so the structure is visible. Paste the text into a formatter, choose 2-space, 4-space or tab indentation, and copy the result; a good formatter also reports the exact line and column of any syntax error and can sort object keys so that two documents can be compared.
In code, JSON.stringify(value, null, 2) in JavaScript, json.dumps(value, indent=2) in Python and jq . file.json on the command line do the same job.
How to validate JSON
Validation has two levels. Syntax validation checks that the text is well-formed JSON — that every bracket is closed and every rule above is respected. Schema validation goes further and checks the structure against a JSON Schema: which keys are required, what type each value must be, allowed ranges and patterns.
Use syntax validation while debugging a payload that will not parse, and schema validation when you own an API contract and want to catch responses that drift away from it.
Try it: JSON Validator Try it: JSON Schema Validator Try it: JSON Schema Generator
JSON vs XML vs YAML
JSON replaced XML as the default web format because it is smaller, maps directly onto the data structures of most languages and needs no schema to be useful. XML remains common in enterprise and SOAP systems and supports attributes, namespaces and comments that JSON lacks.
YAML is a superset of JSON designed for humans to write — configuration files, CI pipelines, Kubernetes manifests. It allows comments and omits most punctuation, but its whitespace sensitivity makes it a poor choice for machine-to-machine exchange. The rule of thumb: JSON for APIs and storage, YAML for configuration, XML when a system requires it.
Try it: JSON to YAML Try it: JSON to XML Try it: XML to JSON Try it: YAML Formatter Try it: XML Formatter Try it: XML Validator
Converting JSON to CSV, SQL and other formats
Flat JSON arrays of objects convert cleanly to CSV: each object becomes a row and each key a column. Nested objects need to be flattened first (user.address.city becomes a column named user.address.city). The same shape maps onto SQL INSERT statements, which is the quickest way to load API data into a database for analysis.
Try it: JSON to CSV Try it: CSV to JSON Try it: JSON to SQL Try it: JSON Flatten / Unflatten
Working with large JSON documents
A tree viewer is the practical way to read a document with thousands of lines: collapse what you do not need, expand one branch at a time and copy the JSONPath of any value. To find or extract specific values programmatically, JSONPath expressions such as $.users[?(@.active)].email select exactly the nodes you want.
Try it: JSON Tree Viewer Try it: JSON Path Tester Try it: JSON Diff
Frequently asked questions
Is JSON a programming language?
No. JSON is a data format — a way of writing structured values as text. It has no variables, functions or logic. It is derived from JavaScript object syntax but is independent of any language.
What file extension does JSON use?
The .json extension, and the MIME type application/json. JSON Lines files (one JSON value per line) use .jsonl or .ndjson.
Can JSON contain comments?
Standard JSON cannot. Some tools accept a relaxed dialect (JSONC, JSON5) that allows comments and trailing commas, but APIs and most parsers reject them.
Why does my JSON fail with "Unexpected token"?
The parser met a character it did not expect — most often a trailing comma, a single-quoted string, an unquoted key or a comment. A validator shows the exact line and column.
Is JSON safe to paste into an online tool?
Only if the tool processes it locally. The Mutqan JSON tools run entirely in your browser and never upload what you paste, so API responses containing tokens or personal data stay on your machine.
What is the difference between JSON and a JavaScript object?
A JavaScript object lives in memory and can hold functions, undefined, Dates and references; JSON is a text serialization with only six value types. JSON.parse turns text into an object; JSON.stringify does the reverse.
References
- RFC 8259: The JavaScript Object Notation (JSON) Data Interchange FormatThe JSON grammar: objects, arrays, strings, numbers, the three literals, and UTF-8 as the interchange encoding.
- ECMA-404: The JSON Data Interchange SyntaxThe JSON syntax as an Ecma standard, kept in step with RFC 8259.
- Introducing JSONThe original one-page description of JSON with its railroad diagrams.
- JSON Schema SpecificationThe vocabulary for describing and validating the shape of JSON documents (types, required properties, formats).
Practice exercise
Repair an order fixture and check the response against its contract
You test the orders API of an online grocery store (fictional). An automated API test fails before it sends any request, because the test runner cannot parse the request body: the fixture order-request.json that a teammate wrote by hand. Part A of the material shows the file; the line numbers on the left are not part of it.
Once the fixture is fixed, the test places the order, and GET /api/v1/orders/ORD-77815 on staging returns the response in Part C. It parses without an error. Check it field by field against the contract excerpt in Part B, and for every deviation say whether syntax validation, schema validation or neither would catch it. Work with pen and paper first, then confirm your findings with the JSON Validator, the JSON Tree Viewer and the JSON Path Tester.
Part A - order-request.json, the request body of the failing test
(the line numbers on the left are not part of the file)
1 {
2 // checkout regression: customer with a saved address
3 "customerId": "CUS-1042",
4 "currency": 'SAR',
5 items: [
6 { "sku": "MLK-1L", "quantity": 2, "unitPrice": 6.50 },
7 { "sku": "RCE-5KG", "quantity": 01, "unitPrice": 42. },
8 ],
9 "giftWrap": False,
10 "couponCode": null,
11 "deliveryNote": "Leave it at the gate marked "B"",
12 }
Part B - API contract excerpt: response body of GET /api/v1/orders/{orderId}
(every field below is required)
Field Type Rule
orderId string for example "ORD-77815"
status string one of "pending", "paid", "shipped",
"delivered", "cancelled"
customer.id string for example "CUS-1042"
customer.phone string Saudi mobile number: "05" and 8 more digits
items array of objects at least 1 item
items[].sku string the code of the product ordered
items[].quantity integer 1 or more
items[].unitPrice number SAR, at most 2 decimal places
total number SAR, at most 2 decimal places;
the sum of quantity x unitPrice of all items
giftWrap boolean
couponCode string or null null when no coupon is used
deliveredAt string or null date-time; null until the order is delivered
Part C - staging: GET /api/v1/orders/ORD-77815
200 OK, Content-Type: application/json
{
"orderId": "ORD-77815",
"status": "Paid",
"customer": { "id": "CUS-1042", "phone": 501234567 },
"items": [
{ "sku": "MLK-1L", "quantity": "2", "unitPrice": 6.5 },
{ "sku": "RCE-5KG", "quantity": 0, "unitPrice": 42 }
],
"total": 55,
"giftWrap": "false",
"couponCode": null
}- Part A: read the fixture line by line against the syntax rules in the guide. For each error, write the line number, the rule it breaks and the corrected text. Note which lines are valid as they are.
- Paste the original fixture, without the line numbers, into the JSON Validator. Fix only the error at the line and column it reports, validate again, and repeat until the document is valid. Count the rounds and compare them with your list.
- Part C: write down the JSON type of every value in the response (the JSON Tree Viewer shows them), and every key the contract requires that is missing.
- Compare every field with Part B: type, allowed values, range and presence. Mark each one correct or a deviation, and name the level of validation that would catch it.
- In the JSON Path Tester, write one expression that returns the quantity of every item and read the Type column. Then recompute the total from the corrected request and from the items in the response: what does the comparison show that no schema can?
Show the model answer
Part A has nine syntax errors. Line 2: a comment; JSON has none. Line 4: 'SAR' uses single quotes; write "SAR". Line 5: the key items is not quoted; write "items". Line 7 holds three errors: 01 has a leading zero (write 1), 42. ends with a decimal point (write 42 or 42.00), and the comma after the last array element must go. Line 9: False must be lower case, false. Line 11 holds two: the inner double quotes end the string early, so escape them with backslashes, "Leave it at the gate marked \"B\"", and the comma after the last member of the object must go.
Lines 1, 3, 6, 8, 10 and 12 are valid. 6.50 is a correct number (zeros after the decimal point are allowed), null is a valid value, and a comma is an error only after the last element, so the comma at the end of line 6 is fine. Delete the comment instead of turning it into a key such as "_comment": the fixture is the request body, so any extra key is sent to the API too. Put the note in the test name or description.
The validator needs nine rounds, one per error in the order of the list above, because a parser stops at the first error it meets. Go by the line and column, which mark where the parser stopped: a hint is a guess made from the text around that point, so check it against the rules. Once you delete the comment line, every later line number moves up by one. The two trailing commas are often reported at the closing bracket on the next line, where the parser notices them. So one reported error never means "one error": read the whole document against the rules first and use the validator to confirm. Note also that the failing test said nothing about the API: the defect was in the testware, so you fix the fixture and do not report a defect against the API.
Part C, types: orderId, status and customer.id are strings; customer.phone is a number; items is an array of two objects whose sku values are strings; quantity is a string ("2") in the first item and a number (0) in the second; both unitPrice values and total are numbers; giftWrap is a string; couponCode is null. deliveredAt is missing.
Correct: orderId, customer.id, items (an array of two objects), both sku values, both unitPrice values, couponCode, and the type and format of total (its value is checked below). A JSON number is a value, not a display format: 6.5 and 6.50 are the same number and 42 is a valid number, so showing "6.50 SAR" is the job of the screen. null is allowed for couponCode and means that no coupon was used.
Deviations, all caught by schema validation and none by syntax validation, because the response is valid JSON: (1) status is "Paid"; strings are compared exactly, so a client that checks for "paid" does not see a paid order (allowed values, an enum). (2) customer.phone is the number 501234567; a JSON number cannot have a leading zero, so a phone number sent as a number always loses it (type string, pattern). (3) items[0].quantity is the string "2"; in JavaScript "2" + 1 gives "21", so a cart that adds one more item shows 21 (type integer). (4) items[1].quantity is 0, below the minimum of 1 (minimum). (5) giftWrap is the string "false"; every non-empty string is truthy in JavaScript, so if (order.giftWrap) treats the order as gift-wrapped (type boolean). (6) deliveredAt is missing; a missing key is not null, and order.deliveredAt === null is false because the value is undefined (required).
The expression $.items[*].quantity returns "2" with type string and 0 with type number, so both quantity deviations show up in one query, and an automated test would assert on the same path. The Type column says number, not integer: JSON has a single number type, and "integer" is a rule of the contract (JSON Schema has an integer type for it). The API Response Analyzer points to some deviations without any contract (the quantity sent as a string and with a different type in each item, giftWrap sent as a string), but it cannot know that the status spelling, the phone number, the missing key or the zero quantity are wrong. Only the contract tells you that.
Neither level: the corrected request ordered 2 × 6.50 + 1 × 42.00 = 55.00 SAR, and total is 55, which matches. The items in the response, however, add up to 2 × 6.5 + 0 × 42 = 13, so they break the contract rule that total is their sum, and the comparison with the request shows that the quantity of RCE-5KG is wrong, not the total. A schema checks each value on its own; it cannot check a sum across fields or compare the response with what was ordered. Had the server returned a quantity of 3, every schema rule would pass. That needs a test oracle, a source of the expected result, here the request: calculate the expected values from it and compare them in an assertion. Report each deviation with the field path, the expected and the actual value, for example "items[0].quantity: expected an integer of 1 or more, actual the string "2"", and attach the request and the response.
Your progress on this topic
Not started
Mark the topic complete when you have studied it and done the exercise.
Sign in to track your progress
Mark topics complete, continue where you left off and unlock specialisation exams.
Part of the QA Roadmap
Before this topic
Next topics
Tools mentioned in this guide
Format, beautify and validate JSON instantly in your browser with custom indentation.
Validate JSON syntax and get precise error locations with helpful fix suggestions.
Explore JSON as a collapsible tree with paths, types and value counts.
Minify JSON by removing whitespace to reduce payload size.
Compare two JSON documents semantically and highlight added, removed and changed values.
Convert an array of JSON objects to CSV with flattened nested keys.
Convert JSON to clean, readable YAML.
Validate a JSON document against a JSON Schema (draft-07 / 2019-09 / 2020-12 core keywords).