Data formats guide Β· JSON
Six data types.
A handful of rules.
Used everywhere.
JSON β JavaScript Object Notation β is the plain-text format most APIs, config files and webhooks use to move structured data around. It's small enough to learn in ten minutes and strict enough that one stray comma breaks it. This page covers both halves. π
Request and response bodies for REST APIs, payment and CRM webhooks, mobile app backends.
package.json, appsettings.json, tsconfig.json, editor settings.
Document databases, JSON columns in SQL databases, structured log lines.
The short history: JSON was popularised by Douglas Crockford in the early 2000s as a subset of JavaScript's object literal syntax. Today it's defined by RFC 8259 and ECMA-404, and every mainstream language ships a parser for it β you no longer need JavaScript anywhere near it.
02 Β· The whole grammar
π§± Syntax rules & data types
A JSON document is exactly one value. Usually that value is an object or an array, but a bare string, number, or true is also valid JSON. Values come in six types:
| Type | Example | Rules |
|---|---|---|
| π€ String | "Pune" | Double quotes only. Escape \", \\ and control characters; \n, \t and Γ© style escapes are allowed. |
| π’ Number | 42, -3.5, 1.2e6 | Decimal only. No leading zeros (007), no leading +, no hex, no NaN or Infinity. |
| β Boolean | true, false | Lowercase. True and TRUE are errors. |
| π« Null | null | Lowercase. There is no undefined. |
| π¦ Object | { "id": 7 } | Unordered set of "key": value pairs. Keys are always double-quoted strings. |
| π Array | [1, "two", null] | Ordered list. Items can be any type, mixed freely. |
That's it. There is no date type, no comment syntax, no binary type and no way to reference another part of the document. Everything else β dates, money, IDs, images β is a convention layered on top of those six types.
Dates are just strings. The near-universal convention is an ISO 8601 string such as "2026-03-14T09:30:00Z". Some APIs send Unix timestamps as numbers instead β see What is a Unix timestamp? for how to tell them apart.
π A few rules people forget
- Whitespace is insignificant between tokens, so minified and pretty-printed JSON are the same data.
- Encoding is UTF-8 for JSON exchanged between systems (RFC 8259 requires it). The media type is
application/json. - Duplicate keys aren't forbidden by the grammar, but the spec says names should be unique, and parsers disagree about what to do with them β most keep the last one. Don't rely on either behaviour.
- Key order isn't meaningful. Most parsers preserve it, but a consumer is allowed to ignore it.
03 Β· Read a real one
π A realistic example
Here's the kind of payload an order API might return. It uses every one of the six types:
{
"orderId": "ORD-10482",
"createdAt": "2026-03-14T09:30:00Z",
"paid": true,
"couponCode": null,
"customer": {
"name": "Asha Verma",
"city": "Pune"
},
"items": [
{ "sku": "TEA-250", "qty": 2, "price": 249.00 },
{ "sku": "MUG-01", "qty": 1, "price": 399.00 }
],
"tags": ["gift", "express"]
}
Read it top-down: the document is one object; customer is a nested object; items is an array of objects; couponCode is present but explicitly empty. That last distinction matters β a key set to null and a missing key are different things, and many APIs use them to mean "cleared" versus "not sent".
Big numbers lose precision in JavaScript. JSON numbers have no size limit, but JSON.parse turns them into 64-bit floats, which are only exact up to 9007199254740991 (253 β 1). A 19-digit database ID will silently change. That's why many APIs send large IDs as strings β and why money is often sent in the smallest unit (paise, cents) as an integer.
Pasted a minified blob and can't see the structure? Drop it into the JSON Formatter to pretty-print, validate and explore it as a collapsible tree.
04 Β· Why it won't parse
π§― The errors everyone hits
Most "invalid JSON" errors come from writing JavaScript object syntax β which is looser β and expecting JSON to accept it. These five cover the large majority of failures:
{"a": 1, "b": 2,}{"a": 1, "b": 2}{'name': 'Asha'}{"name": "Asha"}{name: "Asha"}{"name": "Asha"}{"port": 8080 // dev}{"port": 8080, "_comment": "dev"}{"ratio": NaN}{"ratio": null}π΅οΈ Sneakier ones
- Smart quotes. Copying JSON out of a word processor or chat app can turn
"into curly quotes, which look right and fail to parse. - A byte-order mark at the start of a file saved by some Windows editors. Many parsers reject it.
- Unescaped control characters β a literal tab or newline inside a string must be written as
\tor\n. - Python's output.
json.dumps(float("nan"))writesNaNby default, which other parsers reject. Passallow_nan=Falseto catch it at the source. - Printing a dict instead of serialising it.
str(my_dict)in Python gives single quotes andTrue/Noneβ it looks like JSON but isn't.
"But my config file has comments." Then it's probably JSONC (JSON with Comments β used by VS Code and tsconfig.json) or JSON5, both looser supersets. They're fine where the tool expects them; just don't send them to an API that expects strict JSON.
05 Β· Picking a format
βοΈ JSON vs XML vs YAML
All three represent nested, structured data. They differ in what they optimise for.
| What | JSON | XML | YAML |
|---|---|---|---|
| Looks like | {"name": "Asha"} | <name>Asha</name> | name: Asha |
| Comments | No | Yes | Yes |
| Data types | Six built-in types | Everything is text unless a schema says otherwise | Rich, with implicit typing |
| Attributes & metadata | No β everything is a key | Yes β attributes and namespaces | No |
| Schema languages | JSON Schema | DTD, XSD, RELAX NG β mature | Usually borrows JSON Schema |
| Size on the wire | Compact | Verbose (closing tags) | Compact |
| Parsing gotchas | Few β strict and simple | Entities, namespaces, security settings | Indentation, implicit types |
| Typical home | Web APIs, JS apps, config | SOAP, feeds, sitemaps, documents | CI pipelines, Kubernetes, Compose |
β Choose JSON whenβ¦
Machines are the main readers: API payloads, messages between services, anything a browser consumes. It's the default for new web APIs for good reason.
βοΈ Choose YAML whenβ¦
Humans edit it by hand and need comments β pipelines and deployment config. Watch implicit typing: in older YAML 1.1 parsers, an unquoted no becomes false.
XML still wins for document-style data and established standards β our What is XML? guide covers where and why.
06 Β· In your code
π οΈ Parsing & generating JSON
Every language has the same two operations: parse (text β objects) and serialise (objects β text). Always use the built-in library β never build JSON by concatenating strings, because escaping is where hand-rolled JSON breaks.
// text β object (throws SyntaxError on invalid input) const order = JSON.parse(text); // object β text; the third argument pretty-prints with 2 spaces const body = JSON.stringify(order, null, 2); // fetch() does the parse for you const res = await fetch("/api/orders/10482"); const data = await res.json();
using System.Text.Json;
public record Item(string Sku, int Qty, decimal Price);
public record Order(string OrderId, bool Paid, List<Item> Items);
// Web defaults: camelCase names, case-insensitive matching
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
Order? order = JsonSerializer.Deserialize<Order>(json, options);
string text = JsonSerializer.Serialize(order, options);
import json order = json.loads(text) # str β dict text = json.dumps(order, indent=2, allow_nan=False) with open("order.json", encoding="utf-8") as f: order = json.load(f) # file β dict
Skip writing the classes by hand. Paste a sample payload into JSON to C# or JSON to TypeScript and you get typed models to start from. Debugging a .NET object dumped to JSON? The Object Dump Viewer makes it browsable.
07 Β· Contracts
π JSON Schema, briefly
Valid JSON only means "it parses". Whether it has the right shape β required fields present, numbers positive, strings matching a pattern β is a separate question. JSON Schema is the standard way to write that shape down, itself as JSON:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["orderId", "items"],
"properties": {
"orderId": { "type": "string", "pattern": "^ORD-[0-9]+$" },
"paid": { "type": "boolean" },
"items": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["sku", "qty"],
"properties": { "qty": { "type": "integer", "minimum": 1 } }
}
}
}
}
You'll meet JSON Schema without looking for it: OpenAPI uses it to describe request and response bodies, editors use it for autocomplete in config files, and validator libraries exist for every major language. It's worth writing one for any payload that crosses a team boundary.
08 Β· Quick answers
π¬ Common questions
βΆπ€Is JSON the same as a JavaScript object?
No. JSON is a text format; a JavaScript object is an in-memory value. JSON's syntax borrowed from JS object literals but is stricter: quoted keys, double quotes only, no functions, no undefined, no trailing commas.
βΆπIs there a size limit?
The format has none. Limits come from parsers, servers and memory β many web frameworks cap request bodies by default. For very large datasets, JSON Lines (one JSON value per line) lets you stream records instead of loading one giant array.
βΆπIs it safe to parse JSON from users?
Parsing with a real JSON parser is safe β never use eval(). The risks come afterwards: trusting the values without validation, or deserialising into types that run code. Validate shape and size, and treat every field as untrusted input.
βΆπHow do I convert JSON to XML or CSV?
There's no single correct mapping β JSON arrays and XML attributes don't line up one-to-one β so conversions always involve choices. Pretty-print the source first in the JSON Formatter so you can see the structure you're mapping, and use the XML Formatter to check the result.
βΆβ¨Should I pretty-print or minify?
Pretty-print for humans β logs you'll read, files in git, docs. Minify over the wire if bytes matter, though HTTP compression (gzip, Brotli) removes most of the difference anyway. The data is identical either way.