Introduction: Every JSON Value Is One of Exactly Six Types
Ask most developers how many data types JSON has and you will hear a range of answers. The specification is unambiguous: a JSON value is one of exactly six types. Four of them are primitives — string, number, boolean, and null — and two are structured containers that hold other values — object and array. There is nothing else. No date type, no integer-versus-float distinction, no undefined, no binary. Everything you ever encode in JSON is built by nesting these six types inside one another.
Knowing the exact list matters because a large share of "invalid JSON" and "the API rejected my request" problems come from putting a value in the wrong type: quoting a number that should be numeric, spelling a boolean with a capital letter, using undefined where only null exists, or wrapping a value in single quotes. This guide is a precise, example-driven reference to the six value types defined by RFC 8259, the current Internet Standard for JSON. For each type we show what it looks like, what is valid, what is not, and where strict parsers and APIs draw the line. Paste any snippet here into our JSON formatter and validator to see each rule enforced against the exact character that breaks it.
The Six Value Types at a Glance
RFC 8259, published in December 2017 and designated STD 90, defines a JSON value with a single short rule: a value must be an object, an array, a number, a string, or one of the three literal names true, false, and null. That gives the six types every implementation agrees on:
- object — an unordered set of name/value pairs wrapped in
{ }. - array — an ordered list of values wrapped in
[ ]. - string — text in double quotes.
- number — a numeric literal in decimal notation.
- boolean — the literal
trueorfalse. - null — the literal
null, representing the intentional absence of a value.
A whole JSON document, often called the "text," is itself just a single value with optional surrounding whitespace. That value is usually an object or an array, but a bare 42, a bare "hello", or a bare true is also a complete, valid JSON document under RFC 8259. Older tools sometimes insisted the top level be an object or array, but the current standard does not.
Objects and Arrays: The Two Structured Types
The two container types are what let JSON represent anything from a user record to a deeply nested API response. An object is an unordered collection of name/value pairs, where every name is a string and every value is any of the six types. An array is an ordered sequence of values, and those values do not have to share a type — [1, "two", true, null] is perfectly valid JSON. Both containers can be empty ({} and []) and both can nest to any depth.
The key distinction to internalize is that objects are unordered and keyed, while arrays are ordered and indexed. You address a value in an object by its name and in an array by its position. Because objects are unordered by definition, you must never rely on key order for correctness even though many parsers happen to preserve insertion order. Object names are the one place JSON forces a specific type: a name is always a string, so { 42: "x" } is invalid and must be written { "42": "x" }. For the full set of object rules — quoted names, the six structural characters, trailing commas, and duplicate keys — see our companion reference on JSON object syntax under RFC 8259.
Strings: Text in Double Quotes
A JSON string is a sequence of Unicode characters wrapped in double quotes — the character " at code point U+0022. No other delimiter works: single quotes, backticks, and curly typographic quotes are not JSON string delimiters. This single rule prevents a whole family of errors.
Valid: { "message": "hello world" }
Invalid — single quotes: { "message": 'hello world' }
Certain characters inside a string must be escaped with a backslash. A literal double quote is written \" and a backslash is written \\. Control characters (U+0000 through U+001F) may never appear literally; they are written with escapes such as \n for a line feed or \t for a tab, and any character can be written with a \u escape and four hex digits. Writing a real, unescaped newline inside the quotes makes the document invalid. Strings are also where dates, timestamps, and other rich values live, because JSON has no native type for them: an ISO 8601 timestamp like "2026-07-21T09:30:00Z" is just a string, and both sides of the wire must agree on how to interpret it. The full rules for quoting and escaping are covered in our guide to JSON string escaping rules.
Numbers: Decimal, Finite, and No Leading Zeros
The JSON number type is more tightly specified than most people expect, and it is where subtle bugs hide. RFC 8259 defines a number in decimal notation only, made of an optional minus sign, an integer part, an optional fractional part introduced by a decimal point, and an optional exponent introduced by e or E. There is no separate integer type and no separate float type — there is one number type, and 42 and 42.0 are both simply numbers.
Several constraints follow directly from the grammar:
- No leading zeros.
0is fine and0.5is fine, but007and01are invalid. - A leading decimal point is not allowed. Write
0.5, not.5. A trailing point such as5.is also invalid. - No plus sign on the whole number.
+5is invalid; write5. A plus is only allowed inside an exponent, as in5e+3. - Exponents are allowed.
1.5e10,2E-8, and6.022e23are all valid numbers. - No non-finite values.
NaN,Infinity, and-Infinityare not JSON numbers and are not valid JSON at all, even though JavaScript produces them at runtime. - No hex, octal, or thousands separators.
0x1F,0o17, and1_000are all invalid.
One practical warning about precision: RFC 8259 does not mandate a specific numeric range or precision, but it notes that implementations widely use IEEE 754 double-precision floating point, which can safely represent integers only up to 2 to the 53rd power. Numbers larger than that — long database IDs, for example — can lose precision when parsed. The common fix is to transmit such identifiers as strings, keeping them exact end to end.

