Semantic versioning (SemVer) gives you a structured, predictable way to communicate API changes to your consumers. Instead of leaving developers to guess whether an update will break their integration, SemVer encodes that information directly into the version number using a MAJOR.MINOR.PATCH format:
- MAJOR: Breaking changes (e.g., removing endpoints or changing response structures).
- MINOR: New backward-compatible features (e.g., adding optional fields or new endpoints).
- PATCH: Backward-compatible bug fixes (e.g., correcting error responses or fixing validation logic).
Why Semantic Versioning Matters for APIs
APIs are contracts between your service and every consumer that depends on it. A poorly communicated change can break downstream applications, erode developer trust, and flood your support channels. SemVer addresses these risks by making every release self-documenting:
- Clear expectations: A version bump from
1.2.3to2.0.0immediately signals that breaking changes are present, while1.2.3to1.3.0tells consumers they can upgrade safely. - Safe dependency management: Consumers can reason about safe upgrade ranges
— any
1.x.yrelease after1.2.0is guaranteed to be backward-compatible, so they can upgrade minor and patch versions with confidence. - Reduced integration friction: Teams can plan their upgrade cycles around major releases rather than treating every update as a potential risk.
- Better collaboration: When your entire organization follows the same versioning scheme, cross-team API consumption becomes far more predictable.
Video: Semantic Versioning Explained
If you prefer a visual walkthrough, the video below covers the core concepts of semantic versioning and how they apply to APIs. You can skip ahead to the API-specific section.
Semantic Versioning Rules
Semantic Versioning (SemVer) ensures a consistent approach to API versioning. The SemVer 2.0.0 specification defines the formal rules, but here is how they apply specifically to APIs.
MAJOR.MINOR.PATCH Breakdown
SemVer uses the MAJOR.MINOR.PATCH format, with each part serving a specific purpose:
- MAJOR (X.y.z): Introduces breaking changes. This could mean removing endpoints, changing response formats, renaming required parameters, or altering authentication methods. These changes require clients to update their integrations.
- MINOR (x.Y.z): Adds new features that are backward-compatible. Examples include introducing new endpoints, adding optional request fields, or expanding response data. Deprecation notices for existing functionality may also fall under this category.
- PATCH (x.y.Z): Fixes bugs without changing the API surface. This includes resolving incorrect response codes, fixing validation logic, or correcting documentation.
Guidelines for Updating Version Numbers
Start with 0.1.0 during initial development and move to 1.0.0 for your first
stable public release. Before 1.0.0, the API is considered unstable and
breaking changes can happen in any release. After 1.0.0, the SemVer rules
apply strictly.
Use pre-release tags (like -alpha.1 or -beta.2) to signal unstable releases
that may not satisfy the intended compatibility requirements. Build metadata
(e.g., +20230421) can encode additional information but does not affect
version precedence.
Here’s when to update each version type:
| Type | Trigger | Examples |
|---|---|---|
| MAJOR (X.0.0) | Breaking changes | Removing endpoints, changing required parameters, altering response structures |
| MINOR (0.X.0) | New features | Adding optional parameters, introducing new endpoints, expanding response data |
| PATCH (0.0.X) | Bug fixes | Fixing error responses, resolving validation issues, updating documentation |
Version Bump Playbook
- Always document changes in a changelog — you can use tools like
Optic or
openapi-changesfor automated API diff detection. - Run comprehensive tests after each version bump to verify that only intended changes shipped and that no breaking changes slipped through.
- Update and notify users about major changes at least 30 days in advance.
- To phase out older versions, provide migration guides, update version-specific documentation, and set clear sunset dates.
SemVer Compared to Other API Versioning Strategies
Semantic versioning is the most widely adopted scheme, but it is not the only option. Understanding the alternatives helps you pick the right approach for your use case.
Date-Based Versioning (CalVer)
Calendar Versioning (CalVer) uses the release date as the
version identifier — for example, 2025-03-16. Stripe is the most prominent API
that uses date-based versioning.
CalVer works well when your API ships frequent, incremental changes and you want
consumers to always pin to a specific point in time. However, it does not encode
the severity of a change the way SemVer does. A consumer looking at
2025-03-16 versus 2025-02-01 has no way to know if the update is
backward-compatible or breaking without reading the changelog.
URI-Only Major Versioning
Many public APIs (Stripe, SendGrid, and GitHub among them) only expose the
major version in the URI path — for example, /v1/users and /v2/users.
Minor and patch changes are deployed in place under the same major version. This
approach is simpler for consumers to understand and keeps URLs stable, but it
still benefits from SemVer internally to track what changed between deployments.
For a deeper comparison of URI path, header, query parameter, and content negotiation versioning methods, see the full guide to API versioning.
Version Management in API Lifecycles
Managing Versions Through Development
When following SemVer rules, you have more flexibility before hitting version
1.0.0. The 0.x.y range is explicitly reserved for rapid iteration — breaking
changes can land in any release. After reaching 1.0.0, the rules tighten: any
breaking change requires a major version bump.
This distinction matters for planning. During initial development you can
iterate quickly on your API design. Once you cut a 1.0.0 release, you are
making a public commitment to
backward compatibility.
Tooling for Version Management
You will typically want to manage different versions of your API with an API management tool — particularly one with OpenAPI and GitOps support so that different API versions map to different branches or files. The benefits of combining OpenAPI with GitOps include automated breaking change detection and synchronized API documentation generated directly from your specification.
You can either use a mix of tools to achieve this (e.g., build your API using
Huma, use GitHub
Actions with openapi-changes for
breaking change detection, and Zudoku for generating API
docs) or use a centralized, OpenAPI-native API gateway like Zuplo which
integrates these pieces together.
Deprecation and Sunset Planning
Versioning does not end at release. Every version you publish becomes a maintenance commitment. A well-defined deprecation strategy ensures you do not end up supporting an ever-growing number of old versions.
A common approach is the N-2 support policy: maintain the current major version plus the two previous ones. When a new major version ships, the oldest supported version enters a sunset period. For detailed guidance on the deprecation lifecycle, see how to sunset an API and deprecating REST APIs.
API Version Implementation Methods
Once you have established versioning principles using SemVer, the next step is to consistently expose those versions to consumers. The most common methods are:
- URI path versioning (
/v1/users) — the simplest and most widely used. Consumers can see the version directly in the URL. - Header-based versioning (
Accept-Version: 1.2.0) — keeps URLs clean and allows more granular version control, aligning well with full SemVer strings. - Content negotiation (
Accept: application/vnd.myapi.v2+json) — the most RESTful approach, but harder to test in browsers and less discoverable.
For SemVer-based versioning where you want to expose the full
MAJOR.MINOR.PATCH string, header-based versioning is the most natural fit
since URLs typically only carry the major version. Check out the
full guide to API versioning for a
detailed comparison of each method.
Practical Checklist for SemVer Implementation
Once you have selected a version-exposure method, you need a clear, enforceable policy that your entire team follows. Here is a practical checklist.
Automation and Testing
- Tag releases automatically: Set up your CI/CD pipeline to tag releases
with semantic version numbers. This keeps your codebase and published API
versions aligned. Tools like
semantic-releasecan automate the entire process based on commit message conventions. - Test backward compatibility: Use automated contract tests to confirm compatibility between versions, especially for MINOR and PATCH updates. This helps catch accidental breaking changes before they reach production. See APIOps for automated version control for more on this workflow.
- Detect breaking changes in CI: Integrate an OpenAPI diff tool into your pull request workflow. When a PR changes your API specification, the tool flags any breaking changes so reviewers can verify the version bump is correct.
Documentation and Communication
- Keep your OpenAPI specification updated with every version change. Include version numbers in your API definitions and ensure documentation reflects the latest updates.
- Publish a changelog for every release. For major versions, include a dedicated migration guide that walks consumers through the required changes.
- Notify consumers of upcoming breaking changes well in advance — at least 30 days, ideally 60 to 90 days for widely-used APIs.
Monitoring
Track adoption across versions so you know when it is safe to sunset an old
release. If a significant portion of traffic still hits v1 months after v2
launched, you may need to do more outreach before deprecating. For strategies on
tracking this, see
monitoring API usage across versions.
Version Management with Zuplo
Zuplo provides built-in tooling that simplifies many of the steps above:
- Git-Based Version Control — Zuplo integrates directly with your Git repository and automatically redeploys your gateway and documentation when you push a change. Every pull request gets its own test environment, so you can verify version changes before they go live.
- OpenAPI-Native Configuration — Zuplo is built around OpenAPI. You can import and manage multiple OpenAPI specifications within the gateway — each one as a file in your repo. To create a new version, clone your existing OpenAPI file, make the changes, bump the version (in the path or by updating the header), and push. Zuplo deploys the new endpoints automatically.
- Autogenerated Developer Portal — The built-in developer portal provides version-specific API reference documentation with an interactive testing playground. It supports Markdown and MDX, so you can publish migration guides and deprecation notices alongside your API reference.
- Programmable Routing — Path-based versioning is supported natively through multiple OpenAPI files. Header-based versioning and more advanced routing logic can be implemented using Zuplo’s TypeScript programmability layer. For a walkthrough, see the versioning on Zuplo documentation.
Frequently Asked Questions
Should I use SemVer or date-based versioning for my API?
SemVer is the better default choice for most APIs because the version number itself communicates the impact of a change. Date-based versioning (CalVer) works well for APIs with very frequent releases where consumers always pin to a specific snapshot, like Stripe. If you are unsure, start with SemVer — it is the industry standard and the most widely understood.
Do I need to expose the full MAJOR.MINOR.PATCH in my API URLs?
No. Most public APIs only include the major version in the URL path (e.g.,
/v2/users) and deploy minor and patch updates in place. You can still track
the full SemVer string internally and expose it through response headers or your
API documentation.
When should I bump the major version?
Bump the major version whenever you introduce a change that could break an existing consumer’s integration. Common triggers include removing an endpoint, changing a required field’s data type, restructuring the response body, or altering authentication requirements. If a consumer using the current version would get errors after your change, it is a major bump.
How do I handle breaking changes during the 0.x development phase?
Before 1.0.0, the API is considered unstable and any release can contain
breaking changes. This is the right time to iterate quickly on your design. Once
you are confident in the API surface, release 1.0.0 to signal stability to
consumers.
How many old versions should I support?
The N-2 policy (current version plus two prior major versions) is a practical starting point. Adjust based on your consumer base — if migration is costly for your users, consider a longer support window. Track version usage to make data-driven sunset decisions.
Start Versioning Your API with SemVer
Semantic versioning’s MAJOR.MINOR.PATCH framework provides a clear, proven structure for managing breaking changes, introducing new features, and addressing bug fixes. By following the rules consistently, you give your API consumers the confidence to upgrade on their own schedule and the information they need to plan for breaking changes.
The key takeaways: automate version bumps and breaking change detection in your
CI/CD pipeline, keep your OpenAPI specifications and documentation in sync, and
plan your deprecation strategy before you ship v1. If you are looking for a
platform that handles versioning, documentation, and deployment in one place,
sign up for a free Zuplo account
and try it out.
