JSON is a plain-text format for structured data: keys paired with values, wrapped in braces. Most web APIs send and receive it, and plenty of config files and app-to-app messages use it too, so it pays to know its rules exactly.
What JSON looks like
The name stands for JavaScript Object Notation, but the format belongs to no language. A JSON document is text that any program can read, built from keys and values:
{
"name": "kitty",
"fish": "tuna"
}"name" and "fish" are the keys: labels that say what each piece of data is. "kitty" and "tuna" are the values: the data itself. A colon joins each key to its value, a comma separates one pair from the next, and the braces mark where the object starts and ends.
That comma matters. Leave it out between two pairs and the text is no longer JSON, and any program reading it will refuse it.
The six kinds of value
Keys are always strings in double quotes. Values can be one of six types:
- string: text in double quotes,
"tuna"; - number:
3,4.5or-12, with no quotes; - boolean:
trueorfalse, lower case; - null:
null, meaning 'no value'; - array: an ordered list in square brackets,
["tuna", "salmon"]; - object: another set of key-value pairs in braces.
Arrays and objects can hold any of the six, including more arrays and objects, which is how JSON describes nested data. Here is what an API might send back when you ask for one cat's profile:
{
"id": 42,
"name": "Kitty",
"indoor": true,
"nickname": null,
"favourites": ["tuna", "salmon"],
"owner": {
"name": "Sam",
"city": "London"
}
}That one document uses every value type. JSON has no type for dates, times or binary data, so a date travels as a string, usually in a format both sides agree on, such as "2026-02-14".
Parsing and serialising
JSON is only text. To use it, a program parses it: reads the text and builds the language's own data structures from it. Going the other way, turning data into JSON text, is called serialising (or 'stringifying' in JavaScript).
In Python, the standard library's json module does both. An object becomes a dict, an array a list, true becomes True and null becomes None:
import json
text = '{"name": "kitty", "fish": "tuna"}'
cat = json.loads(text)
print(cat["fish"]) # tuna
cat["naps"] = 3
print(json.dumps(cat))
# {"name": "kitty", "fish": "tuna", "naps": 3}JavaScript has the same pair built in, JSON.parse and JSON.stringify:
const cat = JSON.parse('{"name": "kitty", "naps": 3}');
console.log(cat.naps + 1); // 4
const text = JSON.stringify({ name: "kitty", indoor: true });
console.log(text); // {"name":"kitty","indoor":true}Parsing and serialising are what let JSON work between systems. A Python server can serialise a dict, send the text over HTTP, and a JavaScript app in the browser can parse it into an object. Neither side needs to know what language the other uses. They only have to agree on the keys.
JSON carries data, it doesn't check it
JSON has rules about syntax, and a parser enforces them. It has no rules about meaning. If the text is well formed, it parses, whatever is inside.
Say your shop expects a quantity as a number, but a client sends it as a string:
order = json.loads('{"fish": "tuna", "qty": "2"}')
print(order["qty"] * 2) # 22The parser raised no error, because the text is valid JSON. In Python, "2" * 2 repeats the string, so you get 22 instead of 4. A missing key, a negative quantity or a misspelt field name would also parse without complaint.
Checking the data is your code's job. You can test the types and required keys by hand, or describe the shape you expect with JSON Schema, a separate specification written in JSON itself, and let a validator library check each document against it:
{
"type": "object",
"properties": {
"fish": { "type": "string" },
"qty": { "type": "integer" }
},
"required": ["fish", "qty"]
}Validate data when it arrives from outside your program: request bodies, files users upload, responses from third-party APIs. Once it has passed, the rest of your code can trust it.
JSON next to other formats
JSON is not the only way to pass structured data around, and it isn't always the best fit.
- XML wraps data in opening and closing tags. It is more verbose, but it supports attributes, namespaces and mature schema tooling, so you still meet it in older enterprise systems and document formats.
- YAML describes the same kinds of data with indentation instead of braces, and allows comments. That makes it popular for config files people edit by hand, at the cost of a more complicated set of rules.
- CSV is rows and columns separated by commas. It suits flat tables, such as a spreadsheet export, but has no way to nest data.
JSON sits in the middle: simple enough to read at a glance, strict enough for programs to parse the same way every time. For data passing between programs, especially over HTTP, it is the usual default.
Common mistakes
JSON's syntax is stricter than the JavaScript it grew out of. These are the errors that make a parser reject a document:
- Single quotes:
{'name': 'kitty'}is not JSON. Strings and keys need double quotes. - Unquoted keys:
{name: "kitty"}is valid JavaScript but not JSON. - Trailing commas: a comma after the last item,
["tuna", "salmon",], is an error. - Missing commas between pairs, as in the first example without its comma.
- Comments: JSON has none. If a config file needs explanations, that is a reason to look at YAML or another format.
Two more mistakes parse fine but cause bugs later. JavaScript stores every number as a 64-bit float, so very large integers, such as some database ids, can lose precision when parsed; send them as strings. And JSON.stringify silently drops properties whose value is undefined or a function, so check what went out.
Key takeaways
- JSON is a text format for structured data, built from keys and values.
- Values are strings, numbers, booleans, null, arrays or objects, and nothing else.
- Parsing turns JSON text into your language's data; serialising turns data back into text.
- JSON only carries data: a parser checks the syntax, and your code or a JSON Schema checks the meaning.
- Double quotes, commas between items, no trailing commas and no comments.