diff --git a/jsonschema-core.md b/jsonschema-core.md new file mode 100644 index 00000000..ced79b3d --- /dev/null +++ b/jsonschema-core.md @@ -0,0 +1,3589 @@ +# JSON Schema: A Media Type for Describing JSON Documents + +## Abstract + +JSON Schema defines the media type "application/schema+json", a JSON-based format +for describing the structure of JSON data. +JSON Schema asserts what a JSON document must look like, +ways to extract information from it, +and how to interact with it. +The "application/schema-instance+json" media type provides additional +feature-rich integration with "application/schema+json" beyond what can be offered +for "application/json" documents. + +## Note to Readers + +The issues list for this draft can be found at +https://github.com/json-schema-org/json-schema-spec/issues. + +For additional information, see https://json-schema.org/. + +To provide feedback, use this issue tracker, the communication methods listed on the +homepage, or email the document editors. + +## 1. Introduction + +JSON Schema is a JSON media type for defining the structure of JSON data. JSON Schema +is intended to define validation, documentation, hyperlink navigation, and interaction +control of JSON data. + +This specification defines JSON Schema core terminology and mechanisms, including +pointing to another JSON Schema by reference, +dereferencing a JSON Schema reference, +specifying the dialect being used, +specifying a dialect's vocabulary requirements, +and defining the expected output. + +Other specifications define the vocabularies that perform assertions about validation, +linking, annotation, navigation, and interaction. + +## 2. Conventions and Terminology + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", +"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be +interpreted as described in [RFC 2119](#rfc2119). + +The terms "JSON", "JSON text", "JSON value", "member", "element", "object", "array", +"number", "string", "boolean", "true", "false", and "null" in this document are to +be interpreted as defined in [RFC 8259](#rfc8259). + +## 3. Overview + +This document proposes a new media type "application/schema+json" to identify a JSON +Schema for describing JSON data. +It also proposes a further optional media type, "application/schema-instance+json", +to provide additional integration features. +JSON Schemas are themselves JSON documents. +This, and related specifications, define keywords allowing authors to describe JSON +data in several ways. + +JSON Schema uses keywords to assert constraints on JSON instances or annotate those +instances with additional information. Additional keywords are used to apply +assertions and annotations to more complex JSON data structures, or based on +some sort of condition. + +To facilitate re-use, keywords can be organized into vocabularies. A vocabulary +consists of a list of keywords, together with their syntax and semantics. +A dialect is defined as a set of vocabularies and their required support +identified in a meta-schema. + +JSON Schema can be extended either by defining additional vocabularies, +or less formally by defining additional keywords outside of any vocabulary. +Unrecognized individual keywords simply have their values collected as annotations, +while the behavior with respect to an unrecognized vocabulary can be controlled +when declaring which vocabularies are in use. + +This document defines a core vocabulary that MUST be supported by any +implementation, and cannot be disabled. Its keywords are each prefixed +with a "$" character to emphasize their required nature. This vocabulary +is essential to the functioning of the "application/schema+json" media +type, and is used to bootstrap the loading of other vocabularies. + +Additionally, this document defines a RECOMMENDED vocabulary of keywords +for applying subschemas conditionally, and for applying subschemas to +the contents of objects and arrays. Either this vocabulary or one very +much like it is required to write schemas for non-trivial JSON instances, +whether those schemas are intended for assertion validation, annotation, +or both. While not part of the required core vocabulary, for maximum +interoperability this additional vocabulary is included in this document +and its use is strongly encouraged. + +Further vocabularies for purposes such as structural validation or +hypermedia annotation are defined in other documents. These other +documents each define a dialect collecting the standard sets of +vocabularies needed to write schemas for that document's purpose. + +## 4. Definitions + +### 4.1. JSON Document + +A JSON document is an information resource (series of octets) described by the +application/json media type. + +In JSON Schema, the terms "JSON document", "JSON text", and "JSON value" are +interchangeable because of the data model it defines in [Section 4.2.1](#421-instance-data-model). + +JSON Schema is only defined over JSON documents. However, any document or memory +structure that can be parsed into or processed according to the JSON Schema data +model can be interpreted against a JSON Schema, including media types like +[CBOR](#rfc7049). + +### 4.2. Instance + +A JSON document to which a schema is applied is known as an "instance". + +JSON Schema is defined over "application/json" or compatible documents, +including media types with the "+json" structured syntax suffix. + +Among these, this specification defines the "application/schema-instance+json" +media type which defines handling for fragments in the IRI. + +#### 4.2.1. Instance Data Model + +JSON Schema interprets documents according to a data model. A JSON value +interpreted according to this data model is called an "instance". + +An instance has one of six primitive types, and a range of possible values +depending on the type: + +- *null:* A JSON "null" value +- *boolean:* A "true" or "false" value, from the JSON "true" or "false" value +- *object:* An unordered set of properties mapping a string to an instance, from the JSON "object" value +- *array:* An ordered list of instances, from the JSON "array" value +- *number:* An arbitrary-precision, base-10 decimal number value, from the JSON "number" value +- *string:* A string of Unicode code points, from the JSON "string" value + +Whitespace and formatting concerns, including different lexical +representations of numbers that are equal within the data model, are thus +outside the scope of JSON Schema. JSON Schema +[vocabularies](#81-meta-schemas-and-vocabularies) that wish +to work with such differences in lexical representations SHOULD define +keywords to precisely interpret formatted strings within the data model +rather than relying on having the original JSON representation Unicode +characters available. + +Since an object cannot have two properties with the same key, behavior for a +JSON document that tries to define two properties with +the same key in a single object is undefined. + +Note that JSON Schema vocabularies are free to define their own extended +type system. This should not be confused with the core data model types +defined here. As an example, "integer" is a reasonable type for a +vocabulary to define as a value for a keyword, but the data model +makes no distinction between integers and other numbers. + +#### 4.2.2. Instance Equality + +Two JSON instances are said to be equal if and only if they are of the same type +and have the same value according to the data model. Specifically, this means: + +- both are null; or +- both are true; or +- both are false; or +- both are strings, and are the same codepoint-for-codepoint; or +- both are numbers, and have the same mathematical value; or +- both are arrays, and have an equal value item-for-item; or +- both are objects, and each property in one has exactly one property with + a key equal to the other's, and that other property has an equal + value. + +Implied in this definition is that arrays must be the same length, +objects must have the same number of members, +properties in objects are unordered, +there is no way to define multiple properties with the same key, +and mere formatting differences (indentation, placement of commas, trailing +zeros) are insignificant. + +#### 4.2.3. Non-JSON Instances + +It is possible to use JSON Schema with a superset of the JSON Schema data model, +where an instance may be outside any of the six JSON data types. + +In this case, annotations still apply; but most validation keywords will not be useful, +as they will always pass or always fail. + +A custom vocabulary may define support for a superset of the core data model. +The schema itself may only be expressible in this superset; +for example, to make use of the "const" keyword. + +### 4.3. JSON Schema Documents + +A JSON Schema document, or simply a schema, is a JSON document used to describe +an instance. +A schema can itself be interpreted as an instance, but SHOULD always be given +the media type "application/schema+json" rather than +"application/schema-instance+json". The "application/schema+json" media +type is defined to offer a superset of the +fragment identifier syntax and semantics provided by +"application/schema-instance+json". + +A JSON Schema MUST be an object or a boolean. + +#### 4.3.1. JSON Schema Objects and Keywords + +Object properties that are applied to the instance are called keywords, +or schema keywords. Broadly speaking, keywords fall into one +of five categories: + +- *identifiers:* control schema identification through setting a IRI + for the schema and/or changing how the base IRI is determined +- *assertions:* produce a boolean result when applied to an instance +- *annotations:* attach information to an instance for application use +- *applicators:* apply one or more subschemas to a particular location + in the instance, and combine or modify their results +- *reserved locations:* do not directly affect results, but reserve a place + for a specific purpose to ensure interoperability + +Keywords may fall into multiple categories, although applicators +SHOULD only produce assertion results based on their subschemas' +results. They should not define additional constraints independent +of their subschemas. + +Keywords which are properties within the same schema object are referred to as adjacent keywords. + +Extension keywords, meaning those defined outside of this document +and its companions, are free to define other behaviors as well. + +A JSON Schema MAY contain properties which are not schema keywords or are not recognized as schema keywords. +The behavior of such keywords is governed by [Section 6.5.1](#651-handling-of-unrecognized-or-unsupported-keywords). + +An empty schema is a JSON Schema with no properties. + +#### 4.3.2. Boolean JSON Schemas + +The boolean schema values "true" and "false" are trivial schemas that +always produce themselves as assertion results, regardless of the +instance value. They never produce annotation results. + +These boolean schemas exist to clarify schema author intent and +facilitate schema processing optimizations. They behave identically +to the following schema objects (where "not" is part of the +subschema application vocabulary defined in this document). + +- *true:* Always passes validation, as if the empty schema {} +- *false:* Always fails validation, as if the schema { "not": {} } + While the empty schema object is unambiguous, there are many + possible equivalents to the "false" schema. Using the boolean + values ensures that the intent is clear to both human readers + and implementations. + +#### 4.3.3. Schema Vocabularies + +A schema vocabulary, or simply a vocabulary, is a set of keywords, +their syntax, and their semantics. A vocabulary is generally organized +around a particular purpose. Different uses of JSON Schema, such +as validation, hypermedia, or user interface generation, will +involve different sets of vocabularies. + +Vocabularies are the primary unit of re-use in JSON Schema, as schema +authors can indicate what vocabularies are required or optional in +order to process the schema. Since vocabularies are identified by IRIs +in the meta-schema, generic implementations can load extensions to support +previously unknown vocabularies. While keywords can be supported outside +of any vocabulary, there is no analogous mechanism to indicate individual +keyword usage. + +A schema vocabulary can be defined by anything from an informal description +to a standards proposal, depending on the audience and interoperability +expectations. In particular, in order to facilitate vocabulary use within +non-public organizations, a vocabulary specification need not be published +outside of its scope of use. + +#### 4.3.4. Meta-Schemas + +A schema that itself describes a schema is called a meta-schema. +Meta-schemas are used to validate JSON Schemas and specify which vocabularies +they are using. + +Typically, a meta-schema will specify a set of vocabularies, and validate +schemas that conform to the syntax of those vocabularies. However, meta-schemas +and vocabularies are separate in order to allow meta-schemas to validate +schema conformance more strictly or more loosely than the vocabularies' +specifications call for. Meta-schemas may also describe and validate +additional keywords that are not part of a formal vocabulary. + +#### 4.3.5. Root Schema and Subschemas and Resources + +A JSON Schema resource is a schema which is +[canonically](#rfc6596) identified by an +[absolute IRI](#rfc3987). Schema resources MAY +also be identified by IRIs, including IRIs with fragments, +if the resulting secondary resource (as defined by +[section 3.5 of RFC 3986](#rfc3986)) is identical +to the primary resource. This can occur with the empty fragment, +or when one schema resource is embedded in another. Any such IRIs +with fragments are considered to be non-canonical. + +The root schema is the schema that comprises the entire JSON document +in question. The root schema is always a schema resource, where the +IRI is determined as described in [Section 9.1.1](#911-initial-base-iri).[^1] +[^1]: Note that documents that embed schemas in another format will not +have a root schema resource in this sense. Exactly how such usages +fit with the JSON Schema document and resource concepts will be +clarified in a future draft. + +Some keywords take schemas themselves, allowing JSON Schemas to be nested: + +```json +{ + "title": "root", + "items": { + "title": "array item" + } +} +``` + +In this example document, the schema titled "array item" is a subschema, +and the schema titled "root" is the root schema. + +As with the root schema, a subschema is either an object or a boolean. + +As discussed in [Section 8.2.1](#821-the--id--keyword), a JSON Schema document +can contain multiple JSON Schema resources. When used without qualification, +the term "root schema" refers to the document's root schema. In some +cases, resource root schemas are discussed. A resource's root schema +is its top-level schema object, which would also be a document root schema +if the resource were to be extracted to a standalone JSON Schema document. + +Whether multiple schema resources are embedded or linked with a reference, +they are processed in the same way, with the same available behaviors. + +## 5. Fragment Identifiers + +In accordance with section 3.1 of [RFC 6839](#rfc6839), +the syntax and semantics of fragment identifiers specified for +any +json media type SHOULD be as specified for "application/json". +(At publication of this document, there is no fragment identification +syntax defined for "application/json".) + +Additionally, the "application/schema+json" media type supports two +fragment identifier structures: plain names and JSON Pointers. +The "application/schema-instance+json" media type supports one +fragment identifier structure: JSON Pointers. + +The use of JSON Pointers as IRI fragment identifiers is described in +[RFC 6901](#rfc6901). +For "application/schema+json", which supports two fragment identifier syntaxes, +fragment identifiers matching the JSON Pointer syntax, including the empty string, +MUST be interpreted as JSON Pointer fragment identifiers. + +Per the W3C's +[best practices for fragment identifiers](#w3cwd-fragid-best-practices-20121025), +plain name fragment identifiers in "application/schema+json" are reserved for referencing +locally named schemas. + +Plain name fragments MUST start with a letter ([A-Za-z]) or underscore ("_"), +followed by any number of letters, digits ([0-9]), hyphens ("-"), +underscores ("_"), and periods ("."). This matches the US-ASCII part of XML's +[NCName production](#xml-names), which allows for compatibility +with the recommended plain name [syntax](#w3crec-xptr-framework-20030325) for +XML-based media types. + +All fragment identifiers that do +not match the JSON Pointer syntax MUST be interpreted as +plain name fragment identifiers. + +Defining and referencing a plain name fragment identifier within an +"application/schema+json" document are specified +in the ["$anchor" keyword](#822-defining-location-independent-identifiers) section. + +## 6. General Considerations + +### 6.1. Range of JSON Values + +An instance may be any valid JSON value as defined by [JSON](#rfc8259). +JSON Schema imposes no restrictions on type: JSON Schema can describe any JSON +value, including, for example, null. + +### 6.2. Programming Language Independence + +JSON Schema is programming language agnostic, and supports the full range of +values described in the data model. +Be aware, however, that some languages and JSON parsers may not be able to +represent in memory the full range of values describable by JSON. + +### 6.3. Mathematical Integers + +Some programming languages and parsers use different internal representations +for floating point numbers than they do for integers. + +For consistency, integer JSON numbers SHOULD NOT be encoded with a fractional +part. + +### 6.4. Regular Expressions + +Keywords MAY use regular expressions to express constraints, or constrain +the instance value to be a regular expression. +These regular expressions SHOULD be valid according to the regular expression +dialect described in [ECMA-262, section 21.2.1](#ecma262). + +Unless otherwise specified by a keyword, regular expressions MUST NOT be +considered to be implicitly anchored at either end. All regular expression +keywords in this specification and its companion documents are un-anchored. + +Regular expressions SHOULD be built with the "u" flag (or equivalent) to provide +Unicode support, or processed in such a way which provides Unicode support as +defined by ECMA-262. + +Furthermore, given the high disparity in regular expression constructs support, +schema authors SHOULD limit themselves to the following regular expression +tokens: + +- individual Unicode characters, as defined by the [JSON specification](#rfc8259); +- simple character classes ([abc]), range character classes ([a-z]); +- complemented character classes ([^abc], [^a-z]); +- simple quantifiers: "+" (one or more), "*" (zero or more), "?" (zero or + one), and their lazy versions ("+?", "*?", "??"); +- range quantifiers: "{x}" (exactly x occurrences), "{x,y}" (at least x, at + most y, occurrences), {x,} (x occurrences or more), and their lazy + versions; +- the beginning-of-input ("^") and end-of-input ("$") anchors; +- simple grouping ("(...)") and alternation ("|"). + +Finally, implementations MUST NOT take regular expressions to be +anchored, neither at the beginning nor at the end. This means, for instance, +the pattern "es" matches "expression". + +### 6.5. Extending JSON Schema + +Additional schema keywords and schema vocabularies MAY be defined +by any entity. Save for explicit agreement, schema authors SHALL NOT +expect these additional keywords and vocabularies to be supported by +implementations that do not explicitly document such support. + +Implementations MAY provide the ability to register or load handlers +for vocabularies that they do not support directly. The exact mechanism +for registering and implementing such handlers is implementation-dependent. + +#### 6.5.1. Handling of unrecognized or unsupported keywords + +Implementations SHOULD treat keywords they do not recognize, or that +they recognize but do not support, as annotations, where the value of +the keyword is the value of the annotation. Whether an implementation +collects these annotations or not, they MUST otherwise ignore the keywords. + +## 7. Keyword Behaviors + +JSON Schema keywords fall into several general behavior categories. +Assertions validate that an instance satisfies constraints, producing +a boolean result. Annotations attach information that applications +may use in any way they see fit. +Applicators apply subschemas to parts of the instance and combine +their results. + +Extension keywords SHOULD stay within these categories, keeping in mind +that annotations in particular are extremely flexible. Complex behavior +is usually better delegated to applications on the basis of annotation +data than implemented directly as schema keywords. However, extension +keywords MAY define other behaviors for specialized purposes. + +Evaluating an instance against a schema involves processing all of the +keywords in the schema against the appropriate locations within the instance. +Typically, applicator keywords are processed until a schema object with no +applicators (and therefore no subschemas) is reached. The appropriate +location in the instance is evaluated against the assertion and +annotation keywords in the schema object. The interactions of those +keyword results to produce the schema object results are governed by +[Section 7.7.1.2](#7712-annotations-and-assertions), while the +relationship of subschema results to the results of the applicator +keyword that applied them is described by [Section 7.5](#75-applicators). + +Evaluation of a parent schema object can complete once all of its +subschemas have been evaluated, although in some circumstances evaluation +may be short-circuited due to assertion results. When annotations are +being collected, some assertion result short-circuiting is not possible +due to the need to examine all subschemas for annotation collection, including +those that cannot further change the assertion result. + +### 7.1. Lexical Scope and Dynamic Scope + +While most JSON Schema keywords can be evaluated on their own, +or at most need to take into account the values or results of +adjacent keywords in the same schema object, a few have more +complex behavior. + +The lexical scope of a keyword is determined by the nested JSON +data structure of objects and arrays. The largest such scope +is an entire schema document. The smallest scope is a single +schema object with no subschemas. + +Keywords MAY be defined with a partial value, such as a IRI-reference, +which must be resolved against another value, such as another +IRI-reference or a full IRI, which is found through the lexical +structure of the JSON document. The "$id", "$ref", and +"$dynamicRef" core keywords, and the "base" JSON Hyper-Schema +keyword, are examples of this sort of behavior. + +Note that some keywords, such as "$schema", apply to the lexical +scope of the entire schema resource, and therefore MUST only +appear in a schema resource's root schema. + +Other keywords may take into account the dynamic scope that +exists during the evaluation of a schema, typically together +with an instance document. +The outermost dynamic scope is the schema object at +which processing begins, even if it is not a schema resource root. +The path from this root schema to any particular keyword (that +includes any "$ref" and "$dynamicRef" keywords that may have +been resolved) is considered the keyword's "evaluation path." + +Lexical and dynamic scopes align until a reference keyword +is encountered. While following the reference keyword moves processing +from one lexical scope into a different one, from the perspective +of dynamic scope, following a reference is no different from descending +into a subschema present as a value. A keyword on the far side of +that reference that resolves information through the dynamic scope +will consider the originating side of the reference to be their +dynamic parent, rather than examining the local lexically enclosing parent. + +The concept of dynamic scope is primarily used with "$dynamicRef" and +"$dynamicAnchor", and should be considered an advanced feature +and used with caution when defining additional keywords. It also appears +when reporting errors and collected annotations, as it may be possible +to revisit the same lexical scope repeatedly with different dynamic +scopes. In such cases, it is important to inform the user of the +evaluation path that produced the error or annotation. + +### 7.2. Keyword Interactions + +Keyword behavior MAY be defined in terms of the annotation results +of [subschemas](#435-root-schema-and-subschemas-and-resources) and/or adjacent keywords +(keywords within the same schema object) and their subschemas. +Such keywords MUST NOT result in a circular dependency. +Keywords MAY modify their behavior based on the presence or absence +of another keyword in the same +[schema object](#43-json-schema-documents). + +### 7.3. Default Behaviors + +A missing keyword MUST NOT produce a false assertion result, MUST +NOT produce annotation results, and MUST NOT cause any other schema +to be evaluated as part of its own behavioral definition. +However, given that missing keywords do not contribute annotations, +the lack of annotation results may indirectly change the behavior +of other keywords. + +In some cases, the missing keyword assertion behavior of a keyword is +identical to that produced by a certain value, and keyword definitions +SHOULD note such values where known. However, even if the value which +produces the default behavior would produce annotation results if +present, the default behavior still MUST NOT result in annotations. + +Because annotation collection can add significant cost in terms of both +computation and memory, implementations MAY opt out of this feature. +Keywords that are specified in terms of collected annotations SHOULD +describe reasonable alternate approaches when appropriate. +This approach is demonstrated by the +"[items](#10312-items)" and +"[additionalProperties](#10323-additionalproperties)" keywords in this +document. + +Note that when no such alternate approach is possible for a keyword, +implementations that do not support annotation collections will not +be able to support those keywords or vocabularies that contain them. + +### 7.4. Identifiers + +Identifiers define IRIs for a schema, or affect how such IRIs are +resolved in [references](#824-schema-references), or both. +The Core vocabulary defined in this document defines several +identifying keywords, most notably "$id". + +Canonical schema IRIs MUST NOT change while processing an instance, but +keywords that affect IRI-reference resolution MAY have behavior that +is only fully determined at runtime. + +While custom identifier keywords are possible, vocabulary designers should +take care not to disrupt the functioning of core keywords. For example, +the "$dynamicAnchor" keyword in this specification limits its IRI resolution +effects to the matching "$dynamicRef" keyword, leaving the behavior +of "$ref" undisturbed. + +### 7.5. Applicators + +Applicators allow for building more complex schemas than can be accomplished +with a single schema object. Evaluation of an instance against a +[schema document](#43-json-schema-documents) begins by applying +the [root schema](#435-root-schema-and-subschemas-and-resources) to the complete instance +document. From there, keywords known as applicators are used to determine +which additional schemas are applied. Such schemas may be applied in-place +to the current location, or to a child location. + +The schemas to be applied may be present as subschemas comprising all or +part of the keyword's value. Alternatively, an applicator may refer to +a schema elsewhere in the same schema document, or in a different one. +The mechanism for identifying such referenced schemas is defined by the +keyword. + +Applicator keywords also define how subschema or referenced schema +boolean [assertion](#76-assertions) +results are modified and/or combined to produce the boolean result +of the applicator. Applicators may apply any boolean logic operation +to the assertion results of subschemas, but MUST NOT introduce new +assertion conditions of their own. + +[Annotation](#77-annotations) results from subschemas +are preserved in accordance with [Section 7.7.1](#771-collecting-annotations) so that applications +can decide how to interpret multiple values. Applicator keywords +do not play a direct role in this preservation. + +#### 7.5.1. Referenced and Referencing Schemas + +As noted in [Section 7.5](#75-applicators), an applicator keyword may +refer to a schema to be applied, rather than including it as a +subschema in the applicator's value. In such situations, the +schema being applied is known as the referenced schema, while +the schema containing the applicator keyword is the referencing schema. + +While root schemas and subschemas are static concepts based on a +schema's position within a schema document, referenced and referencing +schemas are dynamic. Different pairs of schemas may find themselves +in various referenced and referencing arrangements during the evaluation +of an instance against a schema. + +For some by-reference applicators, such as +["$ref"](#8241-direct-references-with--ref-), the referenced schema can be determined +by static analysis of the schema document's lexical scope. Others, +such as "$dynamicRef" (with "$dynamicAnchor"), may make use of dynamic +scoping, and therefore only be resolvable in the process of evaluating +the schema with an instance. + +### 7.6. Assertions + +JSON Schema can be used to assert constraints on a JSON document, which +either passes or fails the assertions. This approach can be used to validate +conformance with the constraints, or document what is needed to satisfy them. + +JSON Schema implementations produce a single boolean result when evaluating +an instance against schema assertions. + +An instance can only fail an assertion that is present in the schema. + +#### 7.6.1. Assertions and Instance Primitive Types + +Most assertions only constrain values within a certain +primitive type. When the type of the instance is not of the type +targeted by the keyword, the instance is considered to conform +to the assertion. + +For example, the "maxLength" keyword from the companion +[validation vocabulary](#json-schema-validation): +will only restrict certain strings +(that are too long) from being valid. If the instance is a number, +boolean, null, array, or object, then it is valid against this assertion. + +This behavior allows keywords to be used more easily with instances +that can be of multiple primitive types. The companion validation +vocabulary also includes a "type" keyword which can independently +restrict the instance to one or more primitive types. This allows +for a concise expression of use cases such as a function that might +return either a string of a certain length or a null value: + +```json +{ + "type": [ + "string", + "null" + ], + "maxLength": 255 +} +``` + +If "maxLength" also restricted the instance type to be a string, +then this would be substantially more cumbersome to express because +the example as written would not actually allow null values. +Each keyword is evaluated separately unless explicitly specified +otherwise, so if "maxLength" restricted the instance to strings, +then including "null" in "type" would not have any useful effect. + +### 7.7. Annotations + +JSON Schema can annotate an instance with information, whenever the instance +validates against the schema object containing the annotation, and all of its +parent schema objects. The information can be a simple value, or can be +calculated based on the instance contents. + +Annotations are attached to specific locations in an instance. +Since many subschemas can be applied to any single +location, applications may need to decide how to handle differing +annotation values being attached to the same instance location by +the same schema keyword in different schema objects. + +Unlike assertion results, annotation data can take a wide variety of forms, +which are provided to applications to use as they see fit. JSON Schema +implementations are not expected to make use of the collected information +on behalf of applications. + +Unless otherwise specified, the value of an annotation keyword +is the keyword's value. However, other behaviors are possible. +For example, [JSON Hyper-Schema's](#json-hyper-schema) +"links" keyword is a complex annotation that produces a value based +in part on the instance data. + +While "short-circuit" evaluation is possible for assertions, collecting +annotations requires examining all schemas that apply to an instance +location, even if they cannot change the overall assertion result. +The only exception is that subschemas of a schema object that has +failed validation MAY be skipped, as annotations are not retained +for failing schemas. + +#### 7.7.1. Collecting Annotations + +Annotations are collected by keywords that explicitly define +annotation-collecting behavior. Note that boolean schemas cannot +produce annotations as they do not make use of keywords. + +A collected annotation MUST include the following information: + +- The name of the keyword that produces the annotation +- The instance location to which it is attached, as a JSON Pointer +- The evaluation path, indicating how reference keywords + such as "$ref" were followed to reach the absolute schema location. +- The absolute schema location of the attaching keyword, as a IRI. + This MAY be omitted if it is the same as the evaluation path + from above. +- The attached value(s) + +##### 7.7.1.1. Distinguishing Among Multiple Values + +Applications MAY make decisions on which of multiple annotation values +to use based on the schema location that contributed the value. +This is intended to allow flexible usage. Collecting the schema location +facilitates such usage. + +For example, consider this schema, which uses annotations and assertions from +the [Validation specification](#json-schema-validation): + +```json +{ + "title": "Feature list", + "type": "array", + "prefixItems": [ + { + "title": "Feature A", + "properties": { + "enabled": { + "$ref": "#/$defs/enabledToggle", + "default": true + } + } + }, + { + "title": "Feature B", + "properties": { + "enabled": { + "description": "If set to null, Feature B inherits the enabled value from Feature A", + "$ref": "#/$defs/enabledToggle" + } + } + } + ], + "$defs": { + "enabledToggle": { + "title": "Enabled", + "description": "Whether the feature is enabled (true), disabled (false), or under automatic control (null)", + "type": [ + "boolean", + "null" + ], + "default": null + } + } +} +``` + +In this example, both Feature A and Feature B make use of the re-usable +"enabledToggle" schema. That schema uses the "title", "description", +and "default" annotations. Therefore the application has to decide how +to handle the additional "default" value for Feature A, and the additional +"description" value for Feature B. + +The application programmer and the schema author need to agree on the +usage. For this example, let's assume that they agree that the most +specific "default" value will be used, and any additional, more generic +"default" values will be silently ignored. Let's also assume that they +agree that all "description" text is to be used, starting with the most +generic, and ending with the most specific. This requires the schema +author to write descriptions that work when combined in this way. + +The application can use the evaluation path to determine which +values are which. The values in the feature's immediate "enabled" +property schema are more specific, while the values under the re-usable +schema that is referenced to with "$ref" are more generic. The evaluation +path will show whether each value was found by crossing a +"$ref" or not. + +Feature A will therefore use a default value of true, while Feature B +will use the generic default value of null. Feature A will only +have the generic description from the "enabledToggle" schema, while +Feature B will use that description, and also append its locally +defined description that explains how to interpret a null value. + +Note that there are other reasonable approaches that a different application +might take. For example, an application may consider the presence of +two different values for "default" to be an error, regardless of their +schema locations. + +##### 7.7.1.2. Annotations and Assertions + +Schema objects that produce a false assertion result MUST NOT +produce any annotation results, whether from their own keywords +or from keywords in subschemas. + +Note that the overall schema results may still include annotations +collected from other schema locations. Given this schema: + +```json +{ + "oneOf": [ + { + "title": "Integer Value", + "type": "integer" + }, + { + "title": "String Value", + "type": "string" + } + ] +} +``` + +Against the instance `"This is a string"`, the +title annotation "Integer Value" is discarded because the type assertion +in that schema object fails. The title annotation "String Value" +is kept, as the instance passes the string type assertions. + +### 7.8. Reserved Locations + +A fourth category of keywords simply reserve a location to hold re-usable +components or data of interest to schema authors that is not suitable +for re-use. These keywords do not affect validation or annotation results. +Their purpose in the core vocabulary is to ensure that locations are +available for certain purposes and will not be redefined by extension +keywords. + +While these keywords do not directly affect results, as explained in +[Section 9.4.2](#942-references-to-possible-non-schemas) unrecognized +extension keywords that reserve locations for re-usable schemas may have +undesirable interactions with references in certain circumstances. + +### 7.9. Loading Instance Data + +While none of the vocabularies defined as part of this or the associated documents +define a keyword which may target and/or load instance data, it is possible that +other vocabularies may wish to do so. + +Keywords MAY be defined to use JSON Pointers or Relative JSON Pointers to examine +parts of an instance outside the current evaluation location. + +Keywords that allow adjusting the location using a Relative JSON Pointer SHOULD +default to using the current location if a default is desireable. + +## 8. The JSON Schema Core Vocabulary + +Keywords declared in this section, which all begin with "$", make up +the JSON Schema Core vocabulary. These keywords are either required in +order to process any schema or meta-schema, including those split across +multiple documents, or exist to reserve keywords for purposes that +require guaranteed interoperability. + +The Core vocabulary MUST be considered mandatory at all times, in order +to bootstrap the processing of further vocabularies. Meta-schemas +that use the ["$vocabulary"](#81-meta-schemas-and-vocabularies) keyword +to declare the vocabularies in use MUST explicitly list the Core vocabulary, +which MUST have a value of true indicating that it is required. + +The behavior of a false value for this vocabulary (and only this +vocabulary) is undefined, as is the behavior when "$vocabulary" +is present but the Core vocabulary is not included. However, it +is RECOMMENDED that implementations detect these cases and raise +an error when they occur. It is not meaningful to declare that +a meta-schema optionally uses Core. + +Meta-schemas that do not use "$vocabulary" MUST be considered to +require the Core vocabulary as if its IRI were present with a value of true. + +The current IRI for the Core vocabulary is: +. + +The current IRI for the corresponding meta-schema is: +https://json-schema.org/draft/next/meta/core. + +While the "$" prefix is not formally reserved for the Core vocabulary, +it is RECOMMENDED that extension keywords (in vocabularies or otherwise) +begin with a character other than "$" to avoid possible future collisions. + +### 8.1. Meta-Schemas and Vocabularies + +Two concepts, meta-schemas and vocabularies, are used to inform an implementation +how to interpret a schema. Every schema has a meta-schema, which can be declared +using the "$schema" keyword. + +The meta-schema serves two purposes: + +- *Declaring the vocabularies in use* The "$vocabulary" keyword, when it appears in a meta-schema, declares + which vocabularies are available to be used in schemas that refer + to that meta-schema. Vocabularies define keyword semantics, + as well as their general syntax. +- *Describing valid schema syntax* A schema MUST successfully validate against its meta-schema, which + constrains the syntax of the available keywords. The syntax described + is expected to be compatible with the vocabularies declared; while + it is possible to describe an incompatible syntax, such a meta-schema + would be unlikely to be useful. + +Meta-schemas are separate from vocabularies to allow for +vocabularies to be combined in different ways, and for meta-schema authors +to impose additional constraints such as forbidding certain keywords, or +performing unusually strict syntactical validation, as might be done +during a development and testing cycle. Each vocabulary typically identifies +a meta-schema consisting only of the vocabulary's keywords. + +Meta-schema authoring is an advanced usage of JSON Schema, so the design of +meta-schema features emphasizes flexibility over simplicity. + +#### 8.1.1. The "$schema" Keyword + +The "$schema" keyword is both used as a JSON Schema dialect identifier and +as the identifier of a resource which is itself a JSON Schema, which describes the +set of valid schemas written for this particular dialect. + +The value of this keyword MUST be a [IRI](#rfc3987) +(containing a scheme) and this IRI MUST be normalized. +The current schema MUST be valid against the meta-schema identified by this IRI. + +If this IRI identifies a retrievable resource, that resource SHOULD be of +media type "application/schema+json". + +The "$schema" keyword SHOULD be used in the document root schema object, +and MAY be used in the root schema objects of embedded schema resources. +It MUST NOT appear in non-resource root schema objects. If absent from +the document root schema, the resulting behavior is implementation-defined, +but MUST fall within the following options: + +- Refuse to process the schema, as with unsupported required + vocabularies +- Assume a specific, documented meta-schema +- Document the process by which it examines the schema and determines + which of a specific set of meta-schemas to assume + +Values for this property are defined elsewhere in this and other documents, +and by other parties. + +#### 8.1.2. The "$vocabulary" Keyword + +The "$vocabulary" keyword is used in meta-schemas to identify the +vocabularies available for use in schemas described by that meta-schema, +and whether each vocabulary is required or optional. Together, this +information forms a dialect. + +The value of this keyword MUST be an object. The property names in the +object MUST be IRIs (containing a scheme) and each IRI MUST be normalized. +Each IRI that appears as a property name identifies a specific set of +keywords and their semantics. + +The IRI MAY be a URL, but the nature of the retrievable resource is +currently undefined, and reserved for future use. Vocabulary authors +MAY use the URL of the vocabulary specification, in a human-readable +media type such as text/html or text/plain, as the vocabulary IRI.[^2] +[^2]: Vocabulary documents may be added in forthcoming drafts. +For now, identifying the keyword set is deemed sufficient as that, +along with meta-schema validation, is how the current "vocabularies" +work today. Any future vocabulary document format will be specified +as a JSON document, so using text/html or other non-JSON formats +in the meantime will not produce any future ambiguity. + +The values of the object properties MUST be booleans. +If the value is true, then the vocabulary MUST be considered to be required. +If the value is false, then the vocabulary MUST be considered to be optional. + +##### 8.1.2.1. Required, optional, and omitted vocabularies + +A schema is said to use a dialect and its constituent vocabularies if it is +associated with a meta-schema defining the dialect with "$vocabulary", +either through "$schema", through appropriately defined media type parameters +or link relation types, or through documented default implementation-defined +behavior in the absence of an explicit meta-schema. If a meta-schema +does not contain "$vocabulary", the set of vocabularies in use is determined +according to [Section 8.1.2.4](#8124-default-vocabularies). + +Any vocabulary in use by a schema and understood by the implementation +MUST be processed in a manner consistent with the semantic definitions +contained within the vocabulary, regardless of whether that vocabulary +is required or optional. + +Any vocabulary that is not present in "$vocabulary" MUST NOT be made +available for use in schemas described by that meta-schema, except for +the core vocabulary as specified by the introduction to +[Section 8](#8-the-json-schema-core-vocabulary). + +Implementations that do not support a vocabulary required by a schema +MUST refuse to process that schema. + +Implementations that do not support a vocabulary that is optionally used +by a schema SHOULD proceed with processing the schema. The keywords will +be considered to be unrecognized keywords as addressed by +[Section 6.5.1](#651-handling-of-unrecognized-or-unsupported-keywords). Note that since +the recommended behavior for such keywords is to collect them as +annotations, vocabularies consisting only of annotations will have +the same behavior when used optionally whether the implementation +supports them or not. This allows annotation-only vocabularies to +be supported without custom code, even in implementations that do +not support providing custom code for extension vocabularies. + +##### 8.1.2.2. Vocabularies are schema resource-scoped + +The "$vocabulary" keyword SHOULD be used in the root schema of any schema +resource intended for use as a meta-schema. It MUST NOT appear in subschemas. + +The "$vocabulary" keyword MUST be ignored in schema resources that +are not being processed as a meta-schema. This allows validating +a meta-schema M against its own meta-schema M' without requiring +the validator to understand the vocabularies declared by M. + +##### 8.1.2.3. Vocabulary and non-vocabulary keywords + +Keywords from different vocabularies, as well as non-vocabulary +extension keywords, can have identical names. These are not +considered to be the same keyword from the perspective of +enabling or disabling them through "$vocabulary". + +In particular the keywords defined in this specification and its +companion documents MUST be considered to be vocabulary keywords, +with availability governed by "$vocabulary" even in implementations +that do not support any extension vocabularies. + +Guidance regarding vocabularies with identically-named keywords is provided +in [Appendix D.1](#d1-best-practices-for-vocabulary-and-meta-schema-authors). + +##### 8.1.2.4. Default vocabularies + +If "$vocabulary" is absent, an implementation MAY determine +behavior based on the meta-schema if it is recognized from the +IRI value of the referring schema's "$schema" keyword. +This is how behavior (such as Hyper-Schema usage) has been +recognized prior to the existence of vocabularies. + +If the meta-schema, as referenced by the schema, is not recognized, +or is missing, then the behavior is implementation-defined. +If the implementation +proceeds with processing the schema, it MUST assume the use of the +core vocabulary. If the implementation is built for a specific purpose, +then it SHOULD assume the use of all of the most relevant vocabularies +for that purpose. + +For example, an implementation that is a validator +SHOULD assume the use of all vocabularies in this +specification and the companion Validation specification. + +##### 8.1.2.5. Non-inheritability of vocabularies + +Note that the processing restrictions on "$vocabulary" mean that +meta-schemas that reference other meta-schemas using "$ref" or +similar keywords do not automatically inherit the vocabulary +declarations of those other meta-schemas. All such declarations +must be repeated in the root of each schema document intended +for use as a meta-schema. This is demonstrated in +[the example meta-schema](#d2-example-meta-schema-with-vocabulary-declarations).[^3] +[^3]: This requirement allows implementations to find all vocabulary +requirement information in a single place for each meta-schema. +As schema extensibility means that there are endless potential +ways to combine more fine-grained meta-schemas by reference, +requiring implementations to anticipate all possibilities and +search for vocabularies in referenced meta-schemas would +be overly burdensome. + +#### 8.1.3. Updates to Meta-Schema and Vocabulary IRIs + +Updated vocabulary and meta-schema IRIs MAY be published between +specification drafts in order to correct errors. Implementations +SHOULD consider IRIs dated after this specification draft and +before the next to indicate the same syntax and semantics +as those listed here. + +### 8.2. Base IRI, Anchors, and Dereferencing + +To differentiate between schemas in a vast ecosystem, schemas are +identified by [IRI](#rfc3987), and can embed references +to other schemas by specifying their IRI. + +Several keywords can accept a relative [IRI-reference](#rfc3987), +or a value used to construct a relative IRI-reference. For these keywords, +it is necessary to establish a base IRI in order to resolve the reference. + +#### 8.2.1. The "$id" Keyword + +The "$id" keyword identifies a schema resource with its +[canonical](#rfc6596) IRI. + +Note that this IRI is an identifier and not necessarily a network locator. +In the case of a network-addressable URL, a schema need not be downloadable +from its canonical IRI. + +If present, the value for this keyword MUST be a string, and MUST represent a +valid [IRI-reference](#rfc3987). This IRI-reference +SHOULD be normalized, and MUST resolve to an +[absolute-IRI](#rfc3987) (without a fragment). + +The resulting absolute-IRI serves as the base IRI for relative IRI-references +in keywords within the schema resource, in accordance with +[RFC 3987 section 6.5](#rfc3987) and +[RFC 3986 section 5.1.1](#rfc3986) regarding base IRIs +embedded in content. + +The presence of "$id" in a subschema indicates that the subschema constitutes +a distinct schema resource within a single schema document. Furthermore, +in accordance with [RFC 3987 section 6.5](#rfc3987) and +[RFC 3986 section 5.1.2](#rfc3986) regarding +encapsulating entities, if an "$id" in a subschema is a relative +IRI-reference, the base IRI for resolving that reference is the IRI of +the parent schema resource. Note that an "$id" consisting of an empty IRI or +of the empty fragment only will result in the embedded resource having +the same IRI as the encapsulating resource, which SHOULD be considered +an error per [Section 8.2.3](#823-duplicate-schema-identifiers). + +If no parent schema object explicitly identifies itself as a resource +with "$id", the base IRI is that of the entire document, as established +by the steps given in the [previous section.](#911-initial-base-iri) + +##### 8.2.1.1. Identifying the root schema + +The root schema of a JSON Schema document SHOULD contain an "$id" keyword +with an [absolute-IRI](#rfc3987) (containing a scheme, +but no fragment). + +#### 8.2.2. Defining location-independent identifiers + +Using JSON Pointer fragments requires knowledge of the structure of the schema. +When writing schema documents with the intention to provide re-usable +schemas, it may be preferable to use a plain name fragment that is not tied to +any particular structural location. This allows a subschema to be relocated +without requiring JSON Pointer references to be updated. + +The "$anchor" and "$dynamicAnchor" keywords are used to specify such +fragments. They are identifier keywords that can only be used to create +plain name fragments, rather than absolute IRIs as seen with "$id". + +The base IRI to which the resulting fragment is appended is the canonical +IRI of the schema resource containing the "$anchor" or "$dynamicAnchor" +in question. As discussed in the previous section, this is either the +nearest "$id" in the same or parent schema object, +or the base IRI for the document as determined according to +[RFC 3987](#rfc3987) and +[RFC 3986](#rfc3986). + +Separately from the usual usage of IRIs, "$dynamicAnchor" +indicates that the fragment is an extension point when used with +the "$dynamicRef" keyword. This low-level, advanced feature +makes it easier to extend recursive schemas such as the meta-schemas, +without imposing any particular semantics on that extension. +See the section on ["$dynamicRef"](#8242-dynamic-references-with--dynamicref-) +for details. + +In most cases, the normal fragment behavior both suffices and +is more intuitive. Therefore it is RECOMMENDED that "$anchor" +be used to create plain name fragments unless there is a clear +need for "$dynamicAnchor". + +If present, the value of these keywords MUST be a string and MUST conform +to the plain name fragment identifier syntax defined in +[Section 5](#5-fragment-identifiers).[^4] +[^4]: Note that the anchor string does not include the "#" character, +as it is not a IRI-reference. An "$anchor": "foo" becomes the +fragment "#foo" when used in a IRI. See below for full examples. + +#### 8.2.3. Duplicate schema identifiers + +A schema MAY (and likely will) have multiple IRIs, but there is no way +for an IRI to identify more than one schema. When multiple schemas +attempt to identify as the same IRI through the use of "$id", "$anchor", +"$dynamicAnchor", or any other mechanism, implementations SHOULD raise +an error condition. Otherwise the result is undefined, and even if +documented will not be interoperable. + +#### 8.2.4. Schema References + +Several keywords can be used to reference a schema which is to be applied to the +current instance location. "$ref" and "$dynamicRef" are applicator +keywords, applying the referenced schema to the instance. + +As the values of "$ref" and "$dynamicRef" are IRI References, this allows +the possibility to externalise or divide a schema across multiple files, +and provides the ability to validate recursive structures through +self-reference. + +The resolved IRI produced by these keywords is not necessarily a network +locator, only an identifier. A schema need not be downloadable from the +address if it is a network-addressable URL, and implementations SHOULD NOT +assume they should perform a network operation when they encounter +a network-addressable IRI. + +##### 8.2.4.1. Direct References with "$ref" + +The "$ref" keyword is an applicator that is used to reference a statically +identified schema. Its results are the results of the referenced schema.[^5] +[^5]: Note that this definition of how the results are determined means that +other keywords can appear alongside of "$ref" in the same schema object. + +The value of the "$ref" keyword MUST be a string which is a IRI-Reference. +Resolved against the current IRI base, it produces the IRI of the schema +to apply. This resolution is safe to perform on schema load, as the +process of evaluating an instance cannot change how the reference resolves. + +##### 8.2.4.2. Dynamic References with "$dynamicRef" + +The "$dynamicRef" keyword is an applicator that allows for deferring the +full resolution until runtime, at which point it is resolved each time it is +encountered while evaluating an instance. + +Together with "$dynamicAnchor", "$dynamicRef" implements a cooperative +extension mechanism that is primarily useful with recursive schemas +(schemas that reference themselves). The extension point is defined with +"$dynamicAnchor" and only exhibits runtime dynamic behavior when referenced +with "$dynamicRef". + +The value of the "$dynamicRef" property MUST be a string which is a +IRI-Reference that contains a valid [plain name +fragment](#822-defining-location-independent-identifiers). Resolved against the current IRI base, it indicates +the schema resource used as the starting point for runtime resolution. +This initial resolution is safe to perform on schema load. + +The schema to apply is the outermost schema resource in the +[dynamic scope](#71-lexical-scope-and-dynamic-scope) that defines a +"$dynamicAnchor" that matches the plain name fragment in the initially +resolved IRI. + +For a full example using these keyword, see [Appendix C](#appendix-c-example-of-recursive-schema-extension).[^6] +[^6]: The difference between the hyper-schema meta-schema in pre-2019 +drafts and an this draft dramatically demonstrates the utility +of these keywords. + +#### 8.2.5. Schema Re-Use With "$defs" + +The "$defs" keyword reserves a location for schema +authors to inline re-usable JSON Schemas into a more general schema. +The keyword does not directly affect the validation result. + +This keyword's value MUST be an object. +Each member value of this object MUST be a valid JSON Schema. + +As an example, here is a schema describing an array of positive +integers, where the positive integer constraint is a subschema in +"$defs": + +```json +{ + "type": "array", + "items": { + "$ref": "#/$defs/positiveInteger" + }, + "$defs": { + "positiveInteger": { + "type": "integer", + "exclusiveMinimum": 0 + } + } +} +``` + +### 8.3. Comments With "$comment" + +This keyword reserves a location for comments from schema authors +to readers or maintainers of the schema. + +The value of this keyword MUST be a string. Implementations MUST NOT present this +string to end users. Tools for editing schemas SHOULD support displaying and +editing this keyword. The value of this keyword MAY be used in debug or error +output which is intended for developers making use of schemas. + +Schema vocabularies SHOULD allow "$comment" within any object containing +vocabulary keywords. Implementations MAY assume "$comment" is allowed +unless the vocabulary specifically forbids it. Vocabularies MUST NOT +specify any effect of "$comment" beyond what is described in this +specification. + +Tools that translate other media types or programming languages +to and from application/schema+json MAY choose to convert that media type or +programming language's native comments to or from "$comment" values. +The behavior of such translation when both native comments and "$comment" +properties are present is implementation-dependent. + +Implementations MAY strip "$comment" values at any point during processing. +In particular, this allows for shortening schemas when the size of deployed +schemas is a concern. + +Implementations MUST NOT take any other action based on the presence, absence, +or contents of "$comment" properties. In particular, the value of "$comment" +MUST NOT be collected as an annotation result. + +## 9. Loading and Processing Schemas + +### 9.1. Loading a Schema + +#### 9.1.1. Initial Base IRI + +[RFC 3987 Section 6.5](#rfc3987) and +[RFC 3986 Section 5.1](#rfc3986) defines how to determine the +default base IRI of a document. + +Informatively, the initial base IRI of a schema is the IRI at which it was +found, whether that was a network location, a local filesystem, or any other +situation identifiable by a IRI of any known scheme. + +If a schema document defines no explicit base IRI with "$id" +(embedded in content), the base IRI is that determined per +[RFC 3987 Section 6.5](#rfc3987) and +[RFC 3986 section 5](#rfc3986). + +If no source is known, or no IRI scheme is known for the source, a suitable +implementation-specific default IRI MAY be used as described in +[RFC 3987 Section 6.5](#rfc3987) and +[RFC 3986 Section 5.1.4](#rfc3986). It is RECOMMENDED +that implementations document any default base IRI that they assume. + +If a schema object is embedded in a document of another media type, then +the initial base IRI is determined according to the rules of that +media type. + +Unless the "$id" keyword described in an earlier section is present in the +root schema, this base IRI SHOULD be considered the canonical IRI of the +schema document's root schema resource. + +#### 9.1.2. Loading a referenced schema + +The use of IRIs to identify remote schemas does not necessarily mean anything is downloaded, +but instead JSON Schema implementations SHOULD understand ahead of time which schemas they will be using, +and the IRIs that identify them. + +When schemas are downloaded, +for example by a generic user-agent that does not know until runtime which schemas to download, +see [Usage for Hypermedia](#951-usage-for-hypermedia). + +Implementations SHOULD be able to associate arbitrary IRIs with an arbitrary +schema and/or automatically associate a schema's "$id"-given IRI, depending +on the trust that the validator has in the schema. Such IRIs and schemas +can be supplied to an implementation prior to processing instances, or may +be noted within a schema document as it is processed, producing associations +as shown in [Appendix A](#appendix-a-schema-identification-examples). + +#### 9.1.3. Detecting a Meta-Schema + +Implementations MUST recognize a schema as a meta-schema if it +is being examined because it was identified as such by another +schema's "$schema" keyword. This means that a single schema +document might sometimes be considered a regular schema, and +other times be considered a meta-schema. + +In the case of examining a schema which is its own meta-schema, +when an implementation begins processing it as a regular schema, +it is processed under those rules. However, when loaded a second +time as a result of checking its own "$schema" value, it is treated +as a meta-schema. So the same document is processed both ways in +the course of one session. + +Implementations MAY allow a schema to be explicitly passed as a meta-schema, +for implementation-specific purposes, such as pre-loading a commonly +used meta-schema and checking its vocabulary support requirements +up front. Meta-schema authors MUST NOT expect such features to be +interoperable across implementations. + +### 9.2. Dereferencing + +Schemas can be identified by any IRI that has been given to them, including +a JSON Pointer or their IRI given directly by "$id". In all cases, +dereferencing a "$ref" reference involves first resolving its value as a +IRI reference against the current base IRI per +[RFC 3986](#rfc3986). + +If the resulting IRI identifies a schema within the current document, or +within another schema document that has been made available to the implementation, +then that schema SHOULD be used automatically. + +For example, consider this schema: + +```json +{ + "$id": "https://example.net/root.json", + "type": "array", + "items": { + "$ref": "#item" + }, + "$defs": { + "single": { + "$anchor": "item", + "type": "object", + "additionalProperties": { + "$ref": "other.json" + } + } + } +} +``` + +When an implementation encounters the <#/$defs/single> schema, +it resolves the "$anchor" value as a fragment name against the current +base IRI to form . + +When an implementation then looks inside the <#/items> schema, it +encounters the <#item> reference, and resolves this to +, which it has seen defined in +this same document and can therefore use automatically. + +When an implementation encounters the reference to "other.json", it resolves +this to , which is not defined in this +document. If a schema with that identifier has otherwise been supplied to +the implementation, it can also be used automatically.[^7] +[^7]: What should implementations do when the referenced schema is not known? +Are there circumstances in which automatic network dereferencing is +allowed? A same origin policy? A user-configurable option? In the +case of an evolving API described by Hyper-Schema, it is expected that +new schemas will be added to the system dynamically, so placing an +absolute requirement of pre-loading schema documents is not feasible. + +#### 9.2.1. JSON Pointer fragments and embedded schema resources + +Since JSON Pointer IRI fragments are constructed based on the structure +of the schema document, an embedded schema resource and its subschemas +can be identified by JSON Pointer fragments relative to either its own +canonical IRI, or relative to any containing resource's IRI. + +Conceptually, a set of linked schema resources should behave +identically whether each resource is a separate document connected with +[schema references](#824-schema-references), or is structured as +a single document with one or more schema resources embedded as +subschemas. + +Since IRIs involving JSON Pointer fragments relative to the parent +schema resource's IRI cease to be valid when the embedded schema +is moved to a separate document and referenced, applications and schemas +SHOULD NOT use such IRIs to identify embedded schema resources or +locations within them. + +Consider the following schema document that contains another +schema resource embedded within it: + +```json +{ + "$id": "https://example.com/foo", + "items": { + "$id": "https://example.com/bar", + "additionalProperties": {} + } +} +``` + +The IRI "https://example.com/foo#/items" points to the "items" schema, +which is an embedded resource. The canonical IRI of that schema +resource, however, is "https://example.com/bar". + +For the "additionalProperties" schema within that embedded resource, +the IRI "https://example.com/foo#/items/additionalProperties" points +to the correct object, but that object's IRI relative to its resource's +canonical IRI is "https://example.com/bar#/additionalProperties". + +Now consider the following two schema resources linked by reference +using a IRI value for "$ref": + +```json +{ + "$id": "https://example.com/foo", + "items": { + "$ref": "bar" + } +} +``` + +```json +{ + "$id": "https://example.com/bar", + "additionalProperties": {} +} +``` + +Here we see that "https://example.com/bar#/additionalProperties", +using a JSON Pointer fragment appended to the canonical IRI of +the "bar" schema resource, is still valid, while +"https://example.com/foo#/items/additionalProperties", which relied +on a JSON Pointer fragment appended to the canonical IRI of the +"foo" schema resource, no longer resolves to anything. + +Note also that "https://example.com/foo#/items" is valid in both +arrangements, but resolves to a different value. This IRI ends up +functioning similarly to a retrieval IRI for a resource. While this IRI +is valid, it is more robust to use the "$id" of the embedded or referenced +resource unless it is specifically desired to identify the object containing +the "$ref" in the second (non-embedded) arrangement. + +An implementation MAY choose not to support addressing schema resource +contents by IRIs using a base other than the resource's canonical IRI, +plus a JSON Pointer fragment relative to that base. Therefore, schema +authors SHOULD NOT rely on such IRIs, as using them may reduce interoperability.[^8] +[^8]: This is to avoid requiring implementations to keep track of a whole +stack of possible base IRIs and JSON Pointer fragments for each, +given that all but one will be fragile if the schema resources +are reorganized. Some +have argued that this is easy so there is +no point in forbidding it, while others have argued that it complicates +schema identification and should be forbidden. Feedback on this +topic is encouraged. +After some discussion, we feel that we need to remove the use of +"canonical" in favour of talking about JSON Pointers which reference +across schema resource boundaries as undefined or even forbidden behavior +(https://github.com/json-schema-org/json-schema-spec/issues/937, +https://github.com/json-schema-org/json-schema-spec/issues/1183) + +Further examples of such non-canonical IRI construction, as well as +the appropriate canonical IRI-based fragments to use instead, +are provided in [Appendix A](#appendix-a-schema-identification-examples). + +### 9.3. Compound Documents + +A Compound Schema Document is defined as a JSON document (sometimes called a "bundled" schema) +which has multiple embedded JSON Schema Resources bundled into the same document to +ease transportation. + +Each embedded Schema Resource MUST be treated as an individual Schema Resource, following standard +schema loading and processing requirements, including determining vocabulary support. + +#### 9.3.1. Bundling + +The bundling process for creating a Compound Schema Document is defined as taking +references (such as "$ref") to an external Schema Resource and embedding the referenced +Schema Resources within the referring document. Bundling SHOULD be done in such a way that +all IRIs (used for referencing) in the base document and any referenced/embedded +documents do not require altering. + +Each embedded JSON Schema Resource MUST identify itself with a IRI using the "$id" keyword, +and SHOULD make use of the "$schema" keyword to identify the dialect it is using, in the root of the +schema resource. It is RECOMMENDED that the IRI identifier value of "$id" be an Absolute IRI. + +When the Schema Resource referenced by a by-reference applicator is bundled, it is RECOMMENDED that +the Schema Resource be located as a value of a "$defs" object at the containing schema's root. +The key of the "$defs" for the now embedded Schema Resource MAY be the "$id" of the bundled schema +or some other form of application defined unique identifer (such as a UUID). This key is not +intended to be referenced in JSON Schema, but may be used by an application to aid the +bundling process. + +A Schema Resource MAY be embedded in a location other than "$defs" where the location is defined +as a schema value. + +A Bundled Schema Resource MUST NOT be bundled by replacing the schema object from which it was +referenced, or by wrapping the Schema Resource in other applicator keywords. + +In order to produce identical output, references in the containing schema document to the +previously external Schema Resources MUST NOT be changed, and now resolve to a schema using the +"$id" of an embedded Schema Resource. Such identical output includes validation evaluation and IRIs +or paths used in resulting annotations or errors. + +While the bundling process will often be the main method for creating a Compound Schema Document, +it is also possible and expected that some will be created by hand, potentially without individual +Schema Resources existing on their own previously. + +#### 9.3.2. Differing and Default Dialects + +When multiple schema resources are present in a single document, +schema resources which do not define with which dialect they should be processed +MUST be processed with the same dialect as the enclosing resource. + +Since any schema that can be referenced can also be embedded, embedded schema resources MAY +specify different processing dialects using the "$schema" values from their enclosing resource. + +#### 9.3.3. Validating + +Given that a Compound Schema Document may have embedded resources which identify as using different +dialects, these documents SHOULD NOT be validated by applying a meta-schema +to the Compound Schema Document as an instance. It is RECOMMENDED that an alternate +validation process be provided in order to validate Schema Documents. Each Schema Resource +SHOULD be separately validated against its associated meta-schema.[^9] +[^9]: If you know a schema is what's being validated, you can identify if the schemas +is a Compound Schema Document or not, by way of use of "$id", which identifies an +embedded resource when used not at the document's root. + +A Compound Schema Document in which all embedded resources identify as using the same +dialect, or in which "$schema" is omitted and therefore defaults to that of the enclosing resource, +MAY be validated by applying the appropriate meta-schema. + +### 9.4. Caveats + +#### 9.4.1. Guarding Against Infinite Recursion + +A schema MUST NOT be run into an infinite loop against an instance. For +example, if two schemas "#alice" and "#bob" both have an "allOf" property +that refers to the other, a naive validator might get stuck in an infinite +recursive loop trying to validate the instance. Schemas SHOULD NOT make +use of infinite recursive nesting like this; the behavior is undefined. + +#### 9.4.2. References to Possible Non-Schemas + +Subschema objects (or booleans) are recognized by their use with known +applicator keywords or with location-reserving keywords such as +["$defs"](#825-schema-re-use-with--defs-) that take one or more subschemas +as a value. These keywords may be "$defs" and the standard applicators +from this document, or extension keywords from a known vocabulary, or +implementation-specific custom keywords. + +Multi-level structures of unknown keywords are capable of introducing +nested subschemas, which would be subject to the processing rules for +"$id". Therefore, having a reference target in such an unrecognized +structure cannot be reliably implemented, and the resulting behavior +is undefined. Similarly, a reference target under a known keyword, +for which the value is known not to be a schema, results in undefined +behavior in order to avoid burdening implementations with the need +to detect such targets.[^10] +[^10]: These scenarios are analogous to fetching a schema over HTTP +but receiving a response with a Content-Type other than +application/schema+json. An implementation can certainly +try to interpret it as a schema, but the origin server +offered no guarantee that it actually is any such thing. +Therefore, interpreting it as such has security implications +and may produce unpredictable results. + +Note that single-level custom keywords with identical syntax and +semantics to "$defs" do not allow for any intervening "$id" keywords, +and therefore will behave correctly under implementations that attempt +to use any reference target as a schema. However, this behavior is +implementation-specific and MUST NOT be relied upon for interoperability. + +### 9.5. Associating Instances and Schemas + +#### 9.5.1. Usage for Hypermedia + +JSON has been adopted widely by HTTP servers for automated APIs and robots. This +section describes how to enhance processing of JSON documents in a more RESTful +manner when used with protocols that support media types and +[Web linking](#rfc8288). + +##### 9.5.1.1. Linking to a Schema + +It is RECOMMENDED that instances described by a schema provide a link to +a downloadable JSON Schema using the link relation "describedby", as defined by +[Linked Data Protocol 1.0, section 8.1](#w3crec-ldp-20150226). + +In HTTP, such links can be attached to any response using the +[Link header](#rfc8288). An example of such a header would be: + +``` +Link: ; rel="describedby" +``` + +##### 9.5.1.2. Usage Over HTTP + +When used for hypermedia systems over a network, +[HTTP](#rfc7231) is frequently the protocol of choice for +distributing schemas. Misbehaving clients can pose problems for server +maintainers if they pull a schema over the network more frequently than +necessary, when it's instead possible to cache a schema for a long period of +time. + +HTTP servers SHOULD set long-lived caching headers on JSON Schemas. +HTTP clients SHOULD observe caching headers and not re-request documents within +their freshness period. +Distributed systems SHOULD make use of a shared cache and/or caching proxy. + +Clients SHOULD set or prepend a User-Agent header specific to the JSON Schema +implementation or software product. Since symbols are listed in decreasing order +of significance, the JSON Schema library name/version should precede the more +generic HTTP library name (if any). For example: + +``` +User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0 +``` + +Clients SHOULD be able to make requests with a "From" header so that server +operators can contact the owner of a potentially misbehaving script. + +## 10. A Vocabulary for Applying Subschemas + +This section defines a vocabulary of applicator keywords that +are RECOMMENDED for use as the basis of other vocabularies. + +Meta-schemas that do not use "$vocabulary" SHOULD be considered to +require this vocabulary as if its IRI were present with a value of true. + +The current IRI for this vocabulary, known as the Applicator vocabulary, is: +. + +The current IRI for the corresponding meta-schema is: +https://json-schema.org/draft/next/meta/applicator. + +### 10.1. Keyword Independence + +Schema keywords typically operate independently, without +affecting each other's outcomes. + +For schema author convenience, there are some exceptions among the +keywords in this vocabulary: + +- "additionalProperties", whose behavior is defined in terms of + "properties" and "patternProperties" +- "items", whose behavior is defined in terms of "prefixItems" +- "contains", whose behavior is affected by the presence and value of + "minContains" + +### 10.2. Keywords for Applying Subschemas in Place + +These keywords apply subschemas to the same location in the instance +as the parent schema is being applied. They allow combining +or modifying the subschema results in various ways. + +Subschemas of these keywords evaluate the instance completely independently +such that the results of one such subschema MUST NOT impact the results of sibling +subschemas. Therefore subschemas may be applied in +any order. + +#### 10.2.1. Keywords for Applying Subschemas With Logic + +These keywords correspond to logical operators for combining or modifying +the boolean assertion results of the subschemas. They have no direct +impact on annotation collection, although they enable the same annotation +keyword to be applied to an instance location with different values. +Annotation keywords define their own rules for combining such values. + +##### 10.2.1.1. allOf + +This keyword's value MUST be a non-empty array. +Each item of the array MUST be a valid JSON Schema. + +An instance validates successfully against this keyword if it validates +successfully against all schemas defined by this keyword's value. + +##### 10.2.1.2. anyOf + +This keyword's value MUST be a non-empty array. +Each item of the array MUST be a valid JSON Schema. + +An instance validates successfully against this keyword if it validates +successfully against at least one schema defined by this keyword's value. +Note that when annotations are being collected, all subschemas MUST +be examined so that annotations are collected from each subschema +that validates successfully. + +##### 10.2.1.3. oneOf + +This keyword's value MUST be a non-empty array. +Each item of the array MUST be a valid JSON Schema. + +An instance validates successfully against this keyword if it validates +successfully against exactly one schema defined by this keyword's value. + +##### 10.2.1.4. not + +This keyword's value MUST be a valid JSON Schema. + +An instance is valid against this keyword if it fails to validate +successfully against the schema defined by this keyword. + +#### 10.2.2. Keywords for Applying Subschemas Conditionally + +Three of these keywords work together to implement conditional +application of a subschema based on the outcome of another subschema. +The fourth is a shortcut for a specific conditional case. + +"if", "then", and "else" MUST NOT interact with each other across +subschema boundaries. In other words, an "if" in one +branch of an "allOf" MUST NOT have an impact on a "then" +or "else" in another branch. + +There is no default behavior for "if", "then", or "else" +when they are not present. In particular, they MUST NOT +be treated as if present with an empty schema, and when +"if" is not present, both "then" and "else" MUST be +entirely ignored. + +##### 10.2.2.1. if + +This keyword's value MUST be a valid JSON Schema. + +This validation outcome of this keyword's subschema +has no direct effect on the overall validation +result. Rather, it controls which of the "then" +or "else" keywords are evaluated. + +Instances that successfully validate against this +keyword's subschema MUST also be valid against +the subschema value of the "then" keyword, if +present. + +Instances that fail to validate against this +keyword's subschema MUST also be valid against +the subschema value of the "else" keyword, if +present. + +If [annotations](#77-annotations) +are being collected, they are collected from this +keyword's subschema in the usual way, including when +the keyword is present without either "then" or "else". + +##### 10.2.2.2. then + +This keyword's value MUST be a valid JSON Schema. + +When "if" is present, and the instance successfully +validates against its subschema, then validation +succeeds against this keyword if the instance also +successfully validates against this keyword's subschema. + +This keyword has no effect when "if" is absent, or +when the instance fails to validate against its +subschema. Implementations MUST NOT evaluate +the instance against this keyword, for either validation +or annotation collection purposes, in such cases. + +##### 10.2.2.3. else + +This keyword's value MUST be a valid JSON Schema. + +When "if" is present, and the instance fails to +validate against its subschema, then validation +succeeds against this keyword if the instance +successfully validates against this keyword's subschema. + +This keyword has no effect when "if" is absent, or +when the instance successfully validates against its +subschema. Implementations MUST NOT evaluate +the instance against this keyword, for either validation +or annotation collection purposes, in such cases. + +##### 10.2.2.4. dependentSchemas + +This keyword specifies subschemas that are evaluated if the instance +is an object and contains a certain property. + +This keyword's value MUST be an object. +Each value in the object MUST be a valid JSON Schema. + +If the object key is a property in the instance, the entire +instance must validate against the subschema. Its use is +dependent on the presence of the property. + +Omitting this keyword has the same behavior as an empty object. + +##### 10.2.2.5. propertyDependencies + +This keyword specifies subschemas that are evaluated if the instance is +an object and contains a certain property with a certain string value. + +This keyword's value MUST be an object. Each value in the object MUST be +an object whose values MUST be valid JSON Schemas. + +If the outer object key is a property in the instance and the inner +object key is equal to the value of that property, the entire instance +must validate against the schema. Its use is dependent on the presence +and value of the property. + +Omitting this keyword has the same behavior as an empty object. + +### 10.3. Keywords for Applying Subschemas to Child Instances + +Each of these keywords defines a rule for applying its +subschema(s) to child instances, specifically object +properties and array items, and combining their results. + +#### 10.3.1. Keywords for Applying Subschemas to Arrays + +##### 10.3.1.1. prefixItems + +The value of "prefixItems" MUST be a non-empty array of valid JSON Schemas. + +Validation succeeds if each element of the instance validates +against the subschema at the same position, if any. This keyword +does not constrain the length of the array. Only array positions +present in both the keyword's value and the instance value are +affected by this keyword. + +This keyword produces an annotation value which is the largest +index to which this keyword applied a subschema. The value +MAY be a boolean true if a subschema was applied to every +index of the instance, such as is produced by the "items" keyword. +This annotation affects the behavior of "items" and "unevaluatedItems". + +Omitting this keyword has the same assertion behavior as +an empty array. + +##### 10.3.1.2. items + +The value of "items" MUST be a valid JSON Schema. + +This keyword applies its subschema to all instance elements +at indexes greater than the length of the "prefixItems" array +in the same schema object, as reported by the annotation result +of that "prefixItems" keyword. If no such annotation +result exists, "items" applies its subschema to all instance +array elements.[^11] +[^11]: Note that the behavior of "items" without "prefixItems" is +identical to that of the schema form of "items" in prior drafts. +When "prefixItems" is present, the behavior of "items" is +identical to the former "additionalItems" keyword. + +If the "items" subschema is applied to any +positions within the instance array, it produces an +annotation result of boolean true, indicating that all remaining array +elements have been evaluated against this keyword's subschema. +This annotation affects the behavior of "unevaluatedItems" in the +Unevaluated vocabulary. + +Omitting this keyword has the same assertion behavior as +an empty schema. + +Implementations MAY choose to implement or optimize this keyword +in another way that produces the same effect, such as by directly +checking for the presence and size of a "prefixItems" array. +Implementations that do not support annotation collection MUST do so. + +#### 10.3.2. Keywords for Applying Subschemas to Objects + +##### 10.3.2.1. properties + +The value of "properties" MUST be an object. +Each value of this object MUST be a valid JSON Schema. + +Validation succeeds if, for each name that appears in both +the instance and as a name within this keyword's value, the child +instance for that name successfully validates against the +corresponding schema. + +The annotation result of this keyword is the set of instance +property names which are also present under this keyword. +This annotation affects the behavior of "additionalProperties" (in +this vocabulary) and "unevaluatedProperties" in the Unevaluated vocabulary. + +Omitting this keyword has the same assertion behavior as +an empty object. + +##### 10.3.2.2. patternProperties + +The value of "patternProperties" MUST be an object. Each property name +of this object SHOULD be a valid regular expression, according to the +ECMA-262 regular expression dialect. Each property value of this object +MUST be a valid JSON Schema. + +Validation succeeds if, for each instance name that matches any +regular expressions that appear as a property name in this keyword's value, +the child instance for that name successfully validates against each +schema that corresponds to a matching regular expression. Recall: regular +expressions are not implicitly anchored. + +The annotation result of this keyword is the set of instance +property names matched by at least one property under this keyword. +This annotation affects the behavior of "additionalProperties" (in this +vocabulary) and "unevaluatedProperties" (in the Unevaluated vocabulary). + +Omitting this keyword has the same assertion behavior as +an empty object. + +##### 10.3.2.3. additionalProperties + +The value of "additionalProperties" MUST be a valid JSON Schema. + +The behavior of this keyword depends on the presence and +annotation results of "properties" and "patternProperties" +within the same schema object. +Validation with "additionalProperties" applies only to the child +values of instance names that do not appear in the annotation +results of either "properties" or "patternProperties". + +For all such properties, validation succeeds if the child instance +validates against the "additionalProperties" schema. + +The annotation result of this keyword is the set of instance +property names validated by this keyword's subschema. +This annotation affects the behavior of "unevaluatedProperties" +in the Unevaluated vocabulary. + +Omitting this keyword has the same assertion behavior as +an empty schema. + +Implementations MAY choose to implement or optimize this keyword +in another way that produces the same effect, such as by directly +checking the names in "properties" and the patterns in +"patternProperties" against the instance property set. +Implementations that do not support annotation collection MUST do so.[^12] +[^12]: In defining this option, it seems there is the potential for +ambiguity in the output format. The ambiguity does not affect validation results, +but it does affect the resulting output format. +The ambiguity allows for multiple valid output results depending on whether annotations +are used or a solution that "produces the same effect" as draft-07. It is understood +that annotations from failing schemas are dropped. +See our +[Decision Record](https://github.com/json-schema-org/json-schema-spec/tree/HEAD/adr/2022-04-08-cref-for-ambiguity-and-fix-later-gh-spec-issue-1172.md) +for further details. + +##### 10.3.2.4. propertyNames + +The value of "propertyNames" MUST be a valid JSON Schema. + +If the instance is an object, this keyword validates if every property name in +the instance validates against the provided schema. +Note the property name that the schema is testing will always be a string. + +Omitting this keyword has the same behavior as an empty schema. + +#### 10.3.3. Other Keywords for Applying Subschemas + +##### 10.3.3.1. maxContains + +The value of this keyword MUST be a non-negative integer. + +This keyword modifies the behavior of "contains" within the same schema object, +as described below in the section for that keyword. + +Validation MUST always succeed against this keyword. +The value of this keyword is used as its annotation result. + +##### 10.3.3.2. minContains + +The value of this keyword MUST be a non-negative integer. + +This keyword modifies the behavior of "contains" within the same schema object, +as described below in the section for that keyword. + +Validation MUST always succeed against this keyword. +The value of this keyword is used as its annotation result. + +Per [Section 7.3](#73-default-behaviors), +omitted keywords MUST NOT produce annotation results. However, as described +in the section for "contains", the absence of this keyword's annotation +causes "contains" to assume a minimum value of 1. + +##### 10.3.3.3. contains + +The value of this keyword MUST be a valid JSON Schema. + +This keyword applies its subschema to array elements or object property values. + +An instance is valid against "contains" if the number of elements or property +values that are valid against its subschema is with the inclusive range of +the minimum and (if any) maximum number of occurrences. + +The maximum number of occurrences is provided by the "maxContains" keyword +within the same schema object as "contains". If "maxContains" is absent, +the maximum number of occurrences MUST be unbounded. + +The minimum number of occurrences is provided by the "minContains" keyword +within the same schema object as "contains". If "minContains" is absent, +the minimum number of occurrences MUST be 1. + +Implementations MAY implement the dependency on "minContians" and +"maxContains" by inspecting their values rather than reading annotations +produced by those keywords. + +This keyword produces an annotation value which is an array of the +indexes or property names to which this keyword validates successfully +when applying its subschema, in ascending order. The value MAY be a +boolean "true" if the subschema validates successfully when applied to +every index or property value of the instance. The annotation MUST be +present if the instance array or object to which this keyword's schema +applies is empty. + +This annotation affects the behavior of "unevaluatedItems" in the +Unevaluated vocabulary. + +The subschema MUST be applied to every array element or object property +value even after the first match has been found, in order to collect +annotations for use by other keywords. This is to ensure that all possible +annotations are collected. + +## 11. A Vocabulary for Unevaluated Locations + +The purpose of these keywords is to enable schema authors to apply +subschemas to array items or object properties that have not been +successfully evaluated against any dynamic-scope subschema of any +adjacent keywords. + +These instance items or properties may have been unsuccessfully evaluated +against one or more adjacent keyword subschemas, such as when an assertion +in a branch of an "anyOf" fails. Such failed evaluations are not considered +to contribute to whether or not the item or property has been evaluated. +Only successful evaluations are considered. + +If an item in an array or an object property is "successfully evaluated", it +is logically considered to be valid in terms of the representation of the +object or array that's expected. For example if a subschema represents a car, +which requires between 2-4 wheels, and the value of "wheels" is 6, the instance +object is not "evaluated" to be a car, and the "wheels" property is considered +"unevaluated (successfully as a known thing)", and does not retain any annotations. + +Recall that adjacent keywords are keywords within the same schema object, +and that the dynamic-scope subschemas include reference targets as well as +lexical subschemas. + +The behavior of these keywords depend on the annotation results of +adjacent keywords that apply to the instance location being validated. + +Meta-schemas that do not use "$vocabulary" SHOULD be considered to +require this vocabulary as if its IRI were present with a value of true. + +The current IRI for this vocabulary, known as the Unevaluated Applicator +vocabulary, is: +. + +The current IRI for the corresponding meta-schema is: +https://json-schema.org/draft/next/meta/unevaluated. + +### 11.1. Keyword Independence + +Schema keywords typically operate independently, without +affecting each other's outcomes. However, the keywords in this +vocabulary are notable exceptions: + +- "unevaluatedItems", whose behavior is defined in terms of annotations + from "prefixItems", "items", "contains", and itself +- "unevaluatedProperties", whose behavior is defined in terms of + annotations from "properties", "patternProperties", + "additionalProperties", "contains", and itself + +### 11.2. unevaluatedItems + +The value of "unevaluatedItems" MUST be a valid JSON Schema. + +The behavior of this keyword depends on the annotation results of +adjacent keywords that apply to the instance location being validated. +Specifically, the annotations from "prefixItems", "items", and "contains", +which can come from those keywords when they are adjacent to the +"unevaluatedItems" keyword. Those three annotations, as well as +"unevaluatedItems", can also result from any and all adjacent +[in-place applicator](#102-keywords-for-applying-subschemas-in-place) keywords. +This includes but is not limited to the in-place applicators +defined in this document. + +If no relevant annotations are present, the "unevaluatedItems" +subschema MUST be applied to all locations in the array. +If a boolean true value is present from any of the relevant annotations, +"unevaluatedItems" MUST be ignored. Otherwise, the subschema +MUST be applied to any index greater than the largest annotation +value for "prefixItems", which does not appear in any annotation +value for "contains". + +This means that "prefixItems", "items", "contains", and all in-place +applicators MUST be evaluated before this keyword can be evaluated. +Authors of extension keywords MUST NOT define an in-place applicator +that would need to be evaluated after this keyword. + +If the "unevaluatedItems" subschema is applied to any +positions within the instance array, it produces an +annotation result of boolean true, analogous to the +behavior of "items". +This annotation affects the behavior of "unevaluatedItems" in parent schemas. + +Omitting this keyword has the same assertion behavior as +an empty schema. + +### 11.3. unevaluatedProperties + +The value of "unevaluatedProperties" MUST be a valid JSON Schema. + +The behavior of this keyword depends on the annotation results of +adjacent keywords that apply to the instance location being validated. +Specifically, the annotations from "properties", "patternProperties", +"contains", and "additionalProperties", which can come from those keywords when +they are adjacent to the "unevaluatedProperties" keyword. Those +four annotations, as well as "unevaluatedProperties", can also +result from any and all adjacent +[in-place applicator](#102-keywords-for-applying-subschemas-in-place) keywords. +This includes but is not limited to the in-place applicators +defined in this document. + +Validation with "unevaluatedProperties" applies only to the child +values of instance names that do not appear in the "properties", +"patternProperties", "additionalProperties", "contains", or +"unevaluatedProperties" annotation results that apply to the +instance location being validated. + +For all such properties, validation succeeds if the child instance +validates against the "unevaluatedProperties" schema. + +This means that "properties", "patternProperties", "additionalProperties", +"contains" and all in-place applicators MUST be evaluated before this keyword can +be evaluated. Authors of extension keywords MUST NOT define an in-place +applicator that would need to be evaluated after this keyword. + +The annotation result of this keyword is the set of instance +property names validated by this keyword's subschema. +This annotation affects the behavior of "unevaluatedProperties" in parent schemas. + +Omitting this keyword has the same assertion behavior as +an empty schema. + +## 12. Output Formatting + +JSON Schema is defined to be platform-independent. As such, to increase compatibility +across platforms, implementations SHOULD conform to a standard validation output +format. This section describes the minimum requirements that consumers will need to +properly interpret validation results. + +### 12.1. Format + +JSON Schema output is defined using the JSON Schema data instance model as described +in section 4.2.1. Implementations MAY deviate from this as supported by their +specific languages and platforms, however it is RECOMMENDED that the output be +convertible to the JSON format defined herein via serialization or other means. + +### 12.2. Output Formats + +This specification defines three output formats. See the "Output Structure" +section for the requirements of each format. + +- Flag - A boolean which simply indicates the overall validation result + with no further details. +- List - Provides validation information in a flat list structure. +- Hierarchical - Provides validation information in a hierarchical + structure that follows the evaluation paths generated while processing + the schema. + An implementation MUST provide the "flag" format and SHOULD provide at least one + of the "list" or "hierarchical" formats. Implementations SHOULD specify in + their documentation which formats they support. + +### 12.3. Minimum Information + +Beyond the simplistic "flag" output, additional information is useful to aid in +debugging a schema or instance. Each sub-result SHOULD contain the information +contained within this section at a minimum. + +A single object that contains all of these components is considered an +output unit. + +Implementations MAY elect to provide additional information. + +#### 12.3.1. Evaluation path + +The evalutaion path to the schema object that produced the output unit. +The value MUST be expressed as a JSON Pointer, and it MUST include any +by-reference applicators such as "$ref" or "$dynamicRef".[^13] +[^13]: The schema may not actually have a value at the location indicated +by this pointer. It is provided as an indication of the traversal +path only. + +``` +/properties/width/$ref/allOf/1 +``` + +Note that this pointer may not be resolvable by the normal JSON Pointer process +due to the inclusion of these by-reference applicator keywords. + +The JSON key for this information is "evaluationPath". + +#### 12.3.2. Schema Location + +The absolute, dereferenced location of the schema object that produced +the output unit. The value MUST be expressed using the canonical IRI of the +relevant schema resource plus a JSON Pointer fragment that indicates the schema +object that produced the output. It MUST NOT include by-reference applicators +such as "$ref" or "$dynamicRef".[^14] +[^14]: Note that "absolute" here is in the sense of "absolute filesystem path" +(meaning the complete location) rather than the "absolute-IRI" +terminology from RFC 3987 (meaning with scheme and without fragment). +Schema locations will have a fragment in order to identify the specific +schema object. + +``` +https://example.com/schemas/common#/$defs/allOf/1 +``` + +The JSON key for this information is "schemaLocation". + +#### 12.3.3. Instance Location + +The location of the JSON value within the instance being validated. The +value MUST be expressed as a JSON Pointer. + +The JSON key for this information is "instanceLocation". + +#### 12.3.4. Errors + +Any errors produced by the validation. This property MUST NOT +be included if the validation was successful. The value +for this property MUST be an object where the keys are the names of +keywords and the values are the error message produced by the +associated keyword. + +If the subschema itself is producing the error, that error MUST be +listed with an empty string key.[^15] +[^15]: Although there may be other cases where a subschema can produce +an error, the most common case is the "false" schema. In +cases like these, there is no keyword that produces the error, +so there is nothing to use as a key. Thus the empty string +is used instead. + +The specific wording for the message is not defined by this +specification. Implementations will need to provide this. + +The JSON key for this information is "errors". + +#### 12.3.5. Annotations + +Any annotations produced by the evaluation. This property MUST NOT +be included if the validation result of the containing subschema was +unsuccessful. + +The value for this property MUST be an object where the +keys are the names of keywords and the values are the annotations +produced by the associated keyword. + +Each keyword defines its own annotation data type (e.g. "properties" +produces a list of keywords, whereas "title" produces a string). + +The JSON key for this information is "annotations". + +#### 12.3.6. Dropped Annotations + +Any annotations produced and subsequently dropped by the evaluation +due to an unsuccessful validation result of the containing subschema. +This property MAY be included if the validation result of the containing +subschema was unsuccessful. It MUST NOT be included if the local +validation result of the containing subschema was successful. + +Implementations that wish to provide these annotations MUST NOT provide +them as their default behavior. These annotations MUST only be included +by explicitly configuring the implementation to do so. + +The value for this property MUST be an object where the +keys are the names of keywords and the values are the annotations +produced by the associated keyword. + +Each keyword defines its own annotation data type (e.g. "properties" +produces a list of keywords, whereas "title" produces a string). + +The JSON key for this information is "droppedAnnotations". + +#### 12.3.7. Results from Subschemas + +Evaluation results generated by applying a subschema to the instance +or a child of the instance. +Keywords which have multiple subschemas (e.g. "anyOf") will generally +generate an output unit for each subschema. In order to accommodate +potentially multiple results, the value of this property MUST be an +array of output units, even if only a single output unit is produced. + +For "list", this property will appear only at the root output unit +and will hold all output units in a flat list. + +For "hierarchical", this property will contain results in a tree +structure where each output unit may itself have further nested results. + +The sequence of output units within this list is not specified and +MAY be determined by the implementation. Sets of output units are +considered equivalent if they contain the same units, in any order. + +The JSON key for these additional results is "details". + +### 12.4. Output Structure + +The output MUST be an object containing a boolean property named "valid". When +additional information about the result is required, the output MUST also contain +"details" as described below. + +- "valid" - a boolean value indicating the overall validation success or failure +- "details" - the collection of results produced by subschemas + For these examples, the following schema and instances will be used. + +Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://json-schema.org/schemas/example", + "type": "object", + "title": "root", + "properties": { + "foo": { + "allOf": [ + { + "required": [ + "unspecified-prop" + ] + }, + { + "type": "object", + "title": "foo-title", + "properties": { + "foo-prop": { + "const": 1, + "title": "foo-prop-title" + } + }, + "additionalProperties": { + "type": "boolean" + } + } + ] + }, + "bar": { + "$ref": "#/$defs/bar" + } + }, + "$defs": { + "bar": { + "type": "object", + "title": "bar-title", + "properties": { + "bar-prop": { + "type": "integer", + "minimum": 10, + "title": "bar-prop-title" + } + } + } + } +} +``` + +Failing instance: + +```json +{ + "foo": { + "foo-prop": "not 1", + "other-prop": false + }, + "bar": { + "bar-prop": 2 + } +} +``` + +Passing instance: + +```json +{ + "foo": { + "foo-prop": 1, + "unspecified-prop": true + }, + "bar": { + "bar-prop": 20 + } +} +``` + +The failing instance will produce the following errors: + +- The value at "/foo" + evaluated at "/properties/foo/allOf/0" + by following the path "/properties/foo/allOf/0" + by the "required" keyword + is missing the property "unspecified-prop". +- The value at "/foo/foo-prop" + evaluated at "/properties/foo/allOf/1/properties/foo-prop" + by following the path "/properties/foo/allOf/1/properties/foo-prop" + by the "const" keyword + is not the constant value 1. +- The value at "/bar/bar-prop" + evaluated at "/$defs/bar/properties/bar-prop" + by following the path "/properties/bar/$ref/properties/bar-prop" + by the "type" keyword + is not a number.[^16][^17] + [^16]: "minimum" doesn't produce an error because it only operates on + instances that are numbers. + [^17]: Note that the error message wording as depicted in the examples below is not a + requirement of this specification. Implementations SHOULD craft error messages + tailored for their audience or provide a templating mechanism that allows their + users to craft their own messages. + +The passing instance will produce the following annotations: + +- The keyword "title" + evaluated at "" + by following the path "" + will produce `"root"`. +- The keyword "properties" + evaluated at "" + by following the path "" + will produce `["foo", "bar"]`. +- The keyword "title" + evaluated at "/properties/foo" + by following the path "/properties/foo" + will produce `"foo-title"`. +- The keyword "properties" + evaluated at "/properties/foo/allOf/1" + by following the path "/properties/foo/allOf/1" + will produce `["foo-prop"]`. +- The keyword "additionalProperties" + evaluated at "/properties/foo/allOf/1" + by following the path "/properties/foo/allOf/1" + will produce `["unspecified-prop"]`. +- The keyword "title" + evaluated at "/properties/foo/allOf/1/properties/foo-prop" + by following the path "/properties/foo/allOf/1/properties/foo-prop" + will produce `"foo-prop-title"`. +- The keyword "title" + evaluated at "/$defs/bar" + by following the path "/properties/bar/$ref" + will produce `"bar-title"`. +- The keyword "properties" + evaluated at "/$defs/bar" + by following the path "/properties/var/$ref" + will produce `["bar-prop"]`. +- The keyword "title" + evaluated at "/$defs/bar/properties/bar-prop" + by following the path "/properties/bar/$ref/properties/bar-prop" + will produce `"bar-prop-title"`. + +#### 12.4.1. Flag + +In the simplest case, merely the boolean result for the "valid" valid property +needs to be fulfilled. For this format, all other information is explicitly +omitted. + +```json +{ + "valid": false +} +``` + +Because no errors or annotations are returned with this format, it is +RECOMMENDED that implementations use short-circuiting logic to return +failure or success as soon as the outcome can be determined. For example, +if an "anyOf" keyword contains five subschemas, and the second one +passes, there is no need to check the other three. The logic can simply +return with success. + +#### 12.4.2. List + +The "List" structure is a flat list of output units contained within a +root output unit. + +The root output unit contains "valid" for the overall result and "details" +for the list of specific results. All other information is explicitly +omitted from the root output unit. If the root schema produces errors or +annotations, then the output node for the root MUST be present within the +root output unit's "details" list with those errors or annotations. + +Output units which do not contain errors or annotations SHOULD be excluded +from this format, however implementations MAY choose to include them for +completeness. + +Failing results: + +```json +{ + "valid": false, + "details": [ + { + "valid": false, + "evaluationPath": "/properties/foo/allOf/0", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/0", + "instanceLocation": "/foo", + "errors": { + "required": "Required properties [\"unspecified-prop\"] were not present" + } + }, + { + "valid": false, + "evaluationPath": "/properties/foo/allOf/1/properties/foo-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1/properties/foo-prop", + "instanceLocation": "/foo/foo-prop", + "errors": { + "const": "Expected \"1\"" + } + }, + { + "valid": false, + "evaluationPath": "/properties/bar/$ref/properties/bar-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar/properties/bar-prop", + "instanceLocation": "/bar/bar-prop", + "errors": { + "minimum": "2 is less than or equal to 10" + } + } + ] +} +``` + +Passing results: + +```json +{ + "valid": true, + "details": [ + { + "valid": true, + "evaluationPath": "", + "schemaLocation": "https://json-schema.org/schemas/example#", + "instanceLocation": "", + "annotations": { + "title": "root", + "properties": [ + "foo", + "bar" + ] + } + }, + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/1", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1", + "instanceLocation": "/foo", + "annotations": { + "title": "foo-title", + "properties": [ + "foo-prop" + ], + "additionalProperties": [ + "unspecified-prop" + ] + } + }, + { + "valid": true, + "evaluationPath": "/properties/bar/$ref", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar", + "instanceLocation": "/bar", + "annotations": { + "title": "bar-title", + "properties": [ + "bar-prop" + ] + } + }, + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/1/properties/foo-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1/properties/foo-prop", + "instanceLocation": "/foo/foo-prop", + "annotations": { + "title": "foo-prop-title" + } + }, + { + "valid": true, + "evaluationPath": "/properties/bar/$ref/properties/bar-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar/properties/bar-prop", + "instanceLocation": "/bar/bar-prop", + "annotations": { + "title": "bar-prop-title" + } + } + ] +} +``` + +#### 12.4.3. Hierarchical + +The "Hierarchical" structure is a tree structure that follows the +evaluation path during the validation process. Typically, it will +resemble the schema as if all referenced schemas were inlined in place +of their associated by-reference keywords. + +All output units are included in this format. + +The location properties of the root output unit MAY be omitted. + +Failing results (errors): + +```json +{ + "valid": false, + "evaluationPath": "", + "schemaLocation": "https://json-schema.org/schemas/example#", + "instanceLocation": "", + "details": [ + { + "valid": false, + "evaluationPath": "/properties/foo", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo", + "instanceLocation": "/foo", + "details": [ + { + "valid": false, + "evaluationPath": "/properties/foo/allOf/0", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/0", + "instanceLocation": "/foo", + "errors": { + "required": "Required properties [\"unspecified-prop\"] were not present" + } + }, + { + "valid": false, + "evaluationPath": "/properties/foo/allOf/1", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1", + "instanceLocation": "/foo", + "droppedAnnotations": { + "properties": [ + "foo-prop" + ], + "title": "foo-title" + }, + "details": [ + { + "valid": false, + "evaluationPath": "/properties/foo/allOf/1/properties/foo-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1/properties/foo-prop", + "instanceLocation": "/foo/foo-prop", + "errors": { + "const": "Expected \"1\"" + }, + "droppedAnnotations": { + "title": "foo-prop-title" + } + }, + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/1/additionalProperties", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1/additionalProperties", + "instanceLocation": "/foo/other-prop" + } + ] + } + ] + }, + { + "valid": false, + "evaluationPath": "/properties/bar", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/bar", + "instanceLocation": "/bar", + "details": [ + { + "valid": false, + "evaluationPath": "/properties/bar/$ref", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar", + "instanceLocation": "/bar", + "droppedAnnotations": { + "properties": [ + "bar-prop" + ], + "title": "bar-title" + }, + "details": [ + { + "valid": false, + "evaluationPath": "/properties/bar/$ref/properties/bar-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar/properties/bar-prop", + "instanceLocation": "/bar/bar-prop", + "errors": { + "minimum": "2 is less than or equal to 10" + }, + "droppedAnnotations": { + "title": "bar-prop-title" + } + } + ] + } + ] + } + ] +} +``` + +Passing results (annotations): + +```json +{ + "valid": true, + "evaluationPath": "", + "schemaLocation": "https://json-schema.org/schemas/example#", + "instanceLocation": "", + "annotations": { + "title": "root", + "properties": [ + "foo", + "bar" + ] + }, + "details": [ + { + "valid": true, + "evaluationPath": "/properties/foo", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo", + "instanceLocation": "/foo", + "details": [ + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/0", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/0", + "instanceLocation": "/foo" + }, + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/1", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1", + "instanceLocation": "/foo", + "annotations": { + "title": "foo-title", + "properties": [ + "foo-prop" + ], + "additionalProperties": [ + "unspecified-prop" + ] + }, + "details": [ + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/1/properties/foo-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1/properties/foo-prop", + "instanceLocation": "/foo/foo-prop", + "annotations": { + "title": "foo-prop-title" + } + }, + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/1/additionalProperties", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1/additionalProperties", + "instanceLocation": "/foo/unspecified-prop" + } + ] + } + ] + }, + { + "valid": true, + "evaluationPath": "/properties/bar", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/bar", + "instanceLocation": "/bar", + "details": [ + { + "valid": true, + "evaluationPath": "/properties/bar/$ref", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar", + "instanceLocation": "/bar", + "annotations": { + "title": "bar-title", + "properties": [ + "bar-prop" + ] + }, + "details": [ + { + "valid": true, + "evaluationPath": "/properties/bar/$ref/properties/bar-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar/properties/bar-prop", + "instanceLocation": "/bar/bar-prop", + "annotations": { + "title": "bar-prop-title" + } + } + ] + } + ] + } + ] +} +``` + +#### 12.4.4. Output validation schemas + +For convenience, JSON Schema has been provided to validate output generated +by implementations. Its IRI is: +https://json-schema.org/draft/next/output/schema. + +## 13. Security Considerations + +Both schemas and instances are JSON values. As such, all security considerations +defined in [RFC 8259](#rfc8259) apply. + +Instances and schemas are both frequently written by untrusted third parties, to be +deployed on public Internet servers. +Implementations should take care that the parsing and evaluating against schemas +does not consume excessive system resources. +Implementations MUST NOT fall into an infinite loop. + +A malicious party could cause an implementation to repeatedly collect a copy +of a very large value as an annotation. Implementations SHOULD guard against +excessive consumption of system resources in such a scenario. + +Servers MUST ensure that malicious parties cannot change the functionality of +existing schemas by uploading a schema with a pre-existing or very similar "$id". + +Individual JSON Schema vocabularies are liable to also have their own security +considerations. Consult the respective specifications for more information. + +Schema authors should take care with "$comment" contents, as a malicious +implementation can display them to end-users in violation of a spec, or +fail to strip them if such behavior is expected. + +A malicious schema author could place executable code or other dangerous +material within a "$comment". Implementations MUST NOT parse or otherwise +take action based on "$comment" contents. + +## 14. IANA Considerations + +### 14.1. application/schema+json + +The proposed MIME media type for JSON Schema is defined as follows: + +- Type name: application +- Subtype name: schema+json +- Required parameters: N/A +- Encoding considerations: Encoding considerations are + identical to those specified for the "application/json" + media type. See [JSON](#rfc8259). +- Security considerations: See [Section 13](#13-security-considerations) above. +- Interoperability considerations: See Sections + [6.2](#62-programming-language-independence), + [6.3](#63-mathematical-integers), and + [6.4](#64-regular-expressions) above. +- Fragment identifier considerations: See + [Section 5](#5-fragment-identifiers) + +### 14.2. application/schema-instance+json + +The proposed MIME media type for JSON Schema Instances that require +a JSON Schema-specific media type is defined as follows: + +- Type name: application +- Subtype name: schema-instance+json +- Required parameters: N/A +- Encoding considerations: Encoding considerations are + identical to those specified for the "application/json" + media type. See [JSON](#rfc8259). +- Security considerations: See [Section 13](#13-security-considerations) above. +- Interoperability considerations: See Sections + [6.2](#62-programming-language-independence), + [6.3](#63-mathematical-integers), and + [6.4](#64-regular-expressions) above. +- Fragment identifier considerations: See [Section 5](#5-fragment-identifiers) + +## 15. References + +### 15.1. Normative References + +#### [RFC2119] + +Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March +1997, <>. + +#### [RFC3986] + +Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, +DOI 10.17487/RFC3986, January 2005, <>. + +#### [RFC3987] + +Duerst, M. and M. Suignard, "Internationalized Resource Identifiers (IRIs)", RFC 3987, DOI 10.17487/RFC3987, January +2005, <>. + +#### [RFC6839] + +Hansen, T. and A. Melnikov, "Additional Media Type Structured Syntax Suffixes", RFC 6839, DOI 10.17487/RFC6839, January +2013, <>. + +#### [RFC6901] + +Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed., "JavaScript Object Notation (JSON) Pointer", RFC 6901, DOI +10.17487/RFC6901, April 2013, <>. + +#### [RFC8259] + +Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, +December 2017, <>. + +#### [W3C.REC-ldp-20150226] + +Malhotra, A., Ed., Arwe, J., Ed., and S. Speicher, Ed., "Linked Data Platform 1.0", W3C REC REC-ldp-20150226, W3C +REC-ldp-20150226, 26 February 2015, <>. + +#### [ecma262] + +"ECMA-262, 11th edition specification", June 2020, <>. + +### 15.2. Informative References + +#### [RFC6596] + +Ohye, M. and J. Kupke, "The Canonical Link Relation", RFC 6596, DOI 10.17487/RFC6596, April +2012, <>. + +#### [RFC7049] + +Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", RFC 7049, DOI 10.17487/RFC7049, October +2013, <>. + +#### [RFC7231] + +Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content", RFC 7231, DOI +10.17487/RFC7231, June 2014, <>. + +#### [RFC8288] + +Nottingham, M., "Web Linking", RFC 8288, DOI 10.17487/RFC8288, October +2017, <>. + +#### [W3C.WD-fragid-best-practices-20121025] + +Tennison, J., Ed., "Best Practices for Fragment Identifiers and Media Type Definitions", W3C WD +WD-fragid-best-practices-20121025, W3C WD-fragid-best-practices-20121025, 25 October +2012, <>. + +#### [W3C.REC-xptr-framework-20030325] + +Maler, E., Ed., Marsh, J., Ed., Walsh, N., Ed., and P. Grosso, Ed., "XPointer Framework", W3C REC +REC-xptr-framework-20030325, W3C REC-xptr-framework-20030325, 25 March +2003, <>. + +#### [json-schema-validation] + +Wright, A., Andrews, H., and B. Hutton, "JSON Schema Validation: A Vocabulary for Structural Validation of JSON", Work +in Progress, Internet-Draft, draft-bhutton-json-schema-validation-01, June +2022, <>. + +#### [json-hyper-schema] + +Andrews, H. and A. Wright, "JSON Hyper-Schema: A Vocabulary for Hypermedia Annotation of JSON", Work in Progress, +Internet-Draft, draft-handrews-json-schema-hyperschema-02, November +2017, <>. + +#### [xml-names] + +Bray, T., Ed., Hollander, D., Ed., Layman, A., Ed., and R. Tobin, Ed., "Namespaces in XML 1.1 (Second Edition)", August +2006, <>. + +## Appendix A. Schema identification examples + +Consider the following schema, which shows "$id" being used to identify +both the root schema and various subschemas, and "$anchor" being used +to define plain name fragment identifiers. + +```json +{ + "$id": "https://example.com/root.json", + "$defs": { + "A": { + "$anchor": "foo" + }, + "B": { + "$id": "other.json", + "$defs": { + "X": { + "$anchor": "bar" + }, + "Y": { + "$id": "t/inner.json", + "$anchor": "bar" + } + } + }, + "C": { + "$id": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f" + } + } +} +``` + +The schemas at the following IRI-encoded [JSON +Pointers](#rfc6901) (relative to the root schema) have the following +base IRIs, and are identifiable by any listed IRI in accordance with +[Section 5](#5-fragment-identifiers) and [Section 9.2.1](#921-json-pointer-fragments-and-embedded-schema-resources) +above. + +- *# (document root)* + - *canonical (and base) IRI* https://example.com/root.json + - *canonical resource IRI plus pointer fragment* https://example.com/root.json# +- *#/$defs/A* + - *base IRI* https://example.com/root.json + - *canonical resource IRI plus plain fragment* https://example.com/root.json#foo + - *canonical resource IRI plus pointer fragment* https://example.com/root.json#/$defs/A +- *#/$defs/B* + - *canonical (and base) IRI* https://example.com/other.json + - *canonical resource IRI plus pointer fragment* https://example.com/other.json# + - *base IRI of enclosing (root.json) resource plus fragment* https://example.com/root.json#/$defs/B +- *#/$defs/B/$defs/X* + - *base IRI* https://example.com/other.json + - *canonical resource IRI plus plain fragment* https://example.com/other.json#bar + - *canonical resource IRI plus pointer fragment* https://example.com/other.json#/$defs/X + - *base IRI of enclosing (root.json) resource plus fragment* https://example.com/root.json#/$defs/B/$defs/X +- *#/$defs/B/$defs/Y* + - *canonical (and base) IRI* https://example.com/t/inner.json + - *canonical IRI plus plain fragment* https://example.com/t/inner.json#bar + - *canonical IRI plus pointer fragment* https://example.com/t/inner.json# + - *base IRI of enclosing (other.json) resource plus fragment* https://example.com/other.json#/$defs/Y + - *base IRI of enclosing (root.json) resource plus fragment* https://example.com/root.json#/$defs/B/$defs/Y +- *#/$defs/C* + - *canonical (and base) IRI* urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f + - *canonical IRI plus pointer fragment* urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f# + - *base IRI of enclosing (root.json) resource plus fragment* https://example.com/root.json#/$defs/C + +Note: The fragment part of the IRI does not make it canonical or non-canonical, +rather, the base IRI used (as part of the full IRI with any fragment) is what +determines the canonical nature of the resulting full IRI.[^18] +[^18]: Multiple "canonical" IRIs? We Acknowledge this is potentially confusing, and +direct you to read the CREF located in the +[JSON Pointer fragments and embedded schema resources](#921-json-pointer-fragments-and-embedded-schema-resources) +section for futher comments. + +## Appendix B. Manipulating schema documents and references + +Various tools have been created to rearrange schema documents +based on how and where references ("$ref") appear. This appendix discusses +which use cases and actions are compliant with this specification. + +### B.1. Bundling schema resources into a single document + +A set of schema resources intended for use together can be organized +with each in its own schema document, all in the same schema document, +or any granularity of document grouping in between. + +Numerous tools exist to perform various sorts of reference removal. +A common case of this is producing a single file where all references +can be resolved within that file. This is typically done to simplify +distribution, or to simplify coding so that various invocations +of JSON Schema libraries do not have to keep track of and load +a large number of resources. + +This transformation can be safely and reversibly done as long as +all static references (e.g. "$ref") use IRI-references that resolve +to IRIs using the canonical resource IRI as the base, and all schema +resources have an absolute-IRI as the "$id" in their root schema. + +With these conditions met, each external resource can be copied +under "$defs", without breaking any references among the resources' +schema objects, and without changing any aspect of validation or +annotation results. The names of the schemas under "$defs" do +not affect behavior, assuming they are each unique, as they +do not appear in the canonical IRIs for the embedded resources. + +### B.2. Reference removal is not always safe + +Attempting to remove all references and produce a single schema document does not, +in all cases, produce a schema with identical behavior to the original form. + +Since "$ref" is now treated like any other keyword, with other keywords allowed +in the same schema objects, fully supporting non-recursive "$ref" removal in +all cases can require relatively complex schema manipulations. It is beyond +the scope of this specification to determine or provide a set of safe "$ref" +removal transformations, as they depend not only on the schema structure +but also on the intended usage. + +## Appendix C. Example of recursive schema extension + +Consider the following two schemas describing a simple +recursive tree structure, where each node in the tree +can have a "data" field of any type. The first schema +allows and ignores other instance properties. The second is +more strict and only allows the "data" and "children" properties. +An example instance with "data" misspelled as "daat" is also shown. + +Tree schema, extensible: + +```json +{ + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://example.com/tree", + "$dynamicAnchor": "node", + "type": "object", + "properties": { + "data": true, + "children": { + "type": "array", + "items": { + "$dynamicRef": "#node" + } + } + } +} +``` + +Strict-tree schema, guards against misspelled properties: + +```json +{ + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://example.com/strict-tree", + "$dynamicAnchor": "node", + "$ref": "tree", + "unevaluatedProperties": false +} +``` + +Instance with misspelled field: + +```json +{ + "children": [ + { + "daat": 1 + } + ] +} +``` + +When we load these two schemas, we will notice the "$dynamicAnchor" +named "node" (note the lack of "#" as this is just the name) +present in each, resulting in the following full schema IRIs: + +- "https://example.com/tree#node" +- "https://example.com/strict-tree#node" + In addition, JSON Schema implementations keep track of the fact + that these fragments were created with "$dynamicAnchor". + +If we apply the "strict-tree" schema to the instance, we will follow +the "$ref" to the "tree" schema, examine its "children" subschema, +and find the "$dynamicRef": to "#node" (note the "#" for IRI fragment syntax) +in its "items" subschema. That reference resolves to +"https://example.com/tree#node", which is a IRI with a fragment +created by "$dynamicAnchor". Therefore we must examine the dynamic +scope before following the reference. + +At this point, the evaluation path is +"#/$ref/properties/children/items/$dynamicRef", with a dynamic scope +containing (from the outermost scope to the innermost): + +1. "https://example.com/strict-tree#" +2. "https://example.com/tree#" +3. "https://example.com/tree#/properties/children" +4. "https://example.com/tree#/properties/children/items" + +Since we are looking for a plain name fragment, which can be +defined anywhere within a schema resource, the JSON Pointer fragments +are irrelevant to this check. That means that we can remove those +fragments and eliminate consecutive duplicates, producing: + +1. "https://example.com/strict-tree" +2. "https://example.com/tree" + +In this case, the outermost resource also has a "node" fragment +defined by "$dynamicAnchor". Therefore instead of resolving the +"$dynamicRef" to "https://example.com/tree#node", we resolve it to +"https://example.com/strict-tree#node". + +This way, the recursion in the "tree" schema recurses to the root +of "strict-tree", instead of only applying "strict-tree" to the +instance root, but applying "tree" to instance children. + +This example shows both "$dynamicAnchor"s in the same place +in each schema, specifically the resource root schema. +Since plain-name fragments are independent of the JSON structure, +this would work just as well if one or both of the node schema objects +were moved under "$defs". It is the matching "$dynamicAnchor" values +which tell us how to resolve the dynamic reference, not any sort of +correlation in JSON structure. + +## Appendix D. Working with vocabularies + +### D.1. Best practices for vocabulary and meta-schema authors + +Vocabulary authors should +take care to avoid keyword name collisions if the vocabulary is intended +for broad use, and potentially combined with other vocabularies. JSON +Schema does not provide any formal namespacing system, but also does +not constrain keyword names, allowing for any number of namespacing +approaches. + +Vocabularies may build on each other, such as by defining the behavior +of their keywords with respect to the behavior of keywords from another +vocabulary, or by using a keyword from another vocabulary with +a restricted or expanded set of acceptable values. Not all such +vocabulary re-use will result in a new vocabulary that is compatible +with the vocabulary on which it is built. Vocabulary authors should +clearly document what level of compatibility, if any, is expected. + +Meta-schema authors should not use "$vocabulary" to combine multiple +vocabularies that define conflicting syntax or semantics for the same +keyword. As semantic conflicts are not generally detectable through +schema validation, implementations are not expected to detect such +conflicts. If conflicting vocabularies are declared, the resulting +behavior is undefined. + +Vocabulary authors SHOULD provide a meta-schema that validates the +expected usage of the vocabulary's keywords on their own. Such meta-schemas +SHOULD not forbid additional keywords, and MUST not forbid any +keywords from the Core vocabulary. + +It is recommended that meta-schema authors reference each vocabulary's +meta-schema using the ["allOf"](#10211-allof) keyword, +although other mechanisms for constructing the meta-schema may be +appropriate for certain use cases. + +The recursive nature of meta-schemas makes the "$dynamicAnchor" +and "$dynamicRef" keywords particularly useful for extending +existing meta-schemas, as can be seen in the JSON Hyper-Schema meta-schema +which extends the Validation meta-schema. + +Meta-schemas may impose additional constraints, including describing +keywords not present in any vocabulary, beyond what the meta-schemas +associated with the declared vocabularies describe. This allows for +restricting usage to a subset of a vocabulary, and for validating +locally defined keywords not intended for re-use. + +However, meta-schemas should not contradict any vocabularies that +they declare, such as by requiring a different JSON type than +the vocabulary expects. The resulting behavior is undefined. + +Meta-schemas intended for local use, with no need to test for +vocabulary support in arbitrary implementations, can safely omit +"$vocabulary" entirely. + +### D.2. Example meta-schema with vocabulary declarations + +This meta-schema explicitly declares both the Core and Applicator vocabularies, +together with an extension vocabulary, and combines their meta-schemas with +an "allOf". The extension vocabulary's meta-schema, which describes only the +keywords in that vocabulary, is shown after the main example meta-schema. + +The main example meta-schema also restricts the usage of the Unevaluated +vocabulary by forbidding the keywords prefixed with "unevaluated", which +are particularly complex to implement. This does not change the semantics +or set of keywords defined by the other vocabularies. It just ensures +that schemas using this meta-schema that attempt to use the keywords +prefixed with "unevaluated" will fail validation against this meta-schema. + +Finally, this meta-schema describes the syntax of a keyword, "localKeyword", +that is not part of any vocabulary. Presumably, the implementors and users +of this meta-schema will understand the semantics of "localKeyword". +JSON Schema does not define any mechanism for expressing keyword semantics +outside of vocabularies, making them unsuitable for use except in a +specific environment in which they are understood. + +This meta-schema combines several vocabularies for general use. + +```json +{ + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://example.com/meta/general-use-example", + "$dynamicAnchor": "meta", + "$vocabulary": { + "https://json-schema.org/draft/next/vocab/core": true, + "https://json-schema.org/draft/next/vocab/applicator": true, + "https://json-schema.org/draft/next/vocab/validation": true, + "https://example.com/vocab/example-vocab": true + }, + "allOf": [ + { + "$ref": "https://json-schema.org/draft/next/meta/core" + }, + { + "$ref": "https://json-schema.org/draft/next/meta/applicator" + }, + { + "$ref": "https://json-schema.org/draft/next/meta/validation" + }, + { + "$ref": "https://example.com/meta/example-vocab" + } + ], + "patternProperties": { + "^unevaluated": false + }, + "properties": { + "localKeyword": { + "$comment": "Not in vocabulary, but validated if used", + "type": "string" + } + } +} +``` + +This meta-schema describes only a single extension vocabulary. + +```json +{ + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://example.com/meta/example-vocab", + "$dynamicAnchor": "meta", + "$vocabulary": { + "https://example.com/vocab/example-vocab": true + }, + "type": [ + "object", + "boolean" + ], + "properties": { + "minDate": { + "type": "string", + "pattern": "\\d\\d\\d\\d-\\d\\d-\\d\\d", + "format": "date" + } + } +} +``` + +As shown above, even though each of the single-vocabulary meta-schemas +referenced in the general-use meta-schema's "allOf" declares its +corresponding vocabulary, this new meta-schema must re-declare them. + +The standard meta-schemas that combine all vocabularies defined by +the Core and Validation specification, and that combine all vocabularies +defined by those specifications as well as the Hyper-Schema specification, +demonstrate additional complex combinations. These IRIs for these +meta-schemas may be found in the Validation and Hyper-Schema specifications, +respectively. + +While the general-use meta-schema can validate the syntax of "minDate", +it is the vocabulary that defines the logic behind the semantic meaning +of "minDate". Without an understanding of the semantics (in this example, +that the instance value must be a date equal to or after the date +provided as the keyword's value in the schema), an implementation can +only validate the syntactic usage. In this case, that means validating +that it is a date-formatted string (using "pattern" to ensure that it is +validated even when "format" functions purely as an annotation, as explained +in the [Validation specification](#json-schema-validation). + +## Appendix E. References and generative use cases + +While the presence of references is expected to be transparent +to validation results, generative use cases such as code generators +and UI renderers often consider references to be semantically significant. + +To make such use case-specific semantics explicit, the best practice +is to create an annotation keyword for use in the same +schema object alongside of a reference keyword such as "$ref". + +For example, here is a hypothetical keyword for determining +whether a code generator should consider the reference +target to be a distinct class, and how those classes are related. +Note that this example is solely for illustrative purposes, and is +not intended to propose a functional code generation keyword. + +```json +{ + "allOf": [ + { + "classRelation": "is-a", + "$ref": "classes/base.json" + }, + { + "$ref": "fields/common.json" + } + ], + "properties": { + "foo": { + "classRelation": "has-a", + "$ref": "classes/foo.json" + }, + "date": { + "$ref": "types/dateStruct.json" + } + } +} +``` + +Here, this schema represents some sort of object-oriented class. +The first reference in the "allOf" is noted as the base class. +The second is not assigned a class relationship, meaning that the +code generator should combine the target's definition with this +one as if no reference were involved. + +Looking at the properties, "foo" is flagged as object composition, +while the "date" property is not. It is simply a field with +sub-fields, rather than an instance of a distinct class. + +This style of usage requires the annotation to be in the same object +as the reference, which must be recognizable as a reference. + +## Appendix F. Acknowledgments + +Thanks to +Gary Court, +Francis Galiegue, +Kris Zyp, +and Geraint Luff +for their work on the initial drafts of JSON Schema. + +Thanks to +Jason Desrosiers, +Daniel Perrett, +Erik Wilde, +Evgeny Poberezkin, +Brad Bowman, +Gowry Sankar, +Donald Pipowitch, +Dave Finlay, +Denis Laxalde, +Phil Sturgeon, +Shawn Silverman, +and Karen Etheridge +for their submissions and patches to the document. + +## Appendix G. ChangeLog[^19] + +[^19]: This section to be removed before leaving Internet-Draft status. + +- *draft-bhutton-json-schema-next* + - "contains" now applies to objects as well as arrays + - Use IRIs instead of URIs + - Remove bookending requirement for "$dynamicRef" + - Add "propertyDependencies" keyword +- *draft-bhutton-json-schema-01* + - Improve and clarify the "type", "contains", "unevaluatedProperties", and "unevaluatedItems" keyword explanations + - Clarify various aspects of "canonical URIs" + - Comment on ambiguity around annotations and "additionalProperties" + - Clarify Vocabularies need not be formally defined + - Remove references to remaining media-type parameters + - Fix multiple examples +- *draft-bhutton-json-schema-00* + - "$schema" MAY change for embedded resources + - Array-value "items" functionality is now "prefixItems" + - "items" subsumes the old function of "additionalItems" + - "contains" annotation behavior, and "contains" and "unevaluatedItems" interactions now specified + - Rename $recursive* to $dynamic*, with behavior modification + - $dynamicAnchor defines a fragment like $anchor + - $dynamic* (previously $recursive) no longer use runtime base URI determination + - Define Compound Schema Documents (bundle) and processing + - Reference ECMA-262, 11th edition for regular expression support + - Regular expression should support unicode + - Remove media type parameters + - Specify Unknown keywords are collected as annotations + - Moved "unevaluatedItems" and "unevaluatedProperties" from core into their own vocabulary +- *draft-handrews-json-schema-02* + - Update to RFC 8259 for JSON specification + - Moved "definitions" from the Validation specification here as "$defs" + - Moved applicator keywords from the Validation specification as their own vocabulary + - Moved the schema form of "dependencies" from the Validation specification as "dependentSchemas" + - Formalized annotation collection + - Specified recommended output formats + - Defined keyword interactions in terms of annotation and assertion results + - Added "unevaluatedProperties" and "unevaluatedItems" + - Define "$ref" behavior in terms of the assertion, applicator, and annotation model + - Allow keywords adjacent to "$ref" + - Note undefined behavior for "$ref" targets involving unknown keywords + - Add recursive referencing, primarily for meta-schema extension + - Add the concept of formal vocabularies, and how they can be recognized through meta-schemas + - Additional guidance on initial base URIs beyond network retrieval + - Allow "schema" media type parameter for "application/schema+json" + - Better explanation of media type parameters and the HTTP Accept header + - Use "$id" to establish canonical and base absolute-URIs only, no fragments + - Replace plain-name-fragment-only form of "$id" with "$anchor" + - Clarified that the behavior of JSON Pointers across "$id" boundary is unreliable +- *draft-handrews-json-schema-01* + - This draft is purely a clarification with no functional changes + - Emphasized annotations as a primary usage of JSON Schema + - Clarified $id by use cases + - Exhaustive schema identification examples + - Replaced "external referencing" with how and when an implementation might know of a schema from another document + - Replaced "internal referencing" with how an implementation should recognized schema identifiers during parsing + - Dereferencing the former "internal" or "external" references is always the same process + - Minor formatting improvements +- *draft-handrews-json-schema-00* + - Make the concept of a schema keyword vocabulary more clear + - Note that the concept of "integer" is from a vocabulary, not the data model + - Classify keywords as assertions or annotations and describe their general behavior + - Explain the boolean schemas in terms of generalized assertions + - Reserve "$comment" for non-user-visible notes about the schema + - Wording improvements around "$id" and fragments + - Note the challenges of extending meta-schemas with recursive references + - Add "application/schema-instance+json" media type + - Recommend a "schema" link relation / parameter instead of "profile" +- *draft-wright-json-schema-01* + - Updated intro + - Allowed for any schema to be a boolean + - "$schema" SHOULD NOT appear in subschemas, although that may change + - Changed "id" to "$id"; all core keywords prefixed with "$" + - Clarify and formalize fragments for application/schema+json + - Note applicability to formats such as CBOR that can be represented in the JSON data model +- *draft-wright-json-schema-00* + - Updated references to JSON + - Updated references to HTTP + - Updated references to JSON Pointer + - Behavior for "id" is now specified in terms of RFC3986 + - Aligned vocabulary usage for URIs with RFC3986 + - Removed reference to draft-pbryan-zyp-json-ref-03 + - Limited use of "$ref" to wherever a schema is expected + - Added definition of the "JSON Schema data model" + - Added additional security considerations + - Defined use of subschema identifiers for "id" + - Rewrote section on usage with HTTP + - Rewrote section on usage with rel="describedBy" and rel="profile" + - Fixed numerous invalid examples +- *draft-zyp-json-schema-04* + - Salvaged from draft v3. + - Split validation keywords into separate document. + - Split hypermedia keywords into separate document. + - Initial post-split draft. + - Mandate the use of JSON Reference, JSON Pointer. + - Define the role of "id". Define URI resolution scope. + - Add interoperability considerations. +- *draft-zyp-json-schema-00* + - Initial draft. + +## Authors' Addresses + +### Austin Wright (*editor*) + +Email: aaa@bzfx.net + +### Henry Andrews (*editor*) + +Email: andrews_henry@yahoo.com + +### Ben Hutton (*editor*) + +Postman + +Email: ben@jsonschema.dev + +URI: https://jsonschema.dev + +### Greg Dennis + +Email: gregsdennis@yahoo.com + +URI: https://github.com/gregsdennis diff --git a/jsonschema-validation.md b/jsonschema-validation.md new file mode 100644 index 00000000..4026a4cf --- /dev/null +++ b/jsonschema-validation.md @@ -0,0 +1,1152 @@ +# JSON Schema Validation: A Vocabulary for Structural Validation of JSON + +## Abstract + +JSON Schema (application/schema+json) has several purposes, one of which is JSON +instance validation. +This document specifies a vocabulary for JSON Schema to describe the meaning of JSON +documents, provide hints for user interfaces working with JSON data, and to make +assertions about what a valid document must look like. + +## Note to Readers + +The issues list for this draft can be found at +https://github.com/json-schema-org/json-schema-spec/issues. + +For additional information, see https://json-schema.org/. + +To provide feedback, use this issue tracker, the communication methods listed on the +homepage, or email the document editors. + +## 1. Introduction + +JSON Schema can be used to require that a given JSON document (an instance) +satisfies a certain number of criteria. These criteria are asserted by using +keywords described in this specification. In addition, a set of keywords +is also defined to assist in interactive user interface instance generation. + +This specification will use the concepts, syntax, and terminology defined +by the [JSON Schema core](#json-schema) specification. + +## 2. Conventions and Terminology + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", +"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be +interpreted as described in [RFC 2119](#rfc2119). + +This specification uses the term "container instance" to refer to both array and +object instances. It uses the term "children instances" to refer to array elements +or object member values. + +Elements in an array value are said to be unique if no two elements of this array +are [equal](#json-schema). + +## 3. Overview + +JSON Schema validation asserts constraints on the structure of instance data. +An instance location that satisfies all asserted constraints is then +annotated with any keywords that contain non-assertion information, +such as descriptive metadata and usage hints. If all locations within +the instance satisfy all asserted constraints, then the instance is +said to be valid against the schema. + +Each schema object is independently evaluated against each instance location +to which it applies. This greatly simplifies the implementation requirements +for validators by ensuring that they do not need to maintain state across +the document-wide validation process. + +This specification defines a set of assertion keywords, as well as a small vocabulary +of metadata keywords that can be used to annotate the JSON instance with +useful information. The [Section 7](#7-vocabularies-for-semantic-content-with--format-) keyword is intended primarily +as an annotation, but can optionally be used as an assertion. The +[Section 8](#8-a-vocabulary-for-the-contents-of-string-encoded-data) keywords are annotations for working with documents +embedded as JSON strings. + +## 4. Interoperability Considerations + +### 4.1. Validation of String Instances + +It should be noted that the nul character (\u0000) is valid in a JSON string. An +instance to validate may contain a string value with this character, regardless +of the ability of the underlying programming language to deal with such data. + +### 4.2. Validation of Numeric Instances + +The JSON specification allows numbers with arbitrary precision, and JSON Schema +does not add any such bounds. +This means that numeric instances processed by JSON Schema can be arbitrarily large and/or +have an arbitrarily long decimal part, regardless of the ability of the +underlying programming language to deal with such data. + +### 4.3. Regular Expressions + +Keywords that use regular expressions, or constrain the instance value +to be a regular expression, are subject to the interoperability +considerations for regular expressions in the +[JSON Schema Core](#json-schema) specification. + +## 5. Meta-Schema + +The current IRI for the default JSON Schema dialect meta-schema is +https://json-schema.org/draft/next/schema. +For schema author convenience, this meta-schema describes a dialect +consisting of all vocabularies +defined in this specification and the JSON Schema Core specification, +as well as two former keywords which are reserved for a transitional period. +Individual vocabulary and vocabulary meta-schema IRIs are given for +each section below. Certain vocabularies are optional to support, which +is explained in detail in the relevant sections. + +Updated vocabulary and meta-schema IRIs MAY be published between +specification drafts in order to correct errors. Implementations +SHOULD consider IRIs dated after this specification draft and +before the next to indicate the same syntax and semantics +as those listed here. + +## 6. A Vocabulary for Structural Validation + +Validation keywords in a schema impose requirements for successful validation of an +instance. These keywords are all assertions without any annotation behavior. + +Meta-schemas that do not use "$vocabulary" SHOULD be considered to +require this vocabulary as if its IRI were present with a value of true. + +The current IRI for this vocabulary, known as the Validation vocabulary, is: +. + +The current IRI for the corresponding meta-schema is: +https://json-schema.org/draft/next/meta/validation. + +### 6.1. Validation Keywords for Any Instance Type + +#### 6.1.1. type + +The value of this keyword MUST be either a string or an array. If it is +an array, elements of the array MUST be strings and MUST be unique. + +String values MUST be one of the six primitive types +("null", "boolean", "object", "array", "number", or "string"), +or "integer" which matches any number with a zero fractional part. + +If the value of "type" is a string, then an instance validates successfully if +its type matches the type represented by the value of the string. +If the value of "type" is an array, then an instance validates successfully if +its type matches any of the types indicated by the strings in the array. + +#### 6.1.2. enum + +The value of this keyword MUST be an array. This array SHOULD have at +least one element. Elements in the array SHOULD be unique. + +An instance validates successfully against this keyword if its value is +equal to one of the elements in this keyword's array value. + +Elements in the array might be of any type, including null. + +#### 6.1.3. const + +The value of this keyword MAY be of any type, including null. + +Use of this keyword is functionally equivalent to an +["enum"](#612-enum) with a single value. + +An instance validates successfully against this keyword if its value is +equal to the value of the keyword. + +### 6.2. Validation Keywords for Numeric Instances (number and integer) + +#### 6.2.1. multipleOf + +The value of "multipleOf" MUST be a number, strictly greater than 0. + +A numeric instance is valid only if division by this keyword's value results in +an integer. + +#### 6.2.2. maximum + +The value of "maximum" MUST be a number, representing an inclusive upper limit +for a numeric instance. + +If the instance is a number, then this keyword validates only if the instance is +less than or exactly equal to "maximum". + +#### 6.2.3. exclusiveMaximum + +The value of "exclusiveMaximum" MUST be a number, representing an exclusive upper +limit for a numeric instance. + +If the instance is a number, then the instance is valid only if it has a value +strictly less than (not equal to) "exclusiveMaximum". + +#### 6.2.4. minimum + +The value of "minimum" MUST be a number, representing an inclusive lower limit +for a numeric instance. + +If the instance is a number, then this keyword validates only if the instance is +greater than or exactly equal to "minimum". + +#### 6.2.5. exclusiveMinimum + +The value of "exclusiveMinimum" MUST be a number, representing an exclusive lower +limit for a numeric instance. + +If the instance is a number, then the instance is valid only if it has a value +strictly greater than (not equal to) "exclusiveMinimum". + +### 6.3. Validation Keywords for Strings + +#### 6.3.1. maxLength + +The value of this keyword MUST be a non-negative integer. + +A string instance is valid against this keyword if its +length is less than, or equal to, the value of this keyword. + +The length of a string instance is defined as the number of its +characters as defined by [RFC 8259](#rfc8259). + +#### 6.3.2. minLength + +The value of this keyword MUST be a non-negative integer. + +A string instance is valid against this keyword if its +length is greater than, or equal to, the value of this keyword. + +The length of a string instance is defined as the number of its +characters as defined by [RFC 8259](#rfc8259). + +Omitting this keyword has the same behavior as a value of 0. + +#### 6.3.3. pattern + +The value of this keyword MUST be a string. This string SHOULD be a +valid regular expression, according to the ECMA-262 regular expression +dialect. + +A string instance is considered valid if the regular +expression matches the instance successfully. Recall: regular +expressions are not implicitly anchored. + +### 6.4. Validation Keywords for Arrays + +#### 6.4.1. maxItems + +The value of this keyword MUST be a non-negative integer. + +An array instance is valid against "maxItems" if its size is +less than, or equal to, the value of this keyword. + +#### 6.4.2. minItems + +The value of this keyword MUST be a non-negative integer. + +An array instance is valid against "minItems" if its size is +greater than, or equal to, the value of this keyword. + +Omitting this keyword has the same behavior as a value of 0. + +#### 6.4.3. uniqueItems + +The value of this keyword MUST be a boolean. + +If this keyword has boolean value false, the instance validates +successfully. If it has boolean value true, the instance validates +successfully if all of its elements are unique. + +Omitting this keyword has the same behavior as a value of false. + +### 6.5. Validation Keywords for Objects + +#### 6.5.1. maxProperties + +The value of this keyword MUST be a non-negative integer. + +An object instance is valid against "maxProperties" if its +number of properties is less than, or equal to, the value of this +keyword. + +#### 6.5.2. minProperties + +The value of this keyword MUST be a non-negative integer. + +An object instance is valid against "minProperties" if its +number of properties is greater than, or equal to, the value of this +keyword. + +Omitting this keyword has the same behavior as a value of 0. + +#### 6.5.3. required + +The value of this keyword MUST be an array. +Elements of this array, if any, MUST be strings, and MUST be unique. + +An object instance is valid against this keyword if every item in the array is +the name of a property in the instance. + +Omitting this keyword has the same behavior as an empty array. + +#### 6.5.4. dependentRequired + +The value of this keyword MUST be an object. Properties in +this object, if any, MUST be arrays. Elements in each array, +if any, MUST be strings, and MUST be unique. + +This keyword specifies properties that are required if a specific +other property is present. Their requirement is dependent on the +presence of the other property. + +Validation succeeds if, for each name that appears in both +the instance and as a name within this keyword's value, every +item in the corresponding array is also the name of a property +in the instance. + +Omitting this keyword has the same behavior as an empty object. + +## 7. Vocabularies for Semantic Content With "format" + +### 7.1. Foreword + +Structural validation alone may be insufficient to allow an application to correctly +utilize certain values. The "format" annotation keyword is defined to allow schema +authors to convey semantic information for a fixed subset of values which are +accurately described by authoritative resources, be they RFCs or other external +specifications. + +The value of this keyword is called a format attribute. It MUST be a string. A +format attribute can generally only validate a given set of instance types. If +the type of the instance to validate is not in this set, validation for this +format attribute and instance SHOULD succeed. All format attributes defined +in this section apply to strings, but a format attribute can be specified +to apply to any instance types defined in the data model defined in the +[core JSON Schema.](#json-schema)[^1] +[^1]: Note that the "type" keyword in this specification defines an "integer" type +which is not part of the data model. Therefore a format attribute can be +limited to numbers, but not specifically to integers. However, a numeric +format can be used alongside the "type" keyword with a value of "integer", +or could be explicitly defined to always pass if the number is not an integer, +which produces essentially the same behavior as only applying to integers. + +The current IRI for this vocabulary, known as the Format-Annotation vocabulary, is: +. The current +IRI for the corresponding meta-schema is: +https://json-schema.org/draft/next/meta/format-annotation. +Implementing support for this vocabulary is REQUIRED. + +In addition to the Format-Annotation vocabulary, a secondary vocabulary is available +for custom meta-schemas that defines "format" as an assertion. The IRI for the +Format-Assertion vocabulary, is: +. The current +IRI for the corresponding meta-schema is: +https://json-schema.org/draft/next/meta/format-assertion. +Implementing support for the Format-Assertion vocabulary is OPTIONAL. + +Specifying both the Format-Annotation and the Format-Assertion vocabularies is functionally +equivalent to specifying only the Format-Assertion vocabulary since its requirements +are a superset of the Format-Annotation vocabulary. + +### 7.2. Implementation Requirements + +The "format" keyword functions as defined by the vocabulary which is referenced. + +#### 7.2.1. Format-Annotation Vocabulary + +The value of format MUST be collected as an annotation, if the implementation +supports annotation collection. This enables application-level validation when +schema validation is unavailable or inadequate. + +Implementations MAY still treat "format" as an assertion in addition to an +annotation and attempt to validate the value's conformance to the specified +semantics. The implementation MUST provide options to enable and disable such +evaluation and MUST be disabled by default. Implementations SHOULD document +their level of support for such validation.[^2] +[^2]: Specifying the Format-Annotation vocabulary and enabling validation in an +implementation should not be viewed as being equivalent to specifying +the Format-Assertion vocabulary since implementations are not required to +provide full validation support when the Format-Assertion vocabulary +is not specified. + +When the implementation is configured for assertion behavior, it: + +- SHOULD provide an implementation-specific best effort validation + for each format attribute defined below; +- MAY choose to implement validation of any or all format attributes + as a no-op by always producing a validation result of true;[^3] + [^3]: This matches the current reality of implementations, which provide + widely varying levels of validation, including no validation at all, + for some or all format attributes. It is also designed to encourage + relying only on the annotation behavior and performing semantic + validation in the application, which is the recommended best practice. + +#### 7.2.2. Format-Assertion Vocabulary + +When the Format-Assertion vocabulary is declared with a value of true, +implementations MUST provide full validation support for all of the formats +defined by this specificaion. Implementations that cannot provide full +validation support MUST refuse to process the schema. + +An implementation that supports the Format-Assertion vocabulary: + +- MUST still collect "format" as an annotation if the implementation + supports annotation collection; +- MUST evaluate "format" as an assertion; +- MUST implement syntactic validation for all format attributes defined + in this specification, and for any additional format attributes that + it recognizes, such that there exist possible instance values + of the correct type that will fail validation. + The requirement for minimal validation of format attributes is intentionally + vague and permissive, due to the complexity involved in many of the attributes. + Note in particular that the requirement is limited to syntactic checking; it is + not to be expected that an implementation would send an email, attempt to connect + to a URL, or otherwise check the existence of an entity identified by a format + instance.[^4] + [^4]: The expectation is that for simple formats such as date-time, syntactic + validation will be thorough. For a complex format such as email addresses, + which are the amalgamation of various standards and numerous adjustments + over time, with obscure and/or obsolete rules that may or may not be + restricted by other applications making use of the value, a minimal validation + is sufficient. For example, an instance string that does not contain + an "@" is clearly not a valid email address, and an "email" or "hostname" + containing characters outside of 7-bit ASCII is likewise clearly invalid. + +It is RECOMMENDED that implementations use a common parsing library for each format, +or a well-known regular expression. Implementations SHOULD clearly document +how and to what degree each format attribute is validated. + +The [standard core and validation meta-schema](#5-meta-schema) +includes this vocabulary in its "$vocabulary" keyword with a value of false, +since by default implementations are not required to support this keyword +as an assertion. Supporting the format vocabulary with a value of true is +understood to greatly increase code size and in some cases execution time, +and will not be appropriate for all implementations. + +#### 7.2.3. Custom format attributes + +Implementations MAY support custom format attributes. Save for agreement between +parties, schema authors SHALL NOT expect a peer implementation to support such +custom format attributes. An implementation MUST NOT fail to collect unknown formats +as annotations. When the Format-Assertion vocabulary is specified, implementations +MUST fail upon encountering unknown formats. + +Vocabularies do not support specifically declaring different value sets for keywords. +Due to this limitation, and the historically uneven implementation of this keyword, +it is RECOMMENDED to define additional keywords in a custom vocabulary rather than +additional format attributes if interoperability is desired. + +### 7.3. Defined Formats + +#### 7.3.1. Dates, Times, and Duration + +These attributes apply to string instances. + +Date and time format names are derived from +[RFC 3339, section 5.6](#rfc3339). +The duration format is from the ISO 8601 ABNF as given +in Appendix A of RFC 3339. + +Implementations supporting formats SHOULD implement support for +the following attributes: + +- *date-time:* A string instance is valid against this attribute if it is + a valid representation according to the "date-time' ABNF rule + (referenced above) +- *date:* A string instance is valid against this attribute if it is + a valid representation according to the "full-date" ABNF rule + (referenced above) +- *time:* A string instance is valid against this attribute if it is + a valid representation according to the "full-time" ABNF rule + (referenced above) +- *duration:* A string instance is valid against this attribute if it is + a valid representation according to the "duration" ABNF rule + (referenced above) + +Implementations MAY support additional attributes using the other +format names defined anywhere in that RFC. If "full-date" or "full-time" +are implemented, the corresponding short form ("date" or "time" +respectively) MUST be implemented, and MUST behave identically. +Implementations SHOULD NOT define extension attributes +with any name matching an RFC 3339 format unless it validates +according to the rules of that format.[^5] +[^5]: There is not currently consensus on the need for supporting +all RFC 3339 formats, so this approach of reserving the +namespace will encourage experimentation without committing +to the entire set. Either the format implementation requirements +will become more flexible in general, or these will likely +either be promoted to fully specified attributes or dropped. + +#### 7.3.2. Email Addresses + +These attributes apply to string instances. + +A string instance is valid against these attributes if it is a valid +Internet email address as follows: + +- *email:* As defined by the "Mailbox" ABNF rule in + [RFC 5321, section 4.1.2](#rfc5321). +- *idn-email:* As defined by the extended "Mailbox" ABNF rule in + [RFC 6531, section 3.3](#rfc6531). + Note that all strings valid against the "email" attribute are also + valid against the "idn-email" attribute. + +#### 7.3.3. Hostnames + +These attributes apply to string instances. + +A string instance is valid against these attributes if it is a valid +representation for an Internet hostname as follows: + +- *hostname:* As defined by [RFC 1123, section 2.1](#rfc1123), + including host names produced using the Punycode algorithm + specified in [RFC 5891, section 4.4](#rfc5891). +- *idn-hostname:* As defined by either RFC 1123 as for hostname, or an + internationalized hostname as defined by + [RFC 5890, section 2.3.2.3](#rfc5890). + Note that all strings valid against the "hostname" attribute are also + valid against the "idn-hostname" attribute. + +#### 7.3.4. IP Addresses + +These attributes apply to string instances. + +A string instance is valid against these attributes if it is a valid +representation of an IP address as follows: + +- *ipv4:* An IPv4 address according to the "dotted-quad" ABNF + syntax as defined in + [RFC 2673, section 3.2](#rfc2673). +- *ipv6:* An IPv6 address as defined in + [RFC 4291, section 2.2](#rfc4291). + +#### 7.3.5. Resource Identifiers + +These attributes apply to string instances. + +- *uri:* A string instance is valid against this attribute if it is + a valid IRI, according to [RFC3987](#rfc3987). +- *uri-reference:* A string instance is valid against this attribute if it is a valid URI + Reference (either a URI or a relative-reference), + according to [RFC3986](#rfc3986). +- *iri:* A string instance is valid against this attribute if it is + a valid IRI, according to [RFC3987](#rfc3987). +- *iri-reference:* A string instance is valid against this attribute if it is a valid IRI + Reference (either an IRI or a relative-reference), + according to [RFC3987](#rfc3987). +- *uuid:* A string instance is valid against this attribute if it is a valid + string representation of a UUID, according to [RFC4122](#rfc4122). + +Note that all valid URIs are valid IRIs, and all valid URI References are +also valid IRI References. + +Note also that the "uuid" format is for plain UUIDs, not UUIDs in URNs. An example +is "f81d4fae-7dec-11d0-a765-00a0c91e6bf6". For UUIDs as URNs, use the "uri" format, +with a "pattern" regular expression of "^urn:uuid:" to indicate the URI scheme and +URN namespace. + +#### 7.3.6. uri-template + +This attribute applies to string instances. + +A string instance is valid against this attribute if it is a valid URI Template +(of any level), according to [RFC6570](#rfc6570). + +Note that URI Templates may be used for IRIs; there is no separate +IRI Template specification. + +#### 7.3.7. JSON Pointers + +These attributes apply to string instances. + +- *json-pointer:* A string instance is valid against this attribute if it + is a valid JSON string representation of a JSON Pointer, + according to [RFC 6901, section 5](#rfc6901). +- *relative-json-pointer:* A string instance is valid against this attribute if it is a valid + [Relative JSON Pointer](#relative-json-pointer). + To allow for both absolute and relative JSON Pointers, use "anyOf" or + "oneOf" to indicate support for either format. + +#### 7.3.8. regex + +This attribute applies to string instances. + +A regular expression, which SHOULD be valid according to the +[ECMA-262](#ecma262) regular expression dialect. + +Implementations that validate formats MUST accept at least the subset of +ECMA-262 defined in the [Regular Expressions](#43-regular-expressions) +section of this specification, and SHOULD accept all valid ECMA-262 expressions. + +## 8. A Vocabulary for the Contents of String-Encoded Data + +### 8.1. Foreword + +Annotations defined in this section indicate that an instance contains +non-JSON data encoded in a JSON string. + +These properties provide additional information required to interpret JSON data +as rich multimedia documents. They describe the type of content, how it is encoded, +and/or how it may be validated. They do not function as validation assertions; +a malformed string-encoded document MUST NOT cause the containing instance +to be considered invalid. + +Meta-schemas that do not use "$vocabulary" SHOULD be considered to +require this vocabulary as if its IRI were present with a value of true. + +The current IRI for this vocabulary, known as the Content vocabulary, is: +. + +The current IRI for the corresponding meta-schema is: +https://json-schema.org/draft/next/meta/content. + +### 8.2. Implementation Requirements + +Due to security and performance concerns, as well as the open-ended nature of +possible content types, implementations MUST NOT automatically decode, parse, +and/or validate the string contents. Applications are expected to use these +annotations to invoke the appropriate libraries separately. + +All keywords in this section apply only to strings, and have no +effect on other data types. + +### 8.3. contentEncoding + +If the instance value is a string, this property defines that the string +SHOULD be interpreted as encoded binary data and applications wishing +to decode it SHOULD do so using the encoding named by this property. + +Possible values indicating base 16, 32, and 64 encodings with several +variations are listed in [RFC 4648](#rfc4648). Additionally, +sections 6.7 and 6.8 of [RFC 2045](#rfc2045) provide +encodings used in MIME. This keyword is derived from MIME's +Content-Transfer-Encoding header, which was designed to map binary data +into ASCII characters. It is not related to HTTP's Content-Encoding header, +which is used to encode (e.g. compress or encrypt) +the content of HTTP request and responses. + +As "base64" is defined in both RFCs, the definition +from RFC 4648 SHOULD be assumed unless the string is specifically intended +for use in a MIME context. Note that all of these encodings result in +strings consisting only of 7-bit ASCII characters. Therefore, this keyword +has no meaning for strings containing characters outside of that range. + +If this keyword is absent, but "contentMediaType" is present, this +indicates that the encoding is the identity encoding, meaning that +no transformation was needed in order to represent the content in +a UTF-8 string. + +The value of this property MUST be a string. + +### 8.4. contentMediaType + +If the instance is a string, this property indicates the media type +of the contents of the string. If "contentEncoding" is present, +this property describes the decoded string. + +The value of this property MUST be a string, which MUST be a media type, +as defined by [RFC 2046](#rfc2046). + +### 8.5. contentSchema + +If the instance is a string, and if "contentMediaType" is present, this +property contains a schema which describes the structure of the string. + +This keyword MAY be used with any media type that can be mapped into +JSON Schema's data model. Specifying such mappings is outside of the +scope of this specification. + +The value of this property MUST be a valid JSON schema. It SHOULD be ignored if +"contentMediaType" is not present. Accessing the schema through the schema location +IRI included as part of the annotation will ensure that it is correctly processed +as a subschema. Using the extracted annotation value directly is only safe if +the schema is an embedded resource with both "$schema" and an absolute-IRI "$id". + +### 8.6. Example + +Here is an example schema, illustrating the use of "contentEncoding" and +"contentMediaType": + +```json +{ + "type": "string", + "contentEncoding": "base64", + "contentMediaType": "image/png" +} +``` + +Instances described by this schema are expected to be strings, +and their values should be interpretable as base64-encoded PNG images. + +Another example: + +```json +{ + "type": "string", + "contentMediaType": "text/html" +} +``` + +Instances described by this schema are expected to be strings containing HTML, +using whatever character set the JSON string was decoded into. +Per section 8.1 of +[RFC 8259](#rfc8259), outside of an entirely closed +system, this MUST be UTF-8. + +This example describes a JWT that is MACed using the HMAC SHA-256 +algorithm, and requires the "iss" and "exp" fields in its claim set. + +```json +{ + "type": "string", + "contentMediaType": "application/jwt", + "contentSchema": { + "type": "array", + "minItems": 2, + "prefixItems": [ + { + "const": { + "typ": "JWT", + "alg": "HS256" + } + }, + { + "type": "object", + "required": [ + "iss", + "exp" + ], + "properties": { + "iss": { + "type": "string" + }, + "exp": { + "type": "integer" + } + } + } + ] + } +} +``` + +Note that "contentEncoding" does not appear. While the "application/jwt" +media type makes use of base64url encoding, that is defined by the media +type, which determines how the JWT string is decoded into a list of two +JSON data structures: first the header, and then the payload. Since the +JWT media type ensures that the JWT can be represented in a JSON string, +there is no need for further encoding or decoding. + +## 9. A Vocabulary for Basic Meta-Data Annotations + +These general-purpose annotation keywords provide commonly used information +for documentation and user interface display purposes. They are not intended +to form a comprehensive set of features. Rather, additional vocabularies +can be defined for more complex annotation-based applications. + +Meta-schemas that do not use "$vocabulary" SHOULD be considered to +require this vocabulary as if its IRI were present with a value of true. + +The current IRI for this vocabulary, known as the Meta-Data vocabulary, is: +. + +The current IRI for the corresponding meta-schema is: +https://json-schema.org/draft/next/meta/meta-data. + +### 9.1. "title" and "description" + +The value of both of these keywords MUST be a string. + +Both of these keywords can be used to decorate a user interface with +information about the data produced by this user interface. A title will +preferably be short, whereas a description will provide explanation about +the purpose of the instance described by this schema. + +### 9.2. "default" + +There are no restrictions placed on the value of this keyword. When +multiple occurrences of this keyword are applicable to a single +sub-instance, implementations SHOULD remove duplicates. + +This keyword can be used to supply a default JSON value associated with a +particular schema. It is RECOMMENDED that a default value be valid against +the associated schema. + +### 9.3. "deprecated" + +The value of this keyword MUST be a boolean. When multiple occurrences +of this keyword are applicable to a single sub-instance, applications +SHOULD consider the instance location to be deprecated if any occurrence +specifies a true value. + +If "deprecated" has a value of boolean true, it indicates that applications +SHOULD refrain from usage of the declared property. It MAY mean the property +is going to be removed in the future. + +A root schema containing "deprecated" with a value of true indicates that +the entire resource being described MAY be removed in the future. + +The "deprecated" keyword applies to each instance location to which the +schema object containing the keyword successfully applies. This can +result in scenarios where every array item or object property +is deprecated even though the containing array or object is not. + +Omitting this keyword has the same behavior as a value of false. + +### 9.4. "readOnly" and "writeOnly" + +The value of these keywords MUST be a boolean. When multiple occurrences +of these keywords are applicable to a single sub-instance, the resulting +behavior SHOULD be as for a true value if any occurrence specifies a true value, +and SHOULD be as for a false value otherwise. + +If "readOnly" has a value of boolean true, it indicates that the value +of the instance is managed exclusively by the owning authority, and +attempts by an application to modify the value of this property are +expected to be ignored or rejected by that owning authority. + +An instance document that is marked as "readOnly" for the entire document +MAY be ignored if sent to the owning authority, or MAY result in an +error, at the authority's discretion. + +If "writeOnly" has a value of boolean true, it indicates that the value +is never present when the instance is retrieved from the owning authority. +It can be present when sent to the owning authority to update or create +the document (or the resource it represents), but it will not be included +in any updated or newly created version of the instance. + +An instance document that is marked as "writeOnly" for the entire document +MAY be returned as a blank document of some sort, or MAY produce an error +upon retrieval, or have the retrieval request ignored, at the authority's +discretion. + +For example, "readOnly" would be used to mark a database-generated serial +number as read-only, while "writeOnly" would be used to mark a password +input field. + +These keywords can be used to assist in user interface instance generation. +In particular, an application MAY choose to use a widget that hides +input values as they are typed for write-only fields. + +Omitting these keywords has the same behavior as values of false. + +### 9.5. "examples" + +The value of this keyword MUST be an array. +There are no restrictions placed on the values within the array. +When multiple occurrences of this keyword are applicable to a single +sub-instance, implementations MUST provide a flat array of all +values rather than an array of arrays. + +This keyword can be used to provide sample JSON values associated with a +particular schema, for the purpose of illustrating usage. It is +RECOMMENDED that these values be valid against the associated schema. + +Implementations MAY use the value(s) of "default", if present, as +an additional example. If "examples" is absent, "default" +MAY still be used in this manner. + +## 10. Security Considerations + +JSON Schema validation defines a vocabulary for JSON Schema core and concerns all +the security considerations listed there. + +JSON Schema validation allows the use of Regular Expressions, which have numerous +different (often incompatible) implementations. +Some implementations allow the embedding of arbitrary code, which is outside the +scope of JSON Schema and MUST NOT be permitted. +Regular expressions can often also be crafted to be extremely expensive to compute +(with so-called "catastrophic backtracking"), resulting in a denial-of-service +attack. + +Implementations that support validating or otherwise evaluating instance +string data based on "contentEncoding" and/or "contentMediaType" are at +risk of evaluating data in an unsafe way based on misleading information. +Applications can mitigate this risk by only performing such processing +when a relationship between the schema and instance is established +(e.g., they share the same authority). + +Processing a media type or encoding is subject to the security considerations +of that media type or encoding. For example, the security considerations +of [RFC 4329 Scripting Media Types](#rfc4329) apply when +processing JavaScript or ECMAScript encoded within a JSON string. + +## 11. References + +### 11.1. Normative References + +#### [RFC2119] + +Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March +1997, <>. + +#### [RFC1123] + +Braden, R., Ed., "Requirements for Internet Hosts - Application and Support", STD 3, RFC 1123, DOI 10.17487/RFC1123, +October 1989, <>. + +#### [RFC2045] + +Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", +RFC 2045, DOI 10.17487/RFC2045, November 1996, <>. + +#### [RFC2046] + +Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types", RFC 2046, DOI +10.17487/RFC2046, November 1996, <>. + +#### [RFC2673] + +Crawford, M., "Binary Labels in the Domain Name System", RFC 2673, DOI 10.17487/RFC2673, August +1999, <>. + +#### [RFC3339] + +Klyne, G. and C. Newman, "Date and Time on the Internet: Timestamps", RFC 3339, DOI 10.17487/RFC3339, July +2002, <>. + +#### [RFC3986] + +Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, +DOI 10.17487/RFC3986, January 2005, <>. + +#### [RFC3987] + +Duerst, M. and M. Suignard, "Internationalized Resource Identifiers (IRIs)", RFC 3987, DOI 10.17487/RFC3987, January +2005, <>. + +#### [RFC4122] + +Leach, P., Mealling, M., and R. Salz, "A Universally Unique IDentifier (UUID) URN Namespace", RFC 4122, DOI +10.17487/RFC4122, July 2005, <>. + +#### [RFC4291] + +Hinden, R. and S. Deering, "IP Version 6 Addressing Architecture", RFC 4291, DOI 10.17487/RFC4291, February +2006, <>. + +#### [RFC4648] + +Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, DOI 10.17487/RFC4648, October +2006, <>. + +#### [RFC5321] + +Klensin, J., "Simple Mail Transfer Protocol", RFC 5321, DOI 10.17487/RFC5321, October +2008, <>. + +#### [RFC5890] + +Klensin, J., "Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework", RFC 5890, DOI +10.17487/RFC5890, August 2010, <>. + +#### [RFC5891] + +Klensin, J., "Internationalized Domain Names in Applications (IDNA): Protocol", RFC 5891, DOI 10.17487/RFC5891, August +2010, <>. + +#### [RFC6570] + +Gregorio, J., Fielding, R., Hadley, M., Nottingham, M., and D. Orchard, "URI Template", RFC 6570, DOI 10.17487/RFC6570, +March 2012, <>. + +#### [RFC6531] + +Yao, J. and W. Mao, "SMTP Extension for Internationalized Email", RFC 6531, DOI 10.17487/RFC6531, February +2012, <>. + +#### [RFC6901] + +Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed., "JavaScript Object Notation (JSON) Pointer", RFC 6901, DOI +10.17487/RFC6901, April 2013, <>. + +#### [RFC8259] + +Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, +December 2017, <>. + +#### [ecma262] + +"ECMA-262, 11th edition specification", June 2020, <>. + +#### [relative-json-pointer] + +Luff, G., Andrews, H., and B. Hutton, Ed., "Relative JSON Pointers", Work in Progress, Internet-Draft, +draft-handrews-relative-json-pointer-01, December +2020, <>. + +#### [json-schema] + +Wright, A., Andrews, H., Hutton, B., and G. Dennis, "JSON Schema: A Media Type for Describing JSON Documents", Work in +Progress, Internet-Draft, draft-bhutton-json-schema-01, June +2022, <>. + +### 11.2. Informative References + +#### [RFC4329] + +Hoehrmann, B., "Scripting Media Types", RFC 4329, DOI 10.17487/RFC4329, April +2006, <>. + +## Appendix A. Keywords Moved from Validation to Core + +Several keywords have been moved from this document into the +[Core Specification](#json-schema) starting with draft 2019-09, +in some cases with re-naming or other changes. This affects the following former +validation keywords: + +- *"definitions"* Renamed to "$defs" to match "$ref" and be shorter to type. + Schema vocabulary authors SHOULD NOT define a "definitions" keyword + with different behavior in order to avoid invalidating schemas that + still use the older name. While "definitions" is absent in the + single-vocabulary meta-schemas referenced by this document, it + remains present in the default meta-schema, and implementations + SHOULD assume that "$defs" and "definitions" have the same + behavior when that meta-schema is used. +- *"allOf", "anyOf", "oneOf", "not", "if", "then", "else", "items", " + additionalItems", "contains", "propertyNames", "properties", "patternProperties", " + additionalProperties"* All of these keywords apply subschemas to the instance and combine + their results, without asserting any conditions of their own. + Without assertion keywords, these applicators can only cause assertion + failures by using the false boolean schema, or by inverting the result + of the true boolean schema (or equivalent schema objects). + For this reason, they are better defined as a generic mechanism on which + validation, hyper-schema, and extension vocabularies can all be based. +- *"maxContains", "minContains"* These keywords modify the behavior of "contains", and are therefore + grouped with it in the applicator vocabulary. +- *"dependencies"* This keyword had two different modes of behavior, which made it + relatively challenging to implement and reason about. + The schema form has been moved to Core and renamed to + "dependentSchemas", as part of the applicator vocabulary. + It is analogous to "properties", except that instead of applying + its subschema to the property value, it applies it to the object + containing the property. + The property name array form is retained here and renamed to + "dependentRequired", as it is an assertion which is a shortcut + for the conditional use of the "required" assertion keyword. + +## Appendix B. Acknowledgments + +Thanks to +Gary Court, +Francis Galiegue, +Kris Zyp, +and Geraint Luff +for their work on the initial drafts of JSON Schema. + +Thanks to +Jason Desrosiers, +Daniel Perrett, +Erik Wilde, +Evgeny Poberezkin, +Brad Bowman, +Gowry Sankar, +Donald Pipowitch, +Dave Finlay, +Denis Laxalde, +Phil Sturgeon, +Shawn Silverman, +and Karen Etheridge +for their submissions and patches to the document. + +## Appendix C. ChangeLog[^6] + +[^6]: This section to be removed before leaving Internet-Draft status. + +- *draft-next* + - Use IRIs instead of URIs +- *draft-bhutton-json-schema-validation-01* + - Improve and clarify the "minContains" keyword explanation + - Remove the use of "production" in favour of "ABNF rule" +- *draft-bhutton-json-schema-validation-00* + - Correct email format RFC reference to 5321 instead of 5322 + - Clarified the set and meaning of "contentEncoding" values + - Reference ECMA-262, 11th edition for regular expression support + - Split "format" into an annotation only vocabulary and an assertion vocabulary + - Clarify "deprecated" when applicable to arrays +- *draft-handrews-json-schema-validation-02* + - Grouped keywords into formal vocabularies + - Update "format" implementation requirements in terms of vocabularies + - By default, "format" MUST NOT be validated, although validation can be enabled + - A vocabulary declaration can be used to require "format" validation + - Moved "definitions" to the core spec as "$defs" + - Moved applicator keywords to the core spec + - Renamed the array form of "dependencies" to "dependentRequired", moved the schema form to the core spec + - Specified all "content*" keywords as annotations, not assertions + - Added "contentSchema" to allow applying a schema to a string-encoded document + - Also allow RFC 4648 encodings in "contentEncoding" + - Added "minContains" and "maxContains" + - Update RFC reference for "hostname" and "idn-hostname" + - Add "uuid" and "duration" formats +- *draft-handrews-json-schema-validation-01* + - This draft is purely a clarification with no functional changes + - Provided the general principle behind ignoring annotations under "not" and similar cases + - Clarified "if"/"then"/"else" validation interactions + - Clarified "if"/"then"/"else" behavior for annotation + - Minor formatting and cross-referencing improvements +- *draft-handrews-json-schema-validation-00* + - Added "if"/"then"/"else" + - Classify keywords as assertions or annotations per the core spec + - Warn of possibly removing "dependencies" in the future + - Grouped validation keywords into sub-sections for readability + - Moved "readOnly" from hyper-schema to validation meta-data + - Added "writeOnly" + - Added string-encoded media section, with former hyper-schema "media" keywords + - Restored "regex" format (removal was unintentional) + - Added "date" and "time" formats, and reserved additional RFC 3339 format names + - I18N formats: "iri", "iri-reference", "idn-hostname", "idn-email" + - Clarify that "json-pointer" format means string encoding, not URI fragment + - Fixed typo that inverted the meaning of "minimum" and "exclusiveMinimum" + - Move format syntax references into Normative References + - JSON is a normative requirement +- *draft-wright-json-schema-validation-01* + - Standardized on hyphenated format names with full words ("uriref" becomes "uri-reference") + - Add the formats "uri-template" and "json-pointer" + - Changed "exclusiveMaximum"/"exclusiveMinimum" from boolean modifiers of "maximum"/"minimum" to independent numeric + fields. + - Split the additionalItems/items into two sections + - Reworked properties/patternProperties/additionalProperties definition + - Added "examples" keyword + - Added "contains" keyword + - Allow empty "required" and "dependencies" arrays + - Fixed "type" reference to primitive types + - Added "const" keyword + - Added "propertyNames" keyword +- *draft-wright-json-schema-validation-00* + - Added additional security considerations + - Removed reference to "latest version" meta-schema, use numbered version instead + - Rephrased many keyword definitions for brevity + - Added "uriref" format that also allows relative URI references +- *draft-fge-json-schema-validation-00* + - Initial draft. + - Salvaged from draft v3. + - Redefine the "required" keyword. + - Remove "extends", "disallow" + - Add "anyOf", "allOf", "oneOf", "not", "definitions", "minProperties", + "maxProperties". + - "dependencies" member values can no longer be single strings; at + least one element is required in a property dependency array. + - Rename "divisibleBy" to "multipleOf". + - "type" arrays can no longer have schemas; remove "any" as a possible + value. + - Rework the "format" section; make support optional. + - "format": remove attributes "phone", "style", "color"; rename + "ip-address" to "ipv4"; add references for all attributes. + - Provide algorithms to calculate schema(s) for array/object + instances. + - Add interoperability considerations. + +## Authors' Addresses + +### Austin Wright (*editor*) + +Email: aaa@bzfx.net + +### Henry Andrews (*editor*) + +Email: andrews_henry@yahoo.com + +### Ben Hutton (*editor*) + +Postman + +Email: ben@jsonschema.dev + +URI: https://jsonschema.dev diff --git a/relative-json-pointer.md b/relative-json-pointer.md new file mode 100644 index 00000000..d5fa93b3 --- /dev/null +++ b/relative-json-pointer.md @@ -0,0 +1,248 @@ +# Relative JSON Pointers + +## Abstract + +JSON Pointer is a syntax for specifying locations in a JSON document, +starting from the document root. This document defines an extension +to the JSON Pointer syntax, allowing relative locations from within +the document. + +## 1. Introduction + +JSON Pointer ([RFC 6901](#rfc6901)) is a syntax for specifying +locations in a JSON document, starting from the document root. This +document defines a related syntax allowing identification of relative locations +from within the document. + +## 2. Conventions and Terminology + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", +"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be +interpreted as described in [RFC 2119](#rfc2119). + +## 3. Syntax + +A Relative JSON Pointer is a Unicode string in UTF-8 encoding (see RFC 8259, +[Section 8](#rfc8259)), comprising a non-negative integer, +followed by either a '#' (%x23) character or a JSON Pointer +([RFC 6901](#rfc6901)). + +The separation between the integer prefix and the JSON Pointer will +always be unambiguous, because a JSON Pointer must be either zero- +length or start with a '/' (%x2F). Similarly, a JSON Pointer will +never be ambiguous with the '#'. + +The ABNF syntax of a Relative JSON Pointer is: + +```abnf +relative-json-pointer = non-negative-integer [index-manipulation] +relative-json-pointer =/ non-negative-integer "#" +index-manipulation = ("+" / "-") non-negative-integer +non-negative-integer = %x30 / %x31-39 *( %x30-39 ) + ; "0", or digits without a leading "0" +``` + +where follows the production defined in +[RFC 6901, Section 3](#rfc6901) ("Syntax"). + +## 4. Evaluation + +Evaluation of a Relative JSON Pointer begins with a reference to a +value within a JSON document, and completes with either a value +within that document, a string corresponding to an object member, or +integer value representing an array index. + +Evaluation begins by processing the non-negative-integer prefix. +This can be found by taking the longest continuous sequence of decimal +digits available, starting from the beginning of the string, taking +the decimal numerical value. If the value is zero, the following steps +are skipped. If this value is more than zero, then the following steps +are repeated that number of times: + +- If the current referenced value is the root of the document, then + evaluation fails (see below). +- If the referenced value is an item within an array, then the new + referenced value is that array. +- If the referenced value is an object member within an object, then + the new referenced value is that object. + +If the next character is a plus ("+") or minus ("-"), followed by another +continuous sequence of decimal digits, the following steps +are taken using the decimal numeric value of that plus or minus sign +and decimal sequence: + +- If the current referenced value is not an item of an array, + then evaluation fails (see below). +- If the referenced value is an item of an array, then the + new referenced value is the item of the array indexed by + adding the decimal value (which may be negative), to the + index of the current referenced value. + +If the remainder of the Relative JSON Pointer is a JSON Pointer, then +evaluation proceeds as per +[RFC 6901, Section 5](#rfc6901) +with the modification that the initial reference +being used is the reference currently being held (which may not be +root of the document). + +Otherwise (when the remainder of the Relative JSON Pointer is the +character '#'), the final result is determined as follows: + +- If the current referenced value is the root of the document, then + evaluation fails (see below). +- If the referenced value is an item within an array, then the final + evaluation result is the value's index position within the array. +- If the referenced value is an object member within an object, then + the new referenced value is the corresponding member name. + +## 5. JSON String Representation + +The concerns surrounding JSON String representation of a Relative +JSON Pointer are identical to those laid out in +[RFC 6901, Section 5](#rfc6901). + +### 5.1. Examples + +For example, given the JSON document: + +```json +{ + "foo": [ + "bar", + "baz" + ], + "highly": { + "nested": { + "objects": true + } + } +} +``` + +Starting from the value "baz" (inside "foo"), the following JSON +strings evaluate to the accompanying values: + +``` +"0" "baz" +"1/0" "bar" +"0-1" "bar" +"2/highly/nested/objects" true +"0#" 1 +"0-1#" 0 +"1#" "foo" +``` + +Starting from the value {"objects":true} (corresponding to the member +key "nested"), the following JSON strings evaluate to the +accompanying values: + +``` +"0/objects" true +"1/nested/objects" true +"2/foo/0" "bar" +"0#" "nested" +"1#" "highly" +``` + +## 6. Non-use in URI Fragment Identifiers + +Unlike a JSON Pointer, a Relative JSON Pointer can not be used in a +URI fragment identifier. Such fragments specify exact positions +within a document, and therefore Relative JSON Pointers are not +suitable. + +## 7. Error Handling + +In the event of an error condition, evaluation of the JSON Pointer +fails to complete. + +Evaluation may fail due to invalid syntax, or referencing a non- +existent value. This specification does not define how errors are +handled. An application of JSON Relative Pointer SHOULD specify the +impact and handling of each type of error. + +## 8. Relationship to JSON Pointer + +Relative JSON Pointers are intended as a companion to JSON Pointers. +Applications MUST specify the use of each syntax separately. +Defining either JSON Pointer or Relative JSON Pointer as an acceptable +syntax does not imply that the other syntax is also acceptable. + +## 9. Acknowledgements + +The language and structure of this specification are based heavily on +[RFC6901](#rfc6901), sometimes quoting it outright. + +This draft remains primarily as written and published by Geraint Luff, +with only minor subsequent alterations under new editorship. + +## 10. Security Considerations + +Evaluation of a given Relative JSON Pointer is not guaranteed to +reference an actual JSON value. Applications using Relative JSON +Pointer should anticipate this situation by defining how a pointer +that does not resolve ought to be handled. + +As part of processing, a composite data structure may be assembled +from multiple JSON documents (in part or in full). In such cases, +applications SHOULD ensure that a Relative JSON Pointer does not +evaluate to a value outside the document for which is was written. + +Note that JSON pointers can contain the NUL (Unicode U+0000) +character. Care is needed not to misinterpret this character in +programming languages that use NUL to mark the end of a string. + +## 11. References + +### 11.1. Normative References + +#### [RFC2119] + +Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March +1997, <>. + +#### [RFC6901] + +Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed., "JavaScript Object Notation (JSON) Pointer", RFC 6901, DOI +10.17487/RFC6901, April 2013, <>. + +### 11.2. Informative References + +#### [RFC8259] + +Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, +December 2017, <>. + +## Appendix A. ChangeLog[^1] + +[^1]: This section to be removed before leaving Internet-Draft status. + +- *draft-bhutton-relative-json-pointer-00* + - Add array forward and backward index manipulation +- *draft-handrews-relative-json-pointer-02* + - Update to the latest JSON RFC +- *draft-handrews-relative-json-pointer-01* + - The initial number is "non-negative", not "positive" +- *draft-handrews-relative-json-pointer-00* + - Revived draft with identical wording and structure. + - Clarified how to use alongside JSON Pointer. +- *draft-luff-relative-json-pointer-00* + - Initial draft. + +## Authors' Addresses + +### Geraint Luff + +Cambridge +UK +Email: luffgd@gmail.com + +### Henry Andrews (*editor*) + +Email: andrews_henry@yahoo.com + +### Ben Hutton (*editor*) + +Email: ben@jsonschema.dev + +URI: https://jsonschema.dev