JSON Formatting and Validation: A Practical Guide
JSON (JavaScript Object Notation) is the lingua franca of modern APIs. It powers REST APIs, configuration files, NoSQL databases, and inter-service communication. Despite its apparent simplicity, subtle JSON errors cause a surprising number of production bugs. This guide covers JSON thoroughly — from structure to best practices.
What Is JSON?
JSON is a lightweight, text-based data interchange format. It was derived from JavaScript object syntax but is language-independent — every major programming language has a JSON parser.
A valid JSON document is either:
- An object: { "key": value }
- An array: [value, value, ...]
- A primitive: string, number, boolean, or null
JSON Data Types
| Type | Example | Notes |
|---|---|---|
| String | "hello world" |
Always double quotes — never single |
| Number | 42, 3.14, -7, 1.5e10 |
No quotes |
| Boolean | true, false |
Lowercase only |
| Null | null |
Lowercase only |
| Object | {"key": "value"} |
Keys must be strings |
| Array | [1, 2, 3] |
Any mix of types allowed |
The JSON Specification (What's Strictly Not Allowed)
JSON is stricter than most developers realise. These are invalid in JSON even though they're valid in JavaScript:
// ❌ Single quotes
{ 'name': 'Alice' }
// ❌ Trailing comma
{ "name": "Alice", "age": 30, }
// ❌ Comments
{ "name": "Alice" /* the user */ }
// ❌ Undefined
{ "value": undefined }
// ❌ Functions
{ "fn": function() {} }
// ❌ NaN / Infinity
{ "value": NaN }
// ✅ Valid JSON
{
"name": "Alice",
"age": 30,
"active": true,
"score": null,
"tags": ["admin", "user"]
}
Pretty-Printing vs. Minifying JSON
Pretty-printed JSON uses indentation and newlines for human readability:
{
"user": {
"id": 123,
"name": "Alice",
"roles": ["admin", "editor"]
}
}
Minified JSON removes all unnecessary whitespace:
{"user":{"id":123,"name":"Alice","roles":["admin","editor"]}}
When to use each:
- Pretty-print for config files, logs, and debugging
- Minify for API responses to reduce payload size (a 30% reduction is typical)
- Most HTTP clients accept both; Content-Type is application/json regardless
Our JSON Formatter instantly converts between both and catches syntax errors.
Common JSON Errors and How to Fix Them
1. Trailing comma
// ❌ Error
{"a": 1, "b": 2,}
// ✅ Fix
{"a": 1, "b": 2}
Many editors (VS Code, JetBrains) offer "strip trailing commas" actions.
2. Unquoted keys
// ❌ Error (JavaScript syntax, not JSON)
{name: "Alice"}
// ✅ Fix
{"name": "Alice"}
3. Single-quoted strings
// ❌ Error
{'name': 'Alice'}
// ✅ Fix
{"name": "Alice"}
4. Unescaped special characters in strings
Certain characters inside string values must be backslash-escaped:
| Character | Escaped form |
|---|---|
" |
" |
| Backslash | \\ |
| Newline | ` |
| ` | |
| Tab | |
| Carriage return | ` |
| ` |
5. Numeric keys
// ❌ Error — keys must be strings
{1: "one", 2: "two"}
// ✅ Fix
{"1": "one", "2": "two"}
JSON Schema: Validating Structure
For APIs and configuration files, JSON Schema lets you formally describe the expected structure:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["id", "name"],
"properties": {
"id": { "type": "integer", "minimum": 1 },
"name": { "type": "string", "maxLength": 100 },
"email":{ "type": "string", "format": "email" }
}
}
Tools like ajv (Node.js), jsonschema (Python), and built-in validators in most languages use schemas to validate incoming API data automatically.
JSON in APIs: Best Practices
Date/time
JSON has no native date type. Use ISO 8601 strings:
{ "created_at": "2026-05-27T14:30:00Z" }
Avoid Unix timestamps in human-facing APIs — they're opaque and easy to get wrong (seconds vs. milliseconds is a common source of bugs).
IDs
Use strings for IDs, not numbers, if the ID might ever exceed JavaScript's Number.MAX_SAFE_INTEGER (2⁵³ − 1 = 9,007,199,254,740,991):
{ "id": "9007199254740993" } // Safe as string
{ "id": 9007199254740993 } // ❌ Loses precision in JS
Null vs. omitted fields
Decide on a consistent convention:
- Explicit null ("field": null) signals "this field exists but has no value"
- Omitting the field signals "this field is not applicable"
Pick one and stick to it across your entire API.
Consistent key naming
Choose camelCase (JavaScript convention) or snake_case (Python/Ruby convention) and never mix them within the same API.
Debugging JSON in the Terminal
# Pretty-print JSON from an API
curl https://api.example.com/users | python3 -m json.tool
# Or with jq (more powerful)
curl https://api.example.com/users | jq '.'
# Extract a specific field
curl https://api.example.com/users | jq '.[0].name'
# Filter array
curl https://api.example.com/users | jq '[.[] | select(.active == true)]'
Performance Tips
- For large payloads (>100KB), consider streaming JSON parsers instead of loading the whole document into memory
- MessagePack or Protocol Buffers offer 30–50% smaller payloads than JSON for high-throughput APIs
- HTTP compression (
gzip,brotli) reduces JSON size by 60–80% on the wire — enable it before worrying about manual minification
Format and validate your JSON instantly: JSON Formatter →
Probar la herramienta
Abrir herramienta