Controlling Additional Properties in JSON Schema
Use additionalProperties in JSON Schema to control whether unknown properties are allowed. Learn strict mode, typed extras, and patternProperties.
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"method": {
"type": "string",
"enum": ["GET", "POST", "PUT", "DELETE"]
},
"url": {
"type": "string",
"format": "uri"
},
"timeout": {
"type": "integer",
"minimum": 1,
"maximum": 30000
}
},
"required": ["method", "url"],
"additionalProperties": false
}Test Data
{
"method": "POST",
"url": "https://api.example.com/users",
"timeout": 5000
}Detailed Explanation
Controlling Additional Properties
By default, JSON Schema allows objects to have properties beyond those listed in properties. The additionalProperties keyword lets you restrict or constrain these extra properties.
Three Modes
// Allow anything (default behavior)
{ "additionalProperties": true }
// Forbid any unlisted property
{ "additionalProperties": false }
// Allow extras, but constrain their type
{ "additionalProperties": { "type": "string" } }
How the Example Schema Works
The schema defines a strict HTTP request configuration with three known properties and additionalProperties: false:
method(required) — must be one of the four standard HTTP methods.url(required) — must be a valid URI.timeout(optional) — an integer between 1 and 30000 milliseconds.
Because additionalProperties: false is set, any property not listed in properties will cause validation to fail. Sending {"method": "GET", "url": "https://x.com", "retries": 3} would be rejected because retries is not a defined property.
The test data passes because it only contains method, url, and timeout — all of which are defined in the schema.
Typed Additional Properties
Instead of a boolean, you can provide a schema for additional properties:
{
"type": "object",
"properties": {
"name": { "type": "string" }
},
"additionalProperties": { "type": "string" }
}
This allows any extra properties, but they must all be strings. The object {"name": "test", "color": "blue"} is valid, but {"name": "test", "count": 5} is not because 5 is not a string.
patternProperties for Dynamic Keys
When property names follow a pattern, use patternProperties:
{
"type": "object",
"patternProperties": {
"^x-": { "type": "string" }
},
"additionalProperties": false
}
This allows any property starting with x- (e.g., x-custom-header) and rejects everything else. This pattern is used in the OpenAPI specification for vendor extensions.
Trade-offs of Strict Mode
Pros of additionalProperties: false:
- Catches typos in property names early
- Prevents injection of unexpected data
- Makes the schema self-documenting
Cons:
- Breaks forward compatibility — adding new fields to the API response requires schema updates on the client side
- Can cause friction in loosely coupled microservice architectures
A common compromise is to use additionalProperties: false for request validation (strict) but allow additional properties in response schemas (permissive).
Use Case
Use additionalProperties: false for API request validation to reject malformed payloads, prevent data injection, and catch typos. Use it in configuration file schemas where only known keys are meaningful. Avoid it in response schemas if you plan to add fields without breaking existing consumers.