# OpenAPI 3.0, 3.1 and 3.2 — Routebase

> What changed when 3.1 adopted JSON Schema 2020-12, what 3.2 added on top, and what a document and its tooling actually have to touch on the way up.

Canonical page: https://routebase.dev/guides/openapi/openapi-3-0-3-1-3-2/
Chapter 3 of 10 · OpenAPI · Last reviewed 2026-09-13 · The Routebase Team

Three lines of the specification are in active use, and the jump between the first two is bigger than the version numbers suggest. This chapter covers what actually changed and what an upgrade costs.

## The dates

| Version | Released | What it is |
|---|---|---|
| 3.0.0 | 26 July 2017 | The first release under the OpenAPI name |
| 3.0.4 | 24 October 2024 | The current 3.0 patch, clarifications only |
| 3.1.0 | 15 February 2021 | JSON Schema 2020-12 alignment |
| 3.1.1 | 24 October 2024 | Patch release |
| 3.2.0 | 19 September 2025 | New capabilities on top of the 3.1 model |
| 3.2.1 | 10 September 2026 | The current release |

Patch releases clarify wording rather than change the format, so a 3.0.0 document is still a valid 3.0.4 document and tooling that supports a line supports all of its patches.

## What 3.1 changed

Almost everything worth knowing follows from one decision, which is that the Schema Object became a superset of JSON Schema 2020-12 instead of a modified subset of an old draft.

**Null became a type.** OpenAPI 3.0 defines a `nullable` boolean that only takes effect when `type` is also set, because its schema dialect had no way to say null. In 3.1 you write the type as a list instead.

```yaml
# OpenAPI 3.0
cancelledAt:
  type: string
  format: date-time
  nullable: true
```

```yaml
# OpenAPI 3.1
cancelledAt:
  type: [string, "null"]
  format: date-time
```

**Exclusive bounds became numbers.** The old draft treats `exclusiveMinimum` as a boolean that modifies `minimum`. JSON Schema 2020-12 makes it the bound itself, so `minimum` with a flag becomes one field with a value.

**Every JSON Schema keyword is available.** Keywords such as `const`, `prefixItems`, `patternProperties`, `if` and `unevaluatedProperties` are simply valid, where 3.0 called anything outside its list strictly unsupported. Schemas generated from code no longer have to be trimmed to fit.

**Dialects became explicit.** A document can set `jsonSchemaDialect` to change the default, and an individual schema resource can carry `$schema`, which is what lets a document mix schemas written against another draft.

**Webhooks got a home.** The new `webhooks` field describes incoming calls your consumers may receive, so an API that sends events no longer has to invent a path for them.

**Paths became optional.** A 3.1 document has to contain at least one of `paths`, `components` or `webhooks` rather than always a `paths` object, which is what allows a document that only publishes reusable schemas.

Two smaller additions turn up in almost every real document. The Info Object gained a `summary` field, and the License Object gained an SPDX `identifier` that is mutually exclusive with `url`.

## What 3.2 added

Version 3.2 leaves the schema model alone and extends what a document can describe.

**Methods beyond the fixed list.** A Path Item Object gained `additionalOperations`, a map keyed by the HTTP method as it is sent, for methods the specification does not give a field of its own. The QUERY method gets a named field alongside `get` and `post`, pointing at the IETF draft that defines it.

**A parameter for the whole query string.** Alongside the existing `query` location there is now `querystring`, which treats the entire string as one value described by a media type. That is how a document can finally describe an API that expects JSON or a JSONPath expression in the query string.

**Streaming and sequential media types.** A Media Type Object gained `itemSchema`, which describes each item of a repeating structure such as newline-delimited JSON or a server-sent event stream, rather than pretending the body is a single document.

If you are writing a document today, the question is not whether 3.2 is better but whether the tools you depend on read it. That is the same question as the 3.1 upgrade, one release later.

## What an upgrade actually touches

Converting a document upward is mostly mechanical, and the parts that are not are worth knowing before you start.

The mechanical part is `nullable`, the exclusive bounds, and moving anything that the older dialect could not express into its natural form. Converters handle all of that.

The part that is not mechanical is downstream. A code generator pinned to 3.0 may reject the file or, worse, parse it and quietly ignore keywords it does not know, which produces types that compile and are wrong. A renderer may drop `examples` it cannot place. So the order that works is to check the consumers first, convert second, and regenerate everything once rather than discovering the gap through a client library.

The other thing conversion cannot do is improve the document. Descriptions, examples and error responses that were missing in 3.0 are still missing in 3.1, and those are what decide whether anything generated from the file is worth reading.

## In Routebase

Specifications are authored as OpenAPI 3.0, 3.1 or 3.2, and new ones default to 3.2. Some style-guide rules apply to 3.0 documents only and carry a badge saying so, because a rule about `nullable` has nothing to check in a 3.1 document.

The upgrade shows up where it is most often needed, which is at import. A file that declares 3.0 while using 3.1 keywords fails validation with the offending lines listed, and instead of leaving you to find every occurrence the wizard offers the conversion as one button.

_Screenshot: A document that declares 3.0 and uses 3.1 keywords is a recognisable failure, so the importer names it and offers the upgrade rather than listing the lines and stopping._

The same conversion is available as an import option for any 3.0 file, where it upgrades the nullable syntax and the exclusive bounds to the 3.1 form. The [API Design Settings guide](https://docs.routebase.dev/api-design-settings/) covers choosing the version, and [Import and Export](https://docs.routebase.dev/import-export/) covers the conversion.

## Frequently asked questions

### What is the difference between OpenAPI 3.0 and 3.1?

The schema model. In 3.0 the Schema Object is an extended subset of an old JSON Schema draft, which is why it needs its own nullable keyword and why a few JSON Schema keywords are unsupported. In 3.1 the Schema Object is a superset of JSON Schema 2020-12, so null becomes an ordinary type, exclusiveMinimum becomes a number, and any keyword JSON Schema defines is available.

### How do you express a nullable field in OpenAPI 3.1?

You give the property two types, writing type as a list of the real type and null. The nullable keyword does not exist in 3.1, because JSON Schema 2020-12 already had a way to say it. Converting a 3.0 document means rewriting every nullable true into that list form, which is mechanical and something most converters do for you.

### Is OpenAPI 3.2 out?

Yes. Version 3.2.0 was released on 19 September 2025 and a patch release, 3.2.1, followed on 10 September 2026. It builds on the 3.1 schema model rather than replacing it. What it adds includes the QUERY method, a way to declare operations for methods the specification does not name, a querystring parameter location and support for streaming media types.

### Should I upgrade from OpenAPI 3.0 to 3.1?

Upgrade when your generators support it, since the main gain is that your schemas become ordinary JSON Schema and stop needing translation. The main risk is downstream, because a code generator or a renderer that only understands 3.0 will fail or silently drop what it cannot read. Check the tools you actually run before converting the file everything else depends on.

---

[Routebase](https://routebase.dev/) — [Sign up](https://app.routebase.dev/): Every account starts with a 14-day Pro trial — no credit card required.
