Skip to content
routebase
API Versioning12 chapters

Chapter 10 of 12

OpenAPI Versioning

The three different versions an OpenAPI document carries, how spec versions relate to the API consumers call, and where documentation versions fit.

An OpenAPI document carries several things called a version, and they mean different things. Getting them mixed up is the reason a team can have a tidy specification and still ship a surprise to their consumers. The document itself is covered in the OpenAPI guide.

Three versions in one file

The specification version. The openapi field at the root of the document names which version of the OpenAPI Specification the file is written against, such as 3.0.3 or 3.1.0. It tells a parser how to read the file and says nothing about your API.

The document version. The info.version field. The specification is explicit here, defining it as the version of the OpenAPI document and stating that it is distinct from the specification version and from the version of the API being described.

The version your consumers call. The one in the path, the header or the query parameter, decided by your versioning strategy. Nothing in the document enforces a relationship between this and info.version.

Most teams set info.version to their API version, and that is a sensible convention as long as everyone knows it is a convention. The document does not police it, and tooling that assumes it will mislead you eventually.

The three numbers side by side, with where each one lives, what moves it, and whether a consumer ever notices. The specification release and the document version are both bookkeeping about the file, so a caller feels neither of them. Only the third, the one carried in the URL or a header, is a promise somebody wrote code against.

The document is not the API

The gap between the two is where drift lives. A specification says what the service should do, and the service does what it was built to do, and those two statements part company between deploys without anybody noticing.

That makes the version of a document a claim about a service rather than a description of it. Publishing a document as version 2.1 does not make the running service behave like 2.1, which is why contract validation against the live service is what turns the claim into a fact.

Immutability is the property that matters

Whatever you use to store specifications, one behaviour decides whether versioning works, and it is whether a published version can still change.

A draft has to be editable, since that is where the work happens. A published version must not be, because somebody has integrated against it. When a released document can still be edited, consumers integrated against version 2 at different times against different contracts. The number stops meaning anything.

The corollary is that fixing a released version is not a thing you do. You release a new version, or you move whatever pointer decides which version an environment serves, as described in running multiple versions.

One file per version, or one file for all

A document describes one contract, and a major version is a different contract, so one document per major version is the arrangement that causes the fewest problems.

The alternative of a single document covering every version needs conditionals that most generators handle badly, and it makes the diff between two versions unreadable. Splitting by minor version has the opposite problem, since you end up with near-identical files that drift apart in ways nobody intended.

Branches for parallel work

Version control on a specification serves a different purpose than versioning the API. Two people designing two features in the same draft will collide. The answer is the same one code uses, which is a branch per piece of work and a review before it merges.

Reviewing a specification change is where breaking changes get caught cheaply, before anything is released and while the author still remembers why they made it. A merge is not a release. Keeping those two events distinct is what lets design continue while a frozen version keeps serving consumers.

Documentation versions are a third thing

Your documentation portal has versions too, and they are not the same as either of the above.

A documentation version is what a reader switches between, and it usually corresponds to an API version while being published on its own schedule. Exactly one version is normally live, older ones stay readable, and a page can be corrected without the API changing at all. Keeping the two lifecycles separate is what lets you fix a typo in the docs for version 1 without pretending the contract moved.

In Routebase

Specifications support OpenAPI 3.0, 3.1 and 3.2, and every specification is versioned in the workspace itself. A draft stays editable, a released version is frozen into an immutable snapshot, and the designer refuses edits to a frozen version with a banner telling you to create a new one.

The documentation version switcher listing a draft, a published version and three archived ones, with lock icons on the frozen versions.
Documentation versions have their own lifecycle, with exactly one of them live for readers at a time.

Branches and merge requests cover the parallel-work problem. A merge request reports the breaking changes it would introduce before anybody approves it. Every frozen snapshot can be exported as YAML, JSON, Postman or Insomnia, so the contract leaves the workspace in the form the receiving team needs. The Spec Versioning guide covers the lifecycle, Branching covers parallel work, and Doc Versioning covers the portal side.

Frequently asked questions

What does info.version mean in OpenAPI?

The OpenAPI Specification defines info.version as the version of the OpenAPI document, and it states that this is distinct from the OpenAPI Specification version and from the version of the API being described. In practice most teams set it to the API version anyway, which works as long as everyone knows that the field does not enforce that meaning.

What is the difference between the openapi field and info.version?

The openapi field at the root of the document names the version of the OpenAPI Specification the document is written against, such as 3.1.0. The info.version field describes the document itself. One tells a parser how to read the file and the other tells a reader which revision of the description they are looking at.

How do you version an OpenAPI specification?

Keep the document under version control with the code or in a workspace that versions it for you, and freeze a snapshot whenever you release. The important property is immutability, since a published contract that can still be edited is not a contract. Drafts stay editable, releases do not.

Should each API version have its own OpenAPI file?

One document per major version is the common arrangement, because a document describes one contract and a major version is a different contract. Splitting by minor version produces near-identical files that drift apart in small ways, and merging every version into one document produces conditionals that no generator handles well.

Last reviewed by The Routebase Team.

Ready to ship on it?

Routebase is live. Design your API once — docs, mocks, tests, and monitoring all follow from the same source.

14-day Pro trial — no credit card required.