# jsonschema: JSON Schema validation for Python, from Draft 3 to 2020-12

> The python-jsonschema project validates JSON documents against JSON Schema in Python, with lazy error iteration and programmatic error inspection. It is a validator, not a data model, and that distinction decides when you should reach for it.

**python-jsonschema/jsonschema** — An implementation of the JSON Schema specification for Python

- Repository: https://github.com/python-jsonschema/jsonschema
- Website: https://python-jsonschema.readthedocs.io
- Stars: 4,985 · Forks: 682
- Language: Python
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/python-jsonschema-jsonschema

## What jsonschema solves, and the audience it assumes

JSON Schema is a vocabulary for describing the shape of a JSON document: which keys are allowed, what types their values take, which values are required, and how nested structures relate. The jsonschema package is an implementation of that specification for Python. It answers one question: does this instance satisfy this schema? The README's first example is exactly that, a schema declaring an object with a numeric price and a string name, and a call to validate that either returns silently or raises.

The audience is anyone holding JSON that arrived from somewhere else. Configuration files written by operators, webhook payloads from a third party, records produced by an upstream job you do not control. In all of those cases the schema is the contract and the library is the enforcement point. The project describes itself as Production/Stable in its classifiers, and the supported drafts run from Draft 3 through Draft 2020-12, so schemas written years ago against an older draft are not orphaned.

It is not a serialisation framework. There is no class you subclass to get a typed object back, no field declaration syntax, no automatic conversion of a string to a datetime. The library reads a schema and a value and reports whether the value conforms. Everything after that is your code's problem.

## Lazy validation and the error objects you actually inspect

The mechanism worth understanding is that validation is lazy. The README lists iter_errors as the entry point that can iteratively report all validation errors, as opposed to a boolean check that stops at the first problem. A validator instance is built from a schema, and iter_errors yields error objects one at a time. You can stop consuming the iterator after the first error if you only need to know that something is wrong, or drain it to collect a full report for a user who has to fix several problems at once.

Each error carries enough structure to be acted on programmatically. The README points at programmatic querying of which properties or items failed validation, which is the part that separates this from printing a message. A validation error knows the path through the instance where it occurred and the schema fragment that rejected it, so a caller can map an error back to a form field or a config key rather than showing a wall of text.

The draft support is exposed as separate validator classes, one per draft, named after the specification versions. That matters because drafts disagree with each other: a schema written for Draft 4 does not necessarily mean the same thing under 2020-12, and the library does not guess. You pick the validator that matches the schema you were handed.

## Installing jsonschema and validating your first document

The package is on PyPI and installs with pip. The README gives this as the installation command:

```bash
pip install jsonschema
```

With that in place, the README's own example is the shortest path to a working validation. It builds a schema as a plain dictionary, which is what you get from json.load, and calls validate with an instance and the schema:

```python
from jsonschema import validate

schema = {
    "type" : "object",
    "properties" : {
        "price" : {"type" : "number"},
        "name" : {"type" : "string"},
    },
}

validate(instance={"name" : "Eggs", "price" : 34.99}, schema=schema)
```

The call returns None when the instance is valid. When it is not, the README shows the failure mode directly: passing a price of "Invalid" raises ValidationError with the message that the string is not of type number. If you want every failure instead of the first, build the draft-specific validator and iterate its errors rather than calling validate.

There are two extras, format and format-nongpl, both related to format validation. They are installed by naming the extra, as in pip install jsonschema'[format]'. The README is explicit that installing these dependencies, or even writing format checks into a schema, does not by itself activate format checking. That is a specification behaviour, not an oversight, and it is the single most common source of surprise for new users.

## The format keyword does not check anything until you tell it to

This is the limitation to internalise before you ship. A schema containing a format keyword such as a date or an email address will validate successfully against a value that is obviously not that format, because the specification separates format annotation from format assertion and the library follows it. The README states plainly that the presence of the dependencies or the specification of format checks does not activate them.

Turning format checking on is a deliberate step, described in the format validation documentation rather than the README, and it involves passing a format checker to the validator. If your team assumes that format is enforced because it is written in the schema, you have a validation layer that silently accepts malformed dates and addresses. That is a failure mode with real consequences and it is invisible from the schema alone.

