Skip to content
routebase
API Versioning12 chapters

API Versioning: A Complete Guide

What an API version really promises, which versioning methods exist, when you must cut a new one, and when versioning is a cost with no return.

Every API version is a promise you make to somebody else's code, and that single fact explains why versioning feels heavier than it looks. Cutting a version takes an afternoon, while living with two of them for the next three years is the part nobody plans for.

This guide covers the methods, the trade-offs between them, and the decision that comes before all of them. Every chapter stands on its own, so you can read the one that matches your situation and follow the links out from there.

A version is a contract, not a deployment

Teams often use the word version for two different things, and the confusion is expensive.

One meaning is the build you shipped this afternoon, which changes constantly, carries no promise, and is known to nobody outside your team. The other meaning is the shape of the interface your consumers wrote code against, which changes rarely and is felt by people who do not work with you.

Only the second one is an API version. When a team uses the same number for both, every deploy reads as a change of contract to the people watching your changelog, and they soon stop watching it.

A call passes from a consumer through the contract to the service, and the contract lists the fields it pins, one clause for each field the payload carries either side of it. The version names which of those contracts the call is made against, which is why it changes rarely while the build behind the service changes all day.

The question that comes before the method

Most versioning articles start with the carrier, meaning whether the version belongs in the path or in a header. That question matters, and it is not the one that decides your workload.

The decision that decides your workload is whether the change breaks anybody at all. A change that nobody can detect needs no version, no migration and no announcement. A change that breaks one caller needs all three, whatever carrier you picked.

So the order is fixed. First you classify the change, then you look for an additive path, and only if there is none do you reach for a version. The chapter on what counts as a breaking change sets the classification up so a machine can apply it, because a rule two people can disagree about is not a rule.

The map of methods

Five carriers cover essentially every REST API in production, and they differ in routing, in caching and in how visible the version is to the person calling you.

MethodLooks likeSuits
URL path/v1/ordersPublic APIs that want the version obvious in every log line and every support ticket
HeaderApi-Version: 2APIs whose resource identity should not change when the representation does
Query parameter?api-version=2Platforms where callers paste URLs and tooling has to work without custom headers
Media typeAccept: application/vnd.api.v2+jsonTeams that version representations separately from resources
Date-based2026-08-26Products with frequent small contract changes and long-lived customer pins

Two further layers get versioned alongside the API and are commonly confused with it. Your OpenAPI document has its own version field, and your documentation portal has versions that consumers switch between. Neither of them is the version your consumers call.

What versioning costs

The version number is free. Everything behind it is not.

A second live version means a second contract to keep true, a second suite of tests and a second set of documentation pages. It also means a second mock for the frontend team, and a second set of monitors watching a service you were planning to forget. Support answers questions about both, and every new feature is either built twice or held back until the old version finally dies.

That is the case for the chapter most versioning guides leave out, which is when versioning does not matter. It is also why the healthiest APIs cut versions rarely and evolve constantly.

The short answer

If you want one rule to carry away, this is it. Change your API additively for as long as you can, prove that it stayed additive rather than assuming it, and cut a version only when the change has no additive form. When you do cut one, give it a real end date and a migration path, because a version with no sunset is a version forever.

The rest of the guide is that rule taken apart.

ChapterAnswers
Breaking changesWhich changes actually break a consumer, and which only feel dangerous
Versioning strategiesHow the five carriers compare on routing, caching, tooling and visibility
Semantic versioningWhy consumers only ever feel the major, and where date-based numbers fit
When you must versionThe changes and the audiences that leave you no additive option
When it does not matterControlled consumers, pre-release APIs, and the real bill for parallel versions
Backward compatible changeAdditive evolution, tolerant readers, and how to prove compatibility
Running several versionsKeeping docs, mocks, tests and monitors bound to the right version
Deprecation and sunsetPhases, the Deprecation and Sunset headers, and migration that works
Changelogs and migration guidesWhat a consumer needs to read at the moment they discover the change
OpenAPI versioningSpec versions against shipped versions, and what derives from what
Beyond RESTSchema evolution in GraphQL, field numbers in Protobuf, event schemas
Choosing a strategyOne decision path from the change in front of you to the method

In Routebase

