Solving the JSON Schema dialect fragmentation problem with auto-upgrades Sourcemeta has released tooling that automatically upgrades any JSON Schema to the dialect a given tool expects, via the JSON Schema CLI or the Sourcemeta One registry, addressing fragmentation across the standard's many published dialects. JSON Schema has shipped breaking changes across drafts since 2009 — for example, Draft 6 renamed `id` to `$id`, and `$anchor` accepted colons in 2019-09 but no longer does in 2020-12 — while specs such as OpenAPI layer their own extensions on top. Sourcemeta cites a 2025 OpenProceedings paper calling JSON Schema "the de facto standard schema language to describe JSON data" and notes every major AI provider (OpenAI, Google, Anthropic, Mistral, xAI, DeepSeek) and the Model Context Protocol have converged on it, with every EU country required to run eIDAS 2.0 digital identity on it from December 2026. TL;DR: JSON Schema has published many dialects with breaking changes, and specs like OpenAPI add their own extensions and constraints on top. Different tools and schemas sit on different dialects, so using a schema you need or plugging it into a tool you need is often hard or impossible. What you really want is to keep one schema and let every tool receive it in the dialect it understands. Sourcemeta finally makes that possible, upgrading any schema on the fly to the dialect a tool expects, through the JSON Schema CLI or the Sourcemeta One registry. JSON Schema evolves, and evolution brings breaking changes A 2025 OpenProceedings paper calls JSON Schema “the de facto standard schema language to describe JSON data” , with an adoption that is “almost ubiquitous” OpenProceedings, 2025 https://openproceedings.org/2025/conf/edbt/paper-T3.pdf . Today, it is the one schema language every major AI provider OpenAI, Google, Anthropic, Mistral, xAI, DeepSeek has converged on https://www.sourcemeta.com/blog/ai-only-speaks-json-schema/ , and the format the Model Context Protocol speaks. It is what every G7 government runs its digital public infrastructure on https://www.sourcemeta.com/blog/g7-runs-on-json-schema/ , and from December 2026 every EU country must run its eIDAS 2.0 digital identity https://github.com/EWC-consortium/eudi-wallet-rulebooks-and-schemas/tree/main/data-schemas system on it as well. Whatever you are building, you almost certainly depend on JSON Schema, directly or through OpenAPI https://www.sourcemeta.com/blog/json-schema-dominates-openapi/ , MCP, or a cloud service. Like any healthy standard, JSON Schema evolves. Each new version revisits earlier decisions as the community learns more, rather than keeping them forever. That willingness to break backward compatibility is much of what has kept it from accumulating legacy it could never remove. The price is simply that a schema written for one version may no longer be valid, or may quietly mean something different, under another. Some are easy to spot: in Draft 6 the identifier keyword id https://www.learnjsonschema.com/draft4/core/id/ was renamed to $id https://www.learnjsonschema.com/draft6/core/id/ . Others are far more subtle, like how the $anchor https://www.learnjsonschema.com/2020-12/core/anchor/ keyword accepted colons in 2019-09 https://www.learnjsonschema.com/2019-09/core/anchor/ but no longer does in 2020-12 https://www.learnjsonschema.com/2020-12/core/anchor/ . The result is a family of dialects, each with its own set of breaking changes: | Dialect | Year | Breaking changes | |---|---|---| | Draft 0 | 2009 | The first published draft. | | Draft 1 | 2009 | No schema changes an IETF metadata revision . | | Draft 2 | 2010 | maxDecimal replaced by divisibleBy https://www.learnjsonschema.com/draft3/core/divisibleby/ , redefined from decimal places to divisibility. | | Draft 3 | 2010 | optional replaced by required https://www.learnjsonschema.com/draft3/core/required/ with inverted meaning. maximumCanEqual / minimumCanEqual replaced by exclusiveMaximum https://www.learnjsonschema.com/draft3/core/exclusivemaximum/ / exclusiveMinimum https://www.learnjsonschema.com/draft3/core/exclusiveminimum/ . requires renamed to dependencies https://www.learnjsonschema.com/draft3/core/dependencies/ . format https://www.learnjsonschema.com/draft3/core/format/ dropped the address-oriented values street-address , locality , region , postal-code and country . | | Draft 4 | 2013 | required https://www.learnjsonschema.com/draft4/validation/required/ changed from a per-property boolean flag to an array of names. disallow https://www.learnjsonschema.com/draft3/core/disallow/ and extends https://www.learnjsonschema.com/draft3/core/extends/ removed. divisibleBy https://www.learnjsonschema.com/draft3/core/divisibleby/ renamed to multipleOf https://www.learnjsonschema.com/draft4/validation/multipleof/ . type https://www.learnjsonschema.com/draft4/validation/type/ dropped the "any" value and can no longer hold inline subschemas. format https://www.learnjsonschema.com/draft4/validation/format/ was pruned to six values date , time , utc-millisec , regex , color , style and phone removed, with ip-address and host-name renamed to ipv4 and hostname . | | Draft 5 | 2016 | No schema changes a cleanup of Draft 4 that kept its meta-schemas . | | Draft 6 | 2017 | id https://www.learnjsonschema.com/draft4/core/id/ renamed to $id https://www.learnjsonschema.com/draft6/core/id/ . Boolean exclusiveMinimum https://www.learnjsonschema.com/draft6/validation/exclusiveminimum/ / exclusiveMaximum https://www.learnjsonschema.com/draft6/validation/exclusivemaximum/ became numeric. type https://www.learnjsonschema.com/draft6/validation/type/ "integer" now accepts values like 1.0 . | | Draft 7 | 2018 | None. Backward-compatible with Draft 6. | | 2019-09 | 2019 | definitions https://www.learnjsonschema.com/draft7/validation/definitions/ renamed to $defs https://www.learnjsonschema.com/2019-09/core/defs/ . dependencies https://www.learnjsonschema.com/draft7/validation/dependencies/ split into dependentRequired https://www.learnjsonschema.com/2019-09/validation/dependentrequired/ and dependentSchemas https://www.learnjsonschema.com/2019-09/applicator/dependentschemas/ . Plain-name anchors moved from an $id https://www.learnjsonschema.com/2019-09/core/id/ fragment to $anchor https://www.learnjsonschema.com/2019-09/core/anchor/ , and $ref https://www.learnjsonschema.com/2019-09/core/ref/ may now sit beside other keywords. | | 2020-12 | 2020 | Array items https://www.learnjsonschema.com/2019-09/applicator/items/ and additionalItems https://www.learnjsonschema.com/2019-09/applicator/additionalitems/ became prefixItems https://www.learnjsonschema.com/2020-12/applicator/prefixitems/ and items https://www.learnjsonschema.com/2020-12/applicator/items/ . $recursiveRef https://www.learnjsonschema.com/2019-09/core/recursiveref/ / $recursiveAnchor https://www.learnjsonschema.com/2019-09/core/recursiveanchor/ replaced by $dynamicRef https://www.learnjsonschema.com/2020-12/core/dynamicref/ / $dynamicAnchor https://www.learnjsonschema.com/2020-12/core/dynamicanchor/ . contains https://www.learnjsonschema.com/2020-12/applicator/contains/ now marks matched items as evaluated, changing unevaluatedItems https://www.learnjsonschema.com/2020-12/unevaluated/unevaluateditems/ results. $anchor https://www.learnjsonschema.com/2020-12/core/anchor/ dropped the colon from its allowed characters. | And those breaking changes cascade to JSON Schema’s adopters JSON Schema is also a building block for other specifications, which embed it to describe their data. So every breaking change in JSON Schema cascades up into whatever is built on top of it. The clearest example is OpenAPI, which embeds JSON Schema to describe the data in an API. What an OpenAPI document embeds is not a plain upstream dialect but its own variant of JSON Schema, the OpenAPI Schema Object. Each OpenAPI version ties that object to a particular JSON Schema dialect and then extends or restricts it in its own way. OpenAPI has also rebased onto a newer dialect more than once. All of this adds a new dimension to the fragmentation from the previous section: | Version | Year | JSON Schema dialect | |---|---|---| | Swagger 1.2 | 2014 | Reuses JSON Schema Draft 4’s primitive types type plus a format modifier , but its Models and Properties are Swagger’s own objects that each “follows a subset of the JSON-Schema specification” https://github.com/OAI/OpenAPI-Specification/blob/main/versions/1.2.md , with non-standard spellings like defaultValue not default https://www.learnjsonschema.com/draft4/validation/default/ and minimum / maximum given as strings. | | Swagger / OpenAPI 2.0 | 2014 | “a subset of JSON Schema Draft 4” https://spec.openapis.org/oas/v2.0.html with OpenAPI-only additions discriminator , readOnly , xml , externalDocs , example and its own format values int32 , int64 , float , double , byte , binary , password . type https://www.learnjsonschema.com/draft4/validation/type/ must be single-valued, and only allOf https://www.learnjsonschema.com/draft4/validation/allof/ is supported among the logical applicators. | | OpenAPI 3.0.x | 2017 | “an extended subset of the JSON Schema Specification Wright Draft 00” https://spec.openapis.org/oas/v3.0.3.html Draft 4 lineage , adding nullable , discriminator , readOnly , writeOnly , xml , externalDocs , example , deprecated and its own format values int32 , int64 , byte , binary , password . type https://www.learnjsonschema.com/draft4/validation/type/ must be a single string no null , use nullable , and any JSON Schema keyword it does not list is “strictly unsupported” . | | OpenAPI 3.1 | 2021 | “a superset of the JSON Schema Specification Draft 2020-12” https://spec.openapis.org/oas/v3.1.0.html , defining an OpenAPI Schema Object dialect https://spec.openapis.org/oas/3.1/dialect/base whose base vocabulary adds four keywords discriminator https://www.learnjsonschema.com/2020-12/openapi-3.1/discriminator/ , xml https://www.learnjsonschema.com/2020-12/openapi-3.1/xml/ , externalDocs https://www.learnjsonschema.com/2020-12/openapi-3.1/externaldocs/ , and example https://www.learnjsonschema.com/2020-12/openapi-3.1/example/ . | | OpenAPI 3.2 | 2025 | Also a superset of 2020-12 https://spec.openapis.org/oas/v3.2.0.html , with its own base vocabulary https://spec.openapis.org/oas/3.2/dialect/2025-09-17 carrying the same four keywords in revised form. example https://www.learnjsonschema.com/2020-12/openapi-3.2/example/ is now deprecated, and xml https://www.learnjsonschema.com/2020-12/openapi-3.2/xml/ gains a nodeType while deprecating attribute and wrapped . | OpenAPI is not the only one. The Model Context Protocol https://modelcontextprotocol.io , the fast-growing standard that wires AI models to tools and also builds on JSON Schema https://www.sourcemeta.com/blog/ai-only-speaks-json-schema/ to describe a tool’s inputs and outputs, hit the problem from the opposite direction. Where each OpenAPI version pins a dialect and reshapes it, MCP left its embedded tool schemas without a declared dialect at all. Implementations then ended up “split between draft-07 and 2020-12” , until SEP-1613 https://modelcontextprotocol.io/seps/1613-establish-json-schema-2020-12-as-default-dialect-f October 2025 “establishes JSON Schema 2020-12 as the default dialect for embedded schemas within MCP messages” . The flagship API and AI specs are not the only ones to change dialect. For example, format specifications that ship JSON Schemas straight to their users have quietly done the same. glTF https://www.khronos.org/gltf/ , Khronos’s 3D asset format, went from Draft 4 to 2020-12 https://raw.githubusercontent.com/KhronosGroup/glTF/main/specification/2.0/schema/glTF.schema.json in 2021. Docker Compose https://compose-spec.io/ moved from 2019-09 to 2020-12 https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json in 2026. SPDX https://spdx.dev/ , the software bill-of-materials standard, went from Draft 7 to 2020-12 https://raw.githubusercontent.com/spdx/spdx-spec/develop/schemas/spdx-schema-3-0-1.json with its 3.0 line in 2024. And STAC https://stacspec.org/ , the SpatioTemporal Asset Catalog for geospatial data, moved from Draft 6 to Draft 7 https://raw.githubusercontent.com/radiantearth/stac-spec/v0.9.0/catalog-spec/json-schema/catalog.json in 2020. Whole products migrate too: Confluent Schema Registry https://docs.confluent.io/platform/current/schema-registry/index.html , Kafka’s schema registry, added 2020-12 https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/serdes-json.html in Platform 7.6.0 in 2024, and OpenMetadata https://open-metadata.org/ , an open-source metadata platform, moved its entire schema corpus from Draft 7 to 2020-12 in a single 2026 pull request https://github.com/open-metadata/OpenMetadata/pull/33631 touching 1,324 files. How fragmented is it, really? Pinning this down precisely is close to impossible. Most JSON Schema and OpenAPI use lives inside companies, in private repositories and internal services no one outside can measure. What is public is only a slice, so the best we can do is triangulate from a few imperfect proxies. None is exhaustive or representative on its own, and each looks at a different population, so treat what follows as a rough picture, not a census. The useful part is that the proxies disagree on magnitude but agree on the ranking. Live traffic to the official website Start with live traffic. The json-schema.org https://json-schema.org website hosts the meta-schema for each dialect. Its Cloudflare analytics show which of those meta-schemas the world requests most over a trailing 30-day window, and the ranking is telling: Draft 7 https://json-schema.org/draft-07/schema leads by a wide margin, Draft 4 https://json-schema.org/draft-04/schema is a close second, and 2020-12 https://json-schema.org/draft/2020-12/schema only comes third, with Draft 6 https://json-schema.org/draft-06/schema and 2019-09 https://json-schema.org/draft/2019-09/schema far behind. That Draft 4, whose specification was published back in 2013, still outdraws the current dialect is the sharpest sign of how sticky older dialects can be. The first surprise is that Draft 7 leads at all. OpenAPI, the single largest consumer of JSON Schema, never used it. Its 2.0 and 3.0 lines sit on the Draft 4 lineage, and 3.1 and later on 2020-12. Much of Draft 7’s traffic comes down to one library, the Python jsonschema https://github.com/python-jsonschema/jsonschema library’s deprecated https://github.com/python-jsonschema/jsonschema/pull/1049 remote- $ref fetch path, which sends the User-Agent python-jsonschema deprecated $ref resolution . It fetches a schema’s meta-schema over the network on every validation, doing exactly what the specification advises against: “implementations SHOULD NOT assume they should perform a network operation when they encounter a network-addressable URI” https://json-schema.org/draft/2020-12/json-schema-core.html section-8.2.3 . That does not make Draft 7’s lead fake, though. The library only fetches the Draft 7 meta-schema because the schemas people feed it are Draft 7, so the usage is real. The deprecated path just tilts the analytics further in its favour. The other surprise is at the modern end. 2020-12 has been out for nearly six years, and OpenAPI 3.1 adopted it back in February 2021. Yet it is still not the most-requested dialect, and it has barely moved since a 2023 article that inspected the same Cloudflare analytics https://json-schema.org/blog/posts/website-analytics-snapshot-2023 . Some of that gap is measurement, since the modern tools that use 2020-12 are the ones most likely to ship the meta-schemas as built-in copies and validate against those rather than fetch them over the network, so the figures understate it. But the persistence is also the point. That same python-jsonschema traffic was already there in 2023, which means whoever was validating those Draft 7 schemas then is still doing it now, and still has not upgraded. A last quirk we cannot explain is that 2020-12’s core vocabulary meta-schema https://json-schema.org/draft/2020-12/meta/core is requested nearly twice as often as the dialect meta-schema https://json-schema.org/draft/2020-12/schema that references it. What developers publish on GitHub What developers actually declare on GitHub tells a compatible story. Every dialect’s meta-schema lives at a distinct URL, and each version of OpenAPI and AsyncAPI leaves a distinct marker in its documents. So a text search for those strings is a rough headcount of what people publish. The table below runs one such query per row against GitHub’s code search API on September 28th, 2026, and links each one so you can re-run it. This is text matching over the API, not schema parsing. It counts every file containing the string, including generated and vendored copies, which inflates the newest dialects most. GitHub also returns the totals as estimates. So treat the numbers as approximate, good enough as one more proxy, where the ranking matters more than any exact figure. | Specification | Version | Files on GitHub | Searched for | |---|---|---|---| | JSON Schema | Draft 0 | 398 | "json-schema.org/draft-00/schema" https://github.com/search?q=%22json-schema.org%2Fdraft-00%2Fschema%22&type=code | | JSON Schema | Draft 1 | 487 | "json-schema.org/draft-01/schema" https://github.com/search?q=%22json-schema.org%2Fdraft-01%2Fschema%22&type=code | | JSON Schema | Draft 2 | 489 | "json-schema.org/draft-02/schema" https://github.com/search?q=%22json-schema.org%2Fdraft-02%2Fschema%22&type=code | | JSON Schema | Draft 3 | 28,288 | "json-schema.org/draft-03/schema" https://github.com/search?q=%22json-schema.org%2Fdraft-03%2Fschema%22&type=code | | JSON Schema | Draft 4 | 444,416 | "json-schema.org/draft-04/schema" https://github.com/search?q=%22json-schema.org%2Fdraft-04%2Fschema%22&type=code | | JSON Schema | Draft 6 | 194,560 | "json-schema.org/draft-06/schema" https://github.com/search?q=%22json-schema.org%2Fdraft-06%2Fschema%22&type=code | | JSON Schema | Draft 7 | 839,680 | "json-schema.org/draft-07/schema" https://github.com/search?q=%22json-schema.org%2Fdraft-07%2Fschema%22&type=code | | JSON Schema | 2019-09 | 63,744 | "json-schema.org/draft/2019-09/schema" https://github.com/search?q=%22json-schema.org%2Fdraft%2F2019-09%2Fschema%22&type=code | | JSON Schema | 2020-12 | 829,440 | "json-schema.org/draft/2020-12/schema" https://github.com/search?q=%22json-schema.org%2Fdraft%2F2020-12%2Fschema%22&type=code | | OpenAPI | 2.0 Draft 4 lineage | 67,328 | "swagger: \"2.0\"" https://github.com/search?q=%22swagger%3A%20%5C%222.0%5C%22%22&type=code | | OpenAPI | 3.0 Draft 4 subset | 307,200 | "openapi: 3.0" https://github.com/search?q=%22openapi%3A%203.0%22&type=code | | OpenAPI | 3.1 2020-12 | 100,352 | "openapi: 3.1" https://github.com/search?q=%22openapi%3A%203.1%22&type=code | | OpenAPI | 3.2 2020-12 | 1,824 | "openapi": "3.2.0" https://github.com/search?q=%22openapi%22%3A%20%223.2.0%22&type=code | | AsyncAPI | 2.x + 3.0 Draft 7 | 13,088 | "asyncapi: 2" https://github.com/search?q=%22asyncapi%3A%202%22&type=code , "asyncapi: 3" https://github.com/search?q=%22asyncapi%3A%203%22&type=code | Draft 7 leads here too, now by published files rather than by requests. The one real divergence is 2020-12, which ranks higher by file count than by traffic. Even that reflects the measurement bias pulling each way. File counts are inflated by generated and vendored copies, while the traffic figures understate 2020-12 because modern tools ship the meta-schemas as built-in copies instead of fetching them. Draft 4 is the other constant. It no longer leads by raw file count, but its lineage is what most public APIs still run on: OpenAPI 2.0 and 3.0 are both custom Draft 4 dialects, and together they still outnumber the 2020-12-aligned OpenAPI 3.1 by a wide margin, years after 2020-12 shipped. The extremes behave as expected, with the earliest drafts effectively extinct and OpenAPI 3.2, released only in September 2025, barely registering yet. A study from 2020 shows how recent Draft 7’s rise really is. An Empirical Study on the “Usage of Not” in Real-World JSON Schema Documents https://arxiv.org/abs/2107.08677 crawled GitHub in July 2020, removed duplicate copies, and found that across 82,094 files Draft 4 was declared by 78.85% and Draft 7 by only 2.67%, with Draft 6 and Draft 3 in between. That makes sense for the time. 2020-12 was not out yet, and Draft 7 was only two years old. Draft 4 was still the clear default. Our own numbers, where Draft 7 now leads, show how far it has come since 2020. The SchemaStore catalogue One curated catalogue is worth a closer look. SchemaStore https://github.com/SchemaStore/schemastore is a large public collection of JSON schemas for common configuration files. It is created and maintained by Mads Kristensen, a longtime Visual Studio program manager at Microsoft https://www.youtube.com/watch?v=-yYTxLZZk58 . It is also overwhelmingly Draft 7. Of the 977 standalone schemas we analysed on September 28th, 2026, 89.3% declare Draft 7, only 7.4% declare 2020-12, just 1.1% Draft 4, and 1.7% declare no dialect at all. That is the mirror image of the OpenAPI-driven proxies, where Draft 4 and 2020-12 lead and Draft 7 barely featured. The difference is what SchemaStore is for. Visual Studio and Visual Studio Code draw on it for JSON and YAML auto-completion. It lives entirely in the configuration-and-editor world, which has no OpenAPI in it, so Draft 7 dominates. This suggests that much of Draft 7’s lead in the earlier proxies comes from this world rather than from APIs, and it is not a small one. What dialects do real products and specs actually use? So far we have counted schemas. The following table instead takes real adopters of JSON Schema, commercial products, open-source projects, and standards whose published artefact is the schema itself, and groups them by the dialect each one uses. It is not exhaustive, and it reflects what each project’s own documentation or published schemas state at the time of writing. Adopters that support several dialects appear in every row they belong to, so the numbers are row entries, not unique adopters. The pattern is that no single dialect wins. Real, current adopters span four eras at once, from Draft 3 to 2020-12, and every one of them is still a production dependency for someone. Draft 4 and Draft 7 carry the longest tails, especially on the commercial side, while 2019-09 was skipped almost entirely and 2020-12 is the one clearly gaining ground, mostly among newer AI and data products. The split is sharp even inside a single category: among API gateways alone, Kong, AWS API Gateway, Apache APISIX, Gravitee, and Axway validate against Draft 4, NGINX App Protect reaches Draft 7, Zuplo is on 2020-12, and KrakenD supports several at once, so even a task as narrow as validating requests in a gateway has no one-dialect answer. The LLM structured-output APIs are worse still, each accepting its own incompatible subset that is not a clean dialect at all. Where fragmentation bites The fragmentation is not a theoretical worry. It surfaces as a steady stream of GitHub issues, and the same failures show up from one project to the next, often with similar error strings. Here is what it looks like, one trap at a time. The hard reject A tool that supports exactly one dialect does not adapt to a schema written in another. It rejects it outright, before any validation happens, so the mismatch surfaces as a flat refusal rather than a wrong answer. The clearest live example is the Model Context Protocol, where servers built with the MCP TypeScript SDK https://github.com/modelcontextprotocol/typescript-sdk tag their tool schemas as Draft 7 while Claude’s client validates against 2020-12 and nothing else. The schema is discarded before a single request is made, with an error that names the exact problem: Tool ‘