Specification scope: Core with the Units and Validation companion specifications.

A processor needs to distinguish features a meta-schema makes available from features one schema actually uses. Without both declarations, availability looks like activation and processors must guess which optional vocabulary a document intended to select.

$offers publishes the available feature bundles. $uses records the bundles selected by a document checked against that meta-schema. Neither declaration substitutes for the other.

The extended meta-schema publishes named bundles

The extended v0 meta-schema offers five named bundles:

An offer may point to one add-in definition or to an array of them. The validation offer, for example, selects five add-ins together: NumberValidationAddIn, StringValidationAddIn, StringFormatAddIn, ArrayValidationAddIn, and ObjectValidationAddIn. A schema selects the public name; the pointers identify the add-ins behind that name.

The relevant $offers fragment is:

{
  "$offers": {
    "JSONStructureUnits": [
      "#/definitions/features/UnitsPropertyAddIn",
      "#/definitions/features/UnitsArrayAddIn",
      "#/definitions/features/UnitsMapAddIn"
    ],
    "JSONStructureValidation": [
      "#/definitions/features/NumberValidationAddIn",
      "#/definitions/features/StringValidationAddIn",
      "#/definitions/features/StringFormatAddIn",
      "#/definitions/features/ArrayValidationAddIn",
      "#/definitions/features/ObjectValidationAddIn"
    ]
  }
}

The fragment is illustrative, not a complete meta-schema. The complete extended meta-schema also imports core, identifies itself, declares its root, and contains the referenced definitions.

A schema selects by name

The following complete schema consumes two offers. $uses occurs at the root of the schema document because that document is the instance being checked by the extended meta-schema.

{
  "$schema": "https://json-structure.org/meta/extended/v0/#",
  "$id": "https://example.com/schemas/thermometer-reading",
  "name": "ThermometerReadingSchema",
  "$uses": [
    "JSONStructureUnits",
    "JSONStructureValidation"
  ],
  "$root": "#/definitions/ThermometerReading",
  "definitions": {
    "ThermometerReading": {
      "name": "ThermometerReading",
      "type": "object",
      "properties": {
        "sensorId": {
          "type": "string",
          "pattern": "^T-[0-9]{4}$"
        },
        "temperature": {
          "type": "double",
          "unit": "Cel",
          "minimum": -80,
          "maximum": 180
        }
      },
      "required": ["sensorId", "temperature"],
      "additionalProperties": false
    }
  }
}

This application instance needs no $uses because it selects no optional add-ins from the application schema:

{
  "$schema": "https://example.com/schemas/thermometer-reading",
  "sensorId": "T-0042",
  "temperature": 21.5
}

The instance is validated against the resulting schema. The schema document is where unit, pattern, minimum, and maximum had to be admitted into the schema vocabulary.

Core uses the same mechanism one layer down

Core also describes instance-level add-ins. An application schema can $offers an optional type augmentation such as delivery instructions, and an application instance can select it with $uses. In that case $uses belongs to the data instance, not to the schema.

A schema document is itself an instance when a meta-schema checks it. The current core draft is inconsistent at this point. One normative rule says $uses “MUST only” occur in instance documents, while the preceding text allows it in a meta-schema that references a parent schema. The core meta-schema includes $uses as a SchemaDocument property, and the published extended and validation meta-schemas use it at their roots.

The project’s own meta-schemas support this reading: $uses occurs at the root of the document receiving the add-ins. For vocabulary composition, that receiver is a schema or meta-schema document. For an application add-in, it is the application instance. Treating $uses as globally “data-only” would reject the project’s own meta-schemas.

This mechanism rejects undeclared extensions. A consumer cannot select an unadvertised name, and an offer cannot point vaguely outside its defining document. If a processor accepts either case, it is inventing vocabulary rather than implementing the declared one.