JSON Schema vs OpenAPI Schema: Key Differences in 2025

JSON schema vs OpenAPI schema differences 2025: Explore how validation and compatibility changed from OpenAPI 3.0 to 3.1 and impact your API tooling.

Jump to section

Jump to section

Jump to section

JSON Schema and OpenAPI Schema look nearly identical but behave differently in ways that break production systems. OpenAPI 3.0 introduced custom keywords like `nullable` that seem convenient but cause validation failures, SDK generation errors, and integration bugs when tools expect standard JSON Schema compliance.

This guide covers the specific differences that trip up engineering teams, why OpenAPI 3.1 fixed the compatibility issues, and how to handle both formats when building APIs, generating SDKs, or integrating with AI systems that demand strict schema adherence.
JSON Schema and OpenAPI Schema are not the same, though they look deceptively similar. OpenAPI 3.0 diverged from the official standard, creating its own flavor of schema that breaks common tooling, while OpenAPI 3.1 realigned with modern JSON Schema. This distinction is critical in 2025, as much of the ecosystem still uses the older, incompatible version, and new AI integrations demand strict, standard schemas. Understanding these differences is key to building robust APIs and avoiding painful, hard-to-debug production failures.

The practical difference for engineers

The core difference between JSON Schema and OpenAPI Schema comes down to their primary goal. JSON Schema is a specification built for one purpose: validating the structure of JSON data, wherever it may be. OpenAPI is a specification for describing an entire REST API, from its endpoints and operations to its authentication methods; the schema part is just one piece of that larger puzzle.

This distinction became a major source of friction with OpenAPI 3.0, which used a custom “extended subset” of an older JSON Schema draft. It introduced non-standard keywords like nullable for convenience, even though it broke compatibility with standard validators. While OpenAPI 3.1 course-corrected by becoming fully compliant with a modern JSON Schema draft, many tools and existing APIs still use the 3.0 standard. Assuming these schemas are interchangeable is a common source of bugs when generating SDKs, validating requests, or integrating with new platforms.

The evolution from subset to superset

The relationship between OpenAPI and JSON Schema has changed over time, leading to the confusion we see today. Understanding this evolution helps clarify why your tools might behave unexpectedly.

Timeline highlights

The journey from a divergent format to a superset was gradual.

  • Swagger 2.0: Used its own schema definition that was inspired by, but not compatible with, JSON Schema.

  • OpenAPI 3.0 (2017): Adopted a modified subset of JSON Schema Draft 5. This was a huge step forward but created the divergence problem by adding custom keywords.

  • OpenAPI 3.1 (2021): Fully embraced the official standard, becoming a true superset of JSON Schema Draft 2020-12. This version is 100% compatible.

At Stainless, we see this timeline play out in real time as we help customers migrate their specifications to generate modern, reliable SDKs.

Why OpenAPI 3.0 diverged

OpenAPI 3.0 diverged from JSON Schema to solve common API documentation needs more simply. The goal was to make the spec easier for humans to write, even if it broke tooling compatibility.

  • nullable: Introduced nullable: true as a simpler way to allow null values, instead of the standard JSON Schema type: ["string","null"].

  • exclusiveMinimum / exclusiveMaximum: Changed from numeric values to booleans, making them easier to toggle but incompatible with JSON Schema validators.

  • example: Used a singular example field, whereas JSON Schema had moved toward a more flexible examples array.

Why OpenAPI 3.1 converged

The divergence in 3.0 caused significant pain for developers and tool builders. The ecosystem was forced to support two slightly different schema dialects, leading to bugs and inconsistencies.

OpenAPI 3.1 fixed this by becoming a superset of JSON Schema Draft 2020-12. It now uses the jsonSchemaDialect field to declare full compatibility. While this solves the problem at the specification level, many code generators and validators have been slow to adopt 3.1, meaning engineers still need to handle both versions. Modern API tooling can often bridge this gap by automatically transforming older 3.0 specs into a 3.1-compatible format during processing.

Keywords that trip teams in 2025

While many keywords are shared, a few key differences between OpenAPI 3.0 and JSON Schema are responsible for most validation and code generation errors. Knowing them can save you hours of debugging.

Keywords that work identically

For the most part, the basic building blocks of your schemas work the same everywhere. You can rely on these keywords to be consistent across both specifications.

Keyword

Purpose

Example

type

Defines the data type (string, number, etc.).

type: "string"

properties

Defines the properties of an object.

properties: { "id": { "type": "integer" } }

items

Defines the schema for items in an array.

items: { "type": "string" }

required

Lists the required properties of an object.

required: ["id","name"]

description

Provides a human-readable description.

description: "The user's unique identifier."

Keywords with altered behavior

These are the most common culprits for “it validates here but breaks there” issues. OpenAPI 3.0 changed their behavior for convenience, but OpenAPI 3.1 reverts them to the JSON Schema standard.

  • nullable: In OpenAPI 3.0, you use nullable: true. In JSON Schema and OpenAPI 3.1, you must use a type array: type: ["string","null"].

  • exclusiveMinimum / exclusiveMaximum: In OpenAPI 3.0, these are booleans (exclusiveMinimum: true). In JSON Schema and OpenAPI 3.1, they are numbers representing the exclusive bound (exclusiveMinimum: 10).

  • type: In OpenAPI 3.0, type can only be a single string. In JSON Schema and OpenAPI 3.1, it can be an array to allow multiple types, e.g., type: ["integer","string"].

