Tuple Validation with prefixItems in JSON Schema
Validate fixed-length arrays (tuples) in JSON Schema using prefixItems. Each position has its own type. Learn the Draft 2020-12 tuple syntax and migration.
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"point": {
"type": "array",
"prefixItems": [
{ "type": "number", "minimum": -180, "maximum": 180 },
{ "type": "number", "minimum": -90, "maximum": 90 }
],
"items": false,
"minItems": 2,
"maxItems": 2
},
"rgb": {
"type": "array",
"prefixItems": [
{ "type": "integer", "minimum": 0, "maximum": 255 },
{ "type": "integer", "minimum": 0, "maximum": 255 },
{ "type": "integer", "minimum": 0, "maximum": 255 }
],
"items": false
},
"record": {
"type": "array",
"prefixItems": [
{ "type": "integer" },
{ "type": "string" },
{ "type": "boolean" }
],
"items": false
}
},
"required": ["point"]
}Test Data
{
"point": [-122.4194, 37.7749],
"rgb": [59, 130, 246],
"record": [42, "active", true]
}Detailed Explanation
Tuple Validation with prefixItems
A tuple is a fixed-length array where each position has a specific type. Unlike uniform arrays (where all elements share one schema), tuples validate each position independently. JSON Schema Draft 2020-12 uses prefixItems for this purpose.
Basic Tuple Syntax
{
"type": "array",
"prefixItems": [
{ "type": "number" },
{ "type": "string" }
],
"items": false
}
This validates a two-element array where the first element is a number and the second is a string. Setting items: false prohibits any elements beyond the tuple positions.
How the Example Schema Works
The schema defines three tuple types:
point— a[longitude, latitude]pair. The first element is a number in[-180, 180], and the second is in[-90, 90]. The value[-122.4194, 37.7749]represents San Francisco. Settingitems: falsewithminItems: 2andmaxItems: 2ensures exactly two elements.rgb— a three-element color tuple. Each element is an integer from 0 to 255. The value[59, 130, 246]is a shade of blue (Tailwind's blue-500).record— a mixed-type tuple with an integer, a string, and a boolean. This is similar to a database row or CSV record:[42, "active", true].
items: false and Extra Elements
When items: false is set, any element beyond the prefixItems positions causes validation failure:
[1, "a"]— valid (matches both prefix items)[1, "a", true]— invalid (third element not allowed)[1]— valid (second position is not required unlessminItems: 2)
If you want to allow extra elements of a specific type, use a schema instead of false:
{
"prefixItems": [
{ "type": "string" },
{ "type": "integer" }
],
"items": { "type": "boolean" }
}
This allows ["name", 42, true, false] — two fixed positions followed by any number of booleans.
Draft Migration
In Draft 7 and earlier, tuple validation used the items keyword with an array value:
// Draft 7 syntax (deprecated in 2020-12)
{ "items": [{ "type": "number" }, { "type": "string" }] }
// Draft 2020-12 syntax
{ "prefixItems": [{ "type": "number" }, { "type": "string" }] }
Draft 2020-12 renamed this to prefixItems to avoid confusion between tuple validation and uniform array validation.
Use Case
Use tuple validation for coordinate pairs in geographic APIs, RGB/RGBA color values, fixed-format data records, function argument lists, and any structured array where each position has a defined meaning and type.