A second boundary: this is a validator, so it cannot tell you that your schema is the one you meant to write. A schema with a permissive type or a missing required list will validate everything you throw at it and report success. The library enforces the contract you wrote, including the parts of the contract you wrote too loosely.

## jsonschema versus pydantic: schema-first or model-first

The comparison people reach for is pydantic, and the difference is where the source of truth lives. With jsonschema, the JSON Schema document is the artefact. It can be stored, versioned, shipped to another service, or consumed by a validator written in a different language, and the Python library is one consumer among several. The schema exists independently of any Python code.

Pydantic inverts that. You declare Python classes with type annotations, and the schema is derived from the model. Validation and the typed object arrive together, which is convenient when the data is staying inside your Python program.

The trade-off is concrete. Pydantic gives you typed objects and less boilerplate; jsonschema gives you a schema that is portable and that matches what a non-Python service will check against. If the same contract has to be enforced by a JavaScript front end and a Python back end, keeping the schema as the shared artefact is the reason to choose jsonschema. If the data never leaves Python and you want attributes rather than dictionaries, pydantic removes work that jsonschema leaves to you.

## Maintenance, releases and what the MIT licence leaves you

The repository is not archived, and the last push was on 2026-09-21, two days before this writing. Releases are infrequent and deliberate: v4.25.0 in July 2025, v4.25.1 in August 2025, and v4.26.0 in January 2026. That cadence suits a library whose behaviour is pinned to a published specification; there is no reason for churn when the drafts are stable.

Upgrade cost is driven by the dependency floor in pyproject.toml rather than by the library's own API. The package requires Python 3.10 or newer and depends on attrs, jsonschema-specifications, referencing and rpds-py. The referencing and rpds-py packages are where schema resolution and the persistent data structures live, so a change in how references resolve surfaces there. If you pin jsonschema, pin those alongside it and read the changelog before moving a major version.

The licence is MIT, declared in pyproject.toml with the COPYING file as the licence text. MIT permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is the extent of what the repository states; whether your distribution model satisfies the notice requirement is a question for your own counsel, not for this article. The README also notes that the project accepts sponsorship through GitHub and TideLift, which says nothing about the licence terms.

## Conclusion

Adopt jsonschema when you have JSON Schema documents to enforce and you want the specification's own error semantics, including lazy reporting of every failure through iter_errors. Do not adopt it expecting a typed data model or automatic code generation; pydantic plays that role and expects you to write Python classes instead. Before committing, verify three things yourself: which draft your schemas declare, whether the format keyword needs to be switched on with a format checker, and whether the CLI you want lives in this package or in the separately installed check-jsonschema. The package requires Python 3.10 or newer and is MIT licensed, so the licence question is settled before you start.

## FAQ

### How do I install jsonschema in Python?

Install it from PyPI with pip install jsonschema. The README also documents two extras, format and format-nongpl, which pull in additional dependencies for format validation and are installed by naming the extra.

### How do I use jsonschema to validate a document?

Import validate from jsonschema, define your schema as a dictionary, and call validate with the instance and the schema. The call returns silently when the instance is valid and raises ValidationError when it is not, as shown in the README example.

### How do I use jsonschema in Python to get all errors at once?

The README describes lazy validation through iter_errors, which can iteratively report all validation errors rather than stopping at the first one. The error objects also support programmatic querying of which properties or items failed.

### What is the difference between jsonschema and pydantic?

jsonschema validates a JSON document against a schema that exists as its own artefact, which can be shared with services written in other languages. Pydantic derives the schema from Python classes you declare, so validation and a typed object come together but the schema is tied to your Python code.

### What is jsonschema used for?

It implements the JSON Schema specification for Python, so you can check whether a JSON instance satisfies a schema describing allowed types, properties and required fields. The README lists full support for Draft 2020-12, 2019-09, 7, 6, 4 and 3.

## Sources

- [License: MIT](https://github.com/python-jsonschema/jsonschema/blob/main/LICENSE)
- [Project website](https://python-jsonschema.readthedocs.io)
- [python-jsonschema/jsonschema on GitHub](https://github.com/python-jsonschema/jsonschema)
- [README](https://github.com/python-jsonschema/jsonschema/blob/main/README.md)
- [Releases](https://github.com/python-jsonschema/jsonschema/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/python-jsonschema-jsonschema
