JSON Schema

JSON Schema is a declarative language, itself written in JSON, for describing the structure that a JSON document must have. A validator takes a schema and a document and reports whether the document conforms and, if not, where it fails. It is used to check API requests and responses, configuration files, and, increasingly, the outputs of language models.

Core keywords

A schema is usually an object whose keywords each add a restriction. (Since Draft 6, the literal true and false are also valid schemas: true accepts any document and false accepts none.) The keywords used most:

  • type: one of object, array, string, number, integer, boolean, null, or a list of them.
  • properties: for an object, a schema for each named key.
  • required: a list of keys that must be present. Properties not listed are optional.
  • additionalProperties: whether keys not listed in properties are allowed (false forbids them).
  • enum: the value must equal one of a fixed list.
  • minimum, maximum: bounds for numbers; minLength, maxLength: bounds for string length.
  • items: a schema for the elements of an array.

By default, anything the schema does not mention is allowed, which is why additionalProperties: false and required matter.

A worked example

Here is a schema for a hypothetical sentiment result, validated with the Python jsonschema library (version 4.26):

{
  "type": "object",
  "properties": {
    "label": {"enum": ["pos", "neg", "neu"]},
    "score": {"type": "integer", "minimum": 0, "maximum": 9},
    "note":  {"type": "string", "maxLength": 20}
  },
  "required": ["label", "score"],
  "additionalProperties": false
}

Seven candidate documents give these results:

documentvalidreason when invalid
{"label":"pos","score":7}yes
{"label":"neg","score":9}yes(imagine the input review was glowing)
{"label":"pos"}noscore is required
{"label":"positive","score":7}nonot in the enum
{"label":"pos","score":7.5}nonot an integer
{"label":"pos","score":12}nogreater than maximum 9
{"label":"pos","score":1,"why":"x"}noadditional property not allowed

The second row is the point to hold on to: validation checks the shape of a document, not whether it is true. A document with the wrong label for its input passes as long as the label is in the enum.

What validation does and does not check

Validation can enforce types, presence, allowed values, ranges, and patterns of individual fields. It does not check meaning (is the label right?), consistency across fields beyond what the keywords can express (do the line items sum to the total?), or facts about the outside world (does this customer ID exist?). Those need application code or a separate evaluation.

Use with language models

Providers that offer schema-constrained output (see Constrained Decoding) compile a schema into a restriction on token choice, so that a completed reply conforms. Two cautions apply. Hosted services support a subset of the schema language; documentation from Anthropic, for example, lists numeric bounds and string-length limits among unsupported features, so such constraints must still be checked by the application on that service. And a reply cut off by a token limit, or a refusal, may not conform at all. Validate after generation regardless, and treat a schema as the format contract, not as a correctness check.

Schemas are versioned by “draft” (the example above is valid in recent drafts such as 2020-12), and validator behavior can differ slightly between drafts. The $schema keyword can declare which draft is intended.

References


Discover more from Insightful Data Lab

Subscribe to get the latest posts sent to your email.

Similar Posts

Questions, corrections, or additional insights?

This site uses Akismet to reduce spam. Learn how your comment data is processed.