Skip to content

OpenAPI 3.0 vs 3.1: Which Should You Use?

Choose OpenAPI 3.0 or 3.1 using a toolchain acceptance record. Migrate nullability, examples, references, and webhooks without silently changing the contract.

Use OpenAPI 3.1 when your required tools can preserve the contract features you use. Keep 3.0 when a required gateway, partner importer, validator, or generator cannot process the migrated description correctly. The decision needs evidence from your delivery path, not a claim that one version is always safer.

This comparison uses the published OpenAPI 3.0.4 and 3.1.2 specifications. It addresses the 3.0-to-3.1 decision, not every later OpenAPI release. Changing the document version does not itself change the API's HTTP behavior or enforce its security declarations.

What changes in the schema contract?

ConcernOpenAPI 3.0OpenAPI 3.1Migration check
Schema languageOpenAPI-specific JSON Schema subsetOAS dialect based on JSON Schema 2020-12Check each consumer's dialect support
Null valuesnullable: true with an explicit typeNull can be a type or a union branchPreserve other constraints
Exclusive numeric boundsBoolean beside minimum or maximumNumeric exclusive boundPreserve the boundary value
Schema examplesSingular examplePrefer the examples arrayDo not convert media-type example maps into arrays
Independent outgoing eventsNo top-level webhooks fieldTop-level webhooks availableKeep operation-dependent callbacks distinct

A 3.1 Schema Object can combine $ref with adjacent schema keywords. Do not apply that rule to every Reference Object elsewhere in the document. Reference behavior depends on the object location. Review references structurally instead of performing a global text replacement.

How do you migrate nullable properties?

For a simple string property, these schema fragments express the intended nullable type:

# OpenAPI 3.0 property schema
phone:
  type: string
  nullable: true
# OpenAPI 3.1 property schema
phone:
  type: [string, "null"]

This does not make phone optional. The containing object's required list controls whether the property must exist. As the JSON Schema null reference explains, an absent property and a property containing null are different states.

Use four fixtures: a missing property, explicit null, a valid string, and a wrong-type value. Record the expected result for each before conversion. An enum or composed branch can still exclude null even when the type permits it. Review those constraints together. Do not mechanically add null to every branch of oneOf; overlapping branches can make a value fail its exactly-one-branch rule.

What should your migration procedure record?

  1. Freeze the existing description and all referenced files at one commit. Record each required consumer and its installed version.
  2. List the schema features actually used. Include references, unions, examples, numeric bounds, file bodies, and callbacks. Separate the format migration from unrelated API changes.
  3. Convert a review copy. Preserve operation identifiers, security requirements, and payload semantics unless a separate change explicitly approves them.
  4. Validate the new description. Run positive and negative payload fixtures with a validator that supports the selected schema dialect. A document linter alone does not exercise a running API.
  5. Import the description into each required consumer. Inspect generated types, rendered examples, gateway behavior, and serialization where applicable. Record failures rather than assuming a successful import means complete support.

Keep an acceptance table with consumer, version, feature, expected result, actual result, and owner. Stay on 3.0 if a necessary consumer fails. Assign that limitation a review date. Successful checks for your fixture do not establish universal support for every 3.1 keyword.

Can you publish a 3.0 compatibility copy?

Yes, when its meaning remains adequate for that consumer. Some simple mappings are possible: a nullable single type can use nullable, and const can become a one-value enum. Numeric exclusive bounds need the 3.0 boolean form plus the corresponding bound.

There is no general lossless downgrade for all 3.1 schemas. Modern tuple and unevaluated-property behavior, described in the JSON Schema release notes, needs separate review. Top-level webhooks have no direct 3.0 equivalent. Do not relabel an independent event as a callback merely to make conversion succeed.

Keep the source description authoritative. Generate any compatibility copy, retain a loss report, validate it as 3.0, and compare the accepted payload fixtures. Hold the copy if conversion widens sensitive inputs or drops a required constraint. Finally, compare documented security requirements with server behavior; neither version proves authorization is enforced.

Find the gaps in your access controls

See how an illustrative cross-workspace finding connects evidence, impact and a fix. Discuss the tenant boundaries your team needs reviewed.

Sources

  1. OpenAPI Specification v3.0.4Accessed
  2. OpenAPI Specification v3.1.2Accessed
  3. JSON Schema: nullAccessed
  4. JSON Schema 2020-12 Release NotesAccessed