// Guide
OpenAPI 3.0 vs 3.1: Key Differences and Compatibility
Compare schema dialects, nullable values and migration risks using a Payments API example.
Separate the document version from the API version
The top-level openapi field identifies the description format. info.version identifies your API's own version. Updating one does not require changing the other. Both 3.0 and 3.1 describe operations under paths, with requestBody and responses organized by media type.
Use the complete Payments API example from the creation guide as a 3.0 starting point. Choose a format supported by your entire pipeline: validators, documentation renderers, generators and consumers of exported contracts.
Understand the schema dialect change
OpenAPI 3.0 uses its own restricted Schema Object. OpenAPI 3.1 aligns its schema vocabulary with JSON Schema 2020-12 and defines an OpenAPI dialect. That enables standard JSON Schema constructs but also means a 3.0 validator is insufficient for a 3.1 schema.
For a nullable payment note, 3.0 uses type: string with nullable: true. In 3.1, include null in the type union. Nullability and optionality are separate: required determines whether the property must be present.
OpenAPI 3.0 schema fragment:
{"type":"object","properties":{"note":{"type":"string","nullable":true}}}
OpenAPI 3.1 schema fragment:
{"type":"object","properties":{"note":{"type":["string","null"]}}}Review numeric bounds and examples explicitly
In a 3.0 schema, minimum: 0 with exclusiveMinimum: true requires a value above zero. In 3.1, exclusiveMinimum itself takes the numeric bound. For integer payment amounts, minimum: 1 is clearer in both versions.
When migrating, review schema keywords and reference behavior rather than replacing the version string alone. Schema examples in 3.1 can use JSON Schema's examples array. Media Type Object examples are a separate mechanism and should be reviewed in their own context.
3.0 positive numeric bound:
{"type":"number","minimum":0,"exclusiveMinimum":true}
3.1 equivalent:
{"type":"number","exclusiveMinimum":0}Migrate one contract through the whole toolchain
Keep the original document. Convert nullable values and version-specific keywords, validate with a matching schema dialect, then compare rendered operations and generated types. Test representative payment payloads against the migrated schemas and actual service.
REST Test imports supported definitions into a normalized model. Do not assume every advanced JSON Schema keyword survives every view or generator. Inspect imports and exported JSON, review warnings and test the downstream tool before adopting a version change.
- Check optional versus null fields.
- Verify internal references and reusable schemas.
- Compare request and response types.
- Keep compatibility tests for existing clients.