Booleans and null: The Three Literal Names
The boolean type has exactly two values, written as the bare literals true and false. They are always lowercase and never quoted. True, FALSE, and "true" are not JSON booleans: the first two are not valid JSON at all, and the third is a string that merely looks like a boolean. That distinction bites hard when an API expects a boolean flag and receives the string "false", which many languages treat as truthy — the request silently does the opposite of what was intended.
The null type has a single value, the lowercase literal null. It represents the intentional absence of a value. JSON has no undefined, no None, and no nil — those belong to specific programming languages. If you serialize a JavaScript object with an undefined property, standard serializers drop the property entirely rather than emit undefined, because undefined is not a JSON value. When you genuinely mean "this field exists but has no value," the correct encoding is null. Note that a field set to null and a field that is absent are two different states, and well-designed APIs treat them differently.
Common Type Mistakes That Break Real Payloads
Almost every JSON type bug is one of a handful of confusions between a value and its string lookalike, or a habit carried over from a programming language. Here are the ones that most often cause a strict server to reject a request or a parser to throw:
- Quoting a number:
{ "age": "30" }when the API expects{ "age": 30 }. Both are valid JSON, but they are different types, and a schema that requires a number will reject the string. - Quoting a boolean:
{ "active": "true" }instead of{ "active": true }. The string is truthy in many languages, inverting your logic. - Capitalized literals:
True,False, orNull. JSON literals are lowercase only, and the capitalized forms are not valid JSON. - Using
undefinedorNaN: both come from JavaScript and neither is a JSON value. Usenullfor a missing value and a real decimal number where a number is required. - Single quotes:
{ 'name': 'Ada' }. JSON strings and names require double quotes. - Leading-zero or bare-point numbers:
007,.5,5., and+5all violate the number grammar.
Why Strict Typing Matters When APIs Consume JSON
JSON's type system is small, but the systems that consume JSON are not forgiving about it. When a request body reaches a server, it is usually validated against a schema or deserialized into a typed structure — a struct in Go, a class in Java, a model in Python or TypeScript. At that boundary, 30 and "30" are not interchangeable. A field typed as an integer will reject the string; a field typed as a boolean will reject "true". The mismatch shows up as a 400 error at best and as a silent data corruption at worst, when a lenient parser coerces the value in a way you did not intend.
This is why type discipline on the producing side pays off directly. Emit numbers as numbers, booleans as bare true and false, and absent values as null, and the consuming schema validates cleanly. The tool that formalizes these expectations is JSON Schema, which lets you declare that a property must be of type integer, string, or boolean and reject anything else before your application code ever runs. You can check a document against a contract with our JSON formatter for syntax and a schema validator for types — syntax validity is only the first gate, and correct types are the second.
Worked Example: All Six Types in One Document
Here is a single valid document that exercises every one of the six value types at once — an object at the top, an array of objects inside it, strings, numbers with and without exponents, both booleans, and a null:
{
"id": 1001,
"label": "Quarterly report",
"published": true,
"archived": false,
"reviewer": null,
"score": 9.5,
"views": 1200,
"ratio": 6.4e-2,
"tags": ["finance", "q3"],
"authors": [
{ "name": "Ada", "lead": true },
{ "name": "Grace", "lead": false }
]
}
Every value above has an unambiguous type: id, score, views, and ratio are numbers; label and the tag entries are strings; published, archived, and lead are booleans; reviewer is null; tags and authors are arrays; and the whole thing plus each author entry are objects. Change any value to its wrong-typed lookalike — quote a number, capitalize a boolean, swap null for undefined — and a strict validator will flag exactly that value.
Validate Types and Syntax with the JSON Formatter
Our JSON formatter and validator is the fastest way to confirm everything in this guide. Paste a document and it pretty-prints valid JSON, pinpoints the exact character where invalid JSON fails, and highlights the type mistakes above — unquoted names, single quotes, capitalized literals, and malformed numbers. Because it runs entirely in your browser, no data ever leaves your machine, so it is safe for production payloads and credentials. Once syntax is clean, move on to the two references that go deeper on the trickiest types: JSON object syntax for the object container and JSON string escaping rules for the string type. Together they cover the corners of JSON where valid-looking data most often turns out to be the wrong type.