What Is JSON? A Practical Guide to Syntax, Data Types, Parsing, and Safe APIs
JSON is a text format for exchanging structured data. Learn its six value types, syntax rules, JavaScript differences, parsing, validation, and safe API use.

JSON (JavaScript Object Notation) is a text format for serializing structured data so programs and systems can exchange it. It is readable by people, easy for machines to parse, and supported by nearly every modern programming language. JSON is related historically to JavaScript, but it is not JavaScript code and it is not a programming language.
{
"name": "Mina",
"active": true,
"score": 12,
"tags": ["blue", "green"],
"manager": null
}
This example is one JSON object. It contains a string, a boolean, a number, an array, and a null value. The syntax is defined by IETF RFC 8259 and Ecma ECMA-404. RFC 8259 describes JSON as “a text format for the serialization of structured data.” ECMA-404 focuses only on valid JSON syntax; it does not define what an application’s fields mean.
Why JSON exists
Applications constantly exchange data: a browser requests a user profile, a service returns payment details, or a command-line program reads configuration. The two sides need a common representation that is portable across operating systems and programming languages.
JSON provides that representation as Unicode text. A server can emit JSON, and a client written in Python, Go, Java, JavaScript, Ruby, or another language can parse it into that language’s native values. The JSON format defines the shape and syntax of the text. The application must separately define the meaning of fields, required values, units, permissions, and business rules.
For network exchange outside a closed ecosystem, RFC 8259 specifies UTF-8. A valid JSON document can have any JSON value at its top level, although objects and arrays are the forms most commonly returned by APIs.
The six JSON value types
JSON has exactly six kinds of values:

| Type | Example | What it represents |
|---|---|---|
| String | "hello" |
Unicode text in double quotation marks |
| Number | 42, -3.5 |
A decimal numeric value |
| Boolean | true, false |
A true/false value |
| Null | null |
An explicit absence of a value |
| Object | {"id": 7} |
An unordered collection of string name/value pairs |
| Array | ["a", "b"] |
An ordered sequence of values |
Objects use string member names. A colon separates each name from its value, and commas separate members. Arrays preserve element order and can contain values of different types, including other arrays and objects.
{
"id": 7,
"roles": ["editor", "viewer"],
"profile": {
"timezone": "UTC",
"verified": false
}
}
The object member order is not semantically guaranteed by the JSON standard. If an application needs ordering, represent the data as an array. Do not rely on the order in which object members happen to appear in a file or response.
JSON syntax rules you must remember
- Use double quotes. JSON strings and object names use
". Single quotes are not valid JSON string delimiters. - Separate names and values with a colon. Write
"status": "ready". - Separate items with commas. Put commas between object members and array elements.
- Use lowercase literals. The only boolean and null literals are
true,false, andnull. - Do not add comments. Standard JSON has no comment syntax.
- Do not leave trailing commas. A comma before
}or]is invalid under the standard grammar. - Follow the number grammar. Leading zeros are not allowed except for the number zero itself.
NaNandInfinityare not JSON numbers. - Escape characters inside strings. Use escapes such as
\",\\,\n, and Unicode escapes such as\u00e9.
{
"message": "She said \"hello\"",
"path": "C:\\temp\\data.json",
"line": "first\nsecond"
}
Many parsers accept extensions such as comments, single quotes, or trailing commas. Those extensions can make a document work in one tool and fail in another. Emit standard JSON when data crosses a service boundary.
Is JSON the same as JavaScript?
No. JSON was derived from conventions used by JavaScript object literals, which explains its name and familiar braces, brackets, and strings. However, JSON is only a data format. JavaScript is a programming language with expressions, statements, functions, assignments, classes, and executable behavior.
This is valid JavaScript but invalid JSON:
const user = {
name: 'Mina', // single quotes and a comment
score: 10 + 2, // expression
getName() { return this.name; }
};
The equivalent JSON must contain only serialized values:
{
"name": "Mina",
"score": 12
}
Never parse untrusted JSON with JavaScript eval() or an equivalent evaluation function. RFC 8259 warns that evaluation can execute code and is an unacceptable security risk. Use a dedicated parser supplied by your language’s standard library or a well-maintained JSON package.
Parsing and generating JSON in common languages
JavaScript and Node.js
const text = '{"name":"Mina","active":true}';
try {
const value = JSON.parse(text);
console.log(value.name); // Mina
const output = JSON.stringify({ ok: true, count: 2 });
console.log(output); // {"ok":true,"count":2}
} catch (error) {
console.error('Invalid JSON:', error.message);
}
JSON.parse() converts JSON text into JavaScript values. JSON.stringify() serializes JavaScript values. JavaScript has values that JSON cannot represent directly, including functions, undefined, symbols, and BigInt. Decide how to transform those values before serialization. Large integers can also lose precision when converted to JavaScript’s Number type; use a string or a format and parser designed for large integers when exact precision matters.
Python
import json
text = '{"name": "Mina", "active": true}'
try:
value = json.loads(text)
print(value["name"])
output = json.dumps({"ok": True, "count": 2})
print(output)
except json.JSONDecodeError as error:
print(f"Invalid JSON at line {error.lineno}, column {error.colno}: {error.msg}")
Python’s json.loads() parses text and json.dumps() produces text. When writing files, specify UTF-8 explicitly and choose whether non-ASCII characters should remain readable or be escaped according to the receiving system.
cURL
Use cURL to inspect a JSON API response. The Accept header tells the server that JSON is preferred:
curl -H 'Accept: application/json' \
https://api.example.com/users/7
To send JSON, set both the content type and request body:
curl -X POST https://api.example.com/users \
-H 'Content-Type: application/json' \
-d '{"name":"Mina","active":true}'
Shell quoting is a frequent source of broken requests. For a larger payload, put standard JSON in a file and use --data-binary @payload.json.
Syntax validity versus application validity
A parser can confirm that text follows JSON grammar. It cannot confirm that the data makes sense to your application. This distinction is central to reliable API design.
For example, this is syntactically valid:
{"quantity": -4}
An inventory service might reject it because quantity must be a positive integer. Likewise, an object can omit a required customer_id field and still be valid JSON. ECMA-404 deliberately does not prescribe those meanings.
Validate application data after parsing:
- Parse the bytes as UTF-8 JSON.
- Check that the root value has the expected type.
- Require mandatory fields.
- Check types, ranges, formats, and allowed values.
- Reject unknown or dangerous fields when your protocol requires a strict schema.
- Return an actionable error without echoing secrets or untrusted content into logs.
Teams often describe these rules with JSON Schema or an API contract such as OpenAPI. Those tools add validation and documentation; they do not change JSON’s core syntax.
Working with JSON over HTTP
HTTP APIs normally identify JSON with the media type application/json. A response should send the matching Content-Type header, and a client should check the status code before assuming the body is a successful result.
const response = await fetch('https://api.example.com/profile');
const contentType = response.headers.get('content-type') || '';
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
if (!contentType.includes('application/json')) {
throw new Error('Expected a JSON response');
}
const profile = await response.json();
Do not assume every successful HTTP response contains JSON. A 204 response has no body, and an upstream proxy may return an HTML error page. Check status, content type, body size, and schema where reliability matters.
JSON edge cases and interoperability
- Duplicate object names: The standard describes names as strings but does not make duplicate-name handling a portable application behavior. Avoid duplicates; parsers may keep the first, keep the last, reject the input, or behave differently.
- Numbers: JSON permits decimal and exponent notation, but programming languages have different ranges and precision. Use strings for identifiers, account numbers, and exact monetary values when numeric conversion could round them.
- Null versus missing:
"middle_name": nullis different from omittingmiddle_name. Define what each means in your API. - Unicode: Use UTF-8 for network exchange and test characters beyond ASCII, including emoji and combining marks.
- Very large documents: Parsing the whole body can consume substantial memory. Apply a maximum body size and use a streaming parser when documents are large.
- Untrusted values: JSON parsing does not make values safe for SQL, HTML, shell commands, logs, or file paths. Validate and escape for the destination context.