Unsupported keywords in OpenAPI 3.0

Some powerful JSON Schema keywords are missing entirely in OpenAPI 3.0, limiting your validation logic. If you need these, migrating to OpenAPI 3.1 is your best option.

  • $schema: Declares which version of JSON Schema is being used.

  • const: Specifies that a value must be a constant.

  • contains: Asserts that an array contains at least one item matching a sub-schema.

  • patternProperties: Defines schemas for properties matching a regex pattern.

Production failures we still see

These schema differences aren’t just theoretical. They cause tangible, frustrating bugs in production systems, especially in automated tooling like SDK generators.

Polymorphic responses

Polymorphism (using oneOf or anyOf) is a frequent source of pain. While valid in both specs, tooling support is inconsistent. An OpenAPI 3.0 linter might approve a schema that a code generator can't process, leading to SDKs with missing types or runtime errors. A robust SDK generator must merge or generate distinct types for these polymorphic schemas to produce reliable code.

Recursive references

Schemas that refer to themselves (e.g., a Category with a parent_category property) create $ref cycles. Some JSON Schema validators handle these gracefully, but many code generators will loop indefinitely and crash. A common solution is to detect and flatten recursion up to a certain depth or to alias types to break the cycle.

File upload schemas

OpenAPI uses format: binary or format: base64 to denote file content, while JSON Schema uses contentMediaType and contentEncoding. This mismatch can lead SDKs to generate incorrect method signatures (expecting strings instead of file streams), breaking file upload functionality.

What MCP servers teach us about schema limits

The rise of AI agents and the Model Context Protocol (MCP) has introduced a new, demanding consumer for our API schemas. MCP servers expose API endpoints as “tools” for LLMs, and each tool’s input schema must be pure JSON Schema. This reveals that even a technically correct schema can fail if it’s too complex for models or incompatible with specific AI client limitations.

When generating an MCP server from an OpenAPI spec, we often transform schemas to work around these limitations (similar to our experience converting complex OpenAPI specs to MCP servers).

  • Client Capability Gaps: Some clients don’t support anyOf at the root; others can’t handle $ref pointers at all.

  • Dynamic Transformation: Servers can inline references or simplify unions based on the connected client’s capabilities.

This new frontier proves that the future of API integration depends on clean, compatible JSON Schema— not the quirks of a specific OpenAPI version.

A playbook for schema compatibility

Navigating the differences between JSON Schema and OpenAPI requires a clear strategy. Here’s a playbook for ensuring your schemas are robust, compatible, and future-proof.

Choosing a spec version today

  • New API: Start with OpenAPI 3.1 for full JSON Schema compatibility from day one.

  • Existing OpenAPI 3.0 API: Plan migration to 3.1 to avoid growing technical debt.

  • Pure data validation: Use standalone JSON Schema for config files or message payloads—no need for full OpenAPI docs.

Migrating from 3.0 to 3.1

  1. Update openapi: 3.0.xopenapi: 3.1.0 and add jsonSchemaDialect: 'https://spec.openapis.org/oas/3.1/dialect/base'.

  2. Replace all nullable: true with type: ["<type>","null"].

  3. Convert exclusiveMinimum/exclusiveMaximum booleans to numeric bounds.

  4. Migrate singular example fields to examples arrays.

Validating and testing

  • Dual validation: Use an OpenAPI linter for contract rules and a strict JSON Schema validator for schema compliance.

  • CI integration: Run both validators on every pull request to catch issues early.

Tooling stack in 2025

Category

Recommended Tool

Supported Spec

SDK Generation

Stainless, Fern

OpenAPI 3.0 & 3.1 (with transforms)

Validation

Spectral, AJV

OpenAPI 3.0 & 3.1, JSON Schema

Documentation

Redocly, Stoplight

OpenAPI 3.0 & 3.1

Linters

Vacuum, Speccy

OpenAPI 3.0 & 3.1

Frequently asked questions about JSON Schema and OpenAPI

Is OpenAPI fully compatible with JSON Schema now?

Yes—OpenAPI 3.1 is a true superset of JSON Schema Draft 2020-12. But many tools and existing specs still use 3.0, so remain aware of the differences.

Should I write pure JSON Schema if I use OpenAPI 3.1?

Yes for non-API data validation (e.g., configs or event payloads). Standalone JSON Schema files are simpler and more direct.

How do schema differences affect SDK generation?

They cause incorrect types, broken validation, and missing models. A quality generator must handle divergences—auto-transforming nullable flags or resolving polymorphic oneOf schemas into usable types.

What breaks when AI agents consume my schemas?

Nested $ref pointers, complex anyOf/oneOf unions, and subtle parsing quirks. Schemas often need dynamic simplification for agent compatibility.

Which spec should a greenfield API choose in 2025?

OpenAPI 3.1—for maximum tool and AI agent compatibility, no migration overhead, and future-proofing.

Ready to build SDKs and MCP servers from your OpenAPI spec without schema headaches? Get started for free.