Zuplo
API Versioning

Semantic Versioning for APIs: A Complete Guide to SemVer Best Practices

Adrian MachadoAdrian Machado
April 24, 2025
9 min read

Learn how to apply semantic versioning (SemVer) to your APIs. This guide covers MAJOR.MINOR.PATCH rules, version management, and implementation tips.

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.3 to 2.0.0 immediately signals that breaking changes are present, while 1.2.3 to 1.3.0 tells consumers they can upgrade safely.
  • Safe dependency management: Consumers can reason about safe upgrade ranges — any 1.x.y release after 1.2.0 is 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:

TypeTriggerExamples
MAJOR (X.0.0)Breaking changesRemoving endpoints, changing required parameters, altering response structures
MINOR (0.X.0)New featuresAdding optional parameters, introducing new endpoints, expanding response data
PATCH (0.0.X)Bug fixesFixing error responses, resolving validation issues, updating documentation

Version Bump Playbook

  • Always document changes in a changelog — you can use tools like Optic or openapi-changes for 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-release can 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.