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".
This one document uses all six JSON value types: a single top-level object that holds an object, an array, strings, numbers, a boolean and null.
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
}
  1. 1ObjectKey/value pairs in braces. The outer one is the single top-level value; user is an object nested in it
  2. 2ArrayAn ordered list of values in brackets
  3. 3StringText in double quotes. Keys such as "name" are strings too
  4. 4NumberAn integer or a decimal, optionally with an exponent
  5. 5Booleantrue or false, lower-case
  6. 6nullThe literal null: 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.

Try it: JSON Validator Try it: JSON Lines Formatter

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.

Try it: JSON Formatter Try it: JSON Minifier

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

Practice exercise

Repair an order fixture and check the response against its contract

Your task

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.

Material
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
}
Steps
  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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
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

Part of the QA Roadmap

Tools mentioned in this guide

Format, beautify and validate JSON instantly in your browser with custom indentation.

JSON & Data

Validate JSON syntax and get precise error locations with helpful fix suggestions.

JSON & Data

Explore JSON as a collapsible tree with paths, types and value counts.

JSON & Data

Minify JSON by removing whitespace to reduce payload size.

JSON & Data

Compare two JSON documents semantically and highlight added, removed and changed values.

JSON & Data

Convert an array of JSON objects to CSV with flattened nested keys.

JSON & Data

Convert JSON to clean, readable YAML.

JSON & Data

Validate a JSON document against a JSON Schema (draft-07 / 2019-09 / 2020-12 core keywords).

JSON & Data

How Mutqan Soft can help

More guides

More guides