Routebase treats a version as the frozen contract it is. A draft stays editable while you work, releasing it freezes an immutable snapshot, and a frozen contract cannot be edited afterwards, so nobody quietly changes what a consumer already integrated against.

The version switcher of a specification, open on a list of three versions with the statuses draft, published and deprecated, and a lock icon on the two frozen ones.
The version switcher groups versions by status, locks the ones that have been released, and carries the compare and publish actions.

From there the rest of the workspace follows the version. Comparing two versions classifies every difference as breaking, safe or a deprecation, so the release conversation starts from a list instead of an argument. Each environment pins one version per specification, and promoting or rolling back moves the pin. The mock server routes by the strategy you configured, documentation portals expose a version switcher to your consumers, and deprecations run as dated plans with reminders and a sunset date.

Start with the Spec Versioning guide in the product documentation, or read on for the decision you are facing. The API design feature page has the short version of how specifications, branches and releases fit together.

Frequently asked questions

What is API versioning?

API versioning is how you let a contract change without breaking the code that already depends on it. You keep serving the old behaviour under one identifier and the new behaviour under another, so consumers move when they are ready instead of when you deploy. The identifier can travel in the path, in a header, in a query parameter or in the media type, and the choice of carrier is a smaller decision than most teams expect.

What are the main API versioning methods?

URL path versioning puts the version in the address, as in /v1/orders. Header versioning carries it in a request header such as Api-Version. Query parameter versioning appends it to the URL. Media type versioning negotiates it through the Accept header. Date-based versioning replaces a counter with a release date, which several large public APIs use. Each one routes and caches differently, and each one is differently visible to the people calling you.

When should you version an API?

Version when a change removes something a consumer relies on, changes the type of something, makes an optional input required, or changes what a value means without changing its shape. Version also when you cannot reach the people calling you, which is the situation on any public API. Everything else usually has an additive path that costs you nothing and costs your consumers nothing.

Is API versioning always necessary?

No. An internal API with a handful of known consumers, a pre-release API with no stability promise, and any change that can be made additively are all cases where a version number buys nothing. Every parallel version has to be operated, tested, documented, mocked and monitored for as long as it lives, so the cheapest version is the one you never cut.

Last reviewed by The Routebase Team.

Chapters in this guide

  1. Chapter 01

    What Counts as a Breaking Change in an API

    The changes that break a live consumer, the ones that only feel dangerous, the asymmetry between request and response, and how to classify them automatically.

  2. Chapter 02

    API Versioning Strategies Compared

    URL path, header, query parameter, media type and date-based versioning, with the routing, caching, tooling and visibility trade-offs of each.

  3. Chapter 03

    Semantic Versioning for APIs

    How SemVer maps onto an HTTP API, why consumers only ever feel the major, what an alias like v1 really is, and where date-based numbering fits instead.

  4. Chapter 04

    When You Must Version an API

    The changes that have no additive path, the consumer situations that leave you no choice, and the semantic breaks that never show up in a diff.

  5. Chapter 05

    When API Versioning Does Not Matter

    The situations where a version number buys nothing, what running parallel versions really costs, and the alternatives that solve the same problem for less.

  6. Chapter 06

    Backward Compatible API Changes

    Additive evolution, the tolerant reader pattern, expand and contract, and how to prove an API stayed compatible instead of assuming it did.

  7. Chapter 07

    Running Multiple API Versions at Once

    What it means for a version to be live in an environment, how routing decides who gets which one, and how docs, mocks and tests stay bound to it.

  8. Chapter 08

    API Deprecation and the Sunset Header

    How to retire an endpoint or a version without ambushing anyone, using the Deprecation and Sunset headers, dated phases and a usable migration guide.

  9. Chapter 09

    API Changelogs and Migration Guides

    What belongs in a changelog entry, how release notes differ from it, and how to write a migration guide that reaches the consumer at the moment they need it.

  10. Chapter 10

    OpenAPI Versioning

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

  11. Chapter 11

    Versioning Beyond REST: GraphQL, gRPC and Events

    Why GraphQL evolves instead of versioning, how Protobuf field numbers make compatibility mechanical, and what a schema registry does for event streams.

  12. Chapter 12

    Choosing an API Versioning Strategy

    One decision path from the change in front of you to the method, with the criteria that actually separate the options and the policy each one needs.

The guide that follows this one is API Monitoring.

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.