JSON (JavaScript Object Notation) is a way to represent data by combining basic values in arrays and key/value structures using the syntactic conventions of JavaScript. It’s plain text, it’s readable by humans, and despite the name it has nothing to do with JavaScript anymore — every language can parse it.
JSON won because it’s simple. There are only six kinds of value:
- String —
"hello", always in double quotes - Number —
42or3.14, with no distinction between integers and floats - Boolean —
trueorfalse - Null —
null - Array — an ordered list,
[1, 2, 3] - Object — an unordered set of key/value pairs,
{"a": 1}
Objects and arrays can nest inside each other, which is how JSON represents anything complicated:
{
"id": 1042,
"email": "ada@example.com",
"active": true,
"plan": { "name": "pro", "seats": 12 },
"tags": ["beta", "enterprise"],
"cancelled_at": null
}
Note what’s missing. There are no dates — timestamps travel as strings, usually ISO 8601 like "2026-07-21T14:03:00Z". There are no comments. And numbers have no declared precision, which is why money is often sent as an integer count of cents rather than a decimal.
JSON and APIs
Nearly every web API you’ll pull data from returns JSON. Converting an in-memory object into a JSON string to send over the wire is called serialization; parsing it back on the other end is deserialization.
JSON also shows up as a transport format for structured tokens: a JWT is essentially two small JSON objects, base64-encoded and signed.
JSON in a database
Most databases can store JSON in a column — PostgreSQL has json and jsonb, MySQL and SQL Server have JSON, BigQuery and Snowflake have their own semi-structured types. That’s convenient when API responses have fields you don’t want to model in advance.
It’s also a trap if you leave everything in there. JSON columns are slower to filter and aggregate than typed columns, and a BI tool can’t offer good filters on a field it doesn’t know the data type of. The usual practice is to keep the raw JSON payload for safety, then flatten the fields you actually analyze into proper typed columns during the transform step of your ETL pipeline:
SELECT
payload ->> 'email' AS email,
(payload -> 'plan' ->> 'seats')::int AS seats
FROM raw.users
Do that once, at load time, and every downstream question gets faster and easier to write.
Related terms
Further reading
Put it to work
- Build a data pipeline — Integration
- Stripe — Integration
- PostHog — Integration