JSON troubleshooting checklist
| Symptom | Likely cause | Fix |
|---|---|---|
| “Unexpected token” near a quote | Single quotes or an unescaped quote inside a string | Use double quotes and escape embedded quotes. |
| Error at the final brace | Trailing comma or missing value | Remove the final comma and check every colon. |
| “Unexpected end of JSON input” | Truncated response or missing closing bracket | Inspect the raw body, HTTP transfer, and closing ]/}. |
Parser rejects NaN |
Non-standard numeric value | Use null, a string, or a finite number according to the protocol. |
| Valid JSON but API rejects it | Schema or business-rule failure | Check required fields, types, ranges, and documented meanings. |
| Non-ASCII text is garbled | Wrong character encoding | Send and decode UTF-8 and verify the HTTP headers. |
| Data changes after round-trip | Number precision or unsupported language value | Serialize exact values as strings and define conversion rules. |
| Security review flags parsing | Use of eval() or unsafe downstream interpolation |
Use a JSON parser and context-specific validation/escaping. |
Performance and reliability practices
JSON is compact enough for most APIs, but performance depends on payload size, parsing cost, compression, and the receiving program’s data model. Keep responses focused, paginate long collections, and enable HTTP compression where supported. Avoid repeatedly parsing the same text. For huge streams, process incrementally instead of loading the entire document into memory.
Reliability comes from explicit contracts. Version breaking changes, document null and missing-field behavior, cap request sizes, set timeouts, and log parse failures with request identifiers rather than sensitive payloads. Validate before business logic, and return structured error objects with stable machine-readable codes.
Or skip the browser setup
If your JSON workflow also needs website screenshots, ScreenshotNeo returns a PNG, JPEG, WebP, or PDF from one GET request. It accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture. Each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing result.
See the ScreenshotNeo API documentation for all options. A minimal cURL request is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also provides an MCP server so Claude, Cursor, and other MCP clients can call take_screenshot, get_page_info, and capture_pdf. It includes full-page and element capture, device presets, custom CSS and JavaScript, waits, blocking controls, headers, cookies, geolocation, caching, signed links, asynchronous jobs, bulk capture, usage data, and an OpenAPI specification. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
Frequently asked questions
Can JSON contain comments?
No. Comments are not part of standard JSON. Some configuration formats add comments as an extension, but that file may no longer be portable JSON.
Can the top level be a string or number?
Yes. A JSON text may be any serialized JSON value. Objects and arrays are simply the most common API-level choices.
Does JSON preserve object order?
No portable meaning should depend on object member order. Use an array when order matters.
Is an empty value the same as null?
No. An empty string, an empty array, an empty object, null, and a missing field are distinct values. Define each meaning in your application contract.
What should I use to validate JSON?
Use a standards-compliant parser for syntax, then apply your application’s schema and business rules. A formatter or validator can help locate syntax errors, but it cannot decide whether your domain data is correct.


