Skip to content

OpenAPI Spec Version Management — Strategies for API Evolution

DodaTech Updated 2026-06-28 6 min read

In this tutorial, you will learn about OpenAPI Spec Version Management. We cover key concepts, practical examples, and best practices to help you master this topic.

OpenAPI version management is the practice of tracking and evolving API specifications using semantic versioning, changelog automation, and multi-version support to maintain backward compatibility for consumers.

What You'll Learn

How to manage OpenAPI specification versions: semantic versioning for APIs, maintaining multiple spec versions, automating changelogs from spec diffs, enforcing breaking change policies, and versioning generated SDKs alongside specs.

Why It Matters

APIs evolve rapidly. Without version management, consumers have no way to know what changed, whether their integration will break, or which version to upgrade to. DodaTech maintains 3 active API versions simultaneously, serving 200+ integration partners without breaking changes.

Real-World Use

DodaTech's Orders API has versions v1, v2, and v3. v1 serves legacy partners, v2 is the current stable version, and v3 is in development. Each version has its own spec file and generated SDKs. The CI pipeline manages all three versions independently.

flowchart LR
    A["spec-v1.yaml"] --> B["v1 SDKs"]
    A --> C["v1 Docs"]
    D["spec-v2.yaml"] --> E["v2 SDKs"]
    D --> F["v2 Docs"]
    G["spec-v3.yaml"] --> H["v3 SDKs"]
    G --> I["v3 Docs"]
    subgraph "Active Versions"
        C
        E
        I
    end
    style D fill:#bbf7d0,stroke:#16a34a
    style G fill:#fef3c7,stroke:#d97706

Semantic Versioning for APIs

# spec-v1.2.3.yaml - Semantic versioning applied to API specs
openapi: 3.0.3
info:
  title: Orders API
  version: 1.2.3
  description: |
    Version 1.2.3 - Added export endpoint (minor change)
    
    Version history:
    - 1.0.0: Initial release
    - 1.1.0: Added pagination support
    - 1.2.0: Added sorting parameters
    - 1.2.1: Fixed limit parameter type
    - 1.2.2: Added optional notes field
    - 1.2.3: Added export endpoint
    
    Breaking changes require a major version bump.
# Version management rules:
versioning_rules = {
    "major": "Breaking changes - consumers must update code",
    "minor": "Backward-compatible additions - new endpoints, optional fields",
    "patch": "Backward-compatible fixes - bug fixes, documentation updates"
}

def should_bump_major(diff_result):
    """Check if diff contains breaking changes."""
    breaking_indicators = [
        "Removed endpoints",
        "Changed required fields",
        "Removed response fields",
        "Changed parameter types",
        "Changed security schemes"
    ]
    for indicator in breaking_indicators:
        if indicator in diff_result:
            return True
    return False

# Example version bump logic:
current_version = "1.2.3"
diff_result = "Breaking: removed DELETE /orders/{id}"

if should_bump_major(diff_result):
    new_version = f"{int(current_version.split('.')[0]) + 1}.0.0"
    print(f"Breaking change detected. Bumping to {new_version}")
else:
    parts = current_version.split(".")
    new_version = f"{parts[0]}.{int(parts[1]) + 1}.0"
    print(f"Non-breaking change. Bumping to {new_version}")

# Expected output:
# Breaking change detected. Bumping to 2.0.0

Multi-Version Spec Management

# Directory structure for multi-version spec management:
# specs/
#   v1/
#     openapi.yaml
#     changelog.md
#   v2/
#     openapi.yaml
#     changelog.md
#   v3/
#     openapi.yaml
#     changelog.md
#   latest -> v2  (symlink to current stable)

# Generate code for a specific version:
openapi-generator generate \
    -i specs/v2/openapi.yaml \
    -g python-fastapi \
    -o gen/v2/python/

echo "Generated v2 Python SDK"
# Expected output:
# Generating for version 2.0.0
# Output: gen/v2/python/

# Generate all active versions:
for version in v1 v2 v3; do
    echo "Generating $version..."
    openapi-generator generate \
        -i specs/$version/openapi.yaml \
        -g python-fastapi \
        -o gen/$version/python/
done
# Expected output:
# Generating v1...
# Generating v2...
# Generating v3...

Automated Changelog Generation

# generate_changelog.py
import subprocess
import datetime

def generate_changelog(old_spec, new_spec, old_version, new_version):
    """Generate version changelog from spec diff."""
    result = subprocess.run(
        ["openapi-diff", old_spec, new_spec, "--format", "markdown"],
        capture_output=True, text=True
    )

    changelog = f"""# Changelog

## {new_version} ({datetime.date.today().isoformat()})

### Changes from {old_version}

{result.stdout}

---

*Generated automatically from OpenAPI spec diff*
"""
    return changelog

# Usage in CI:
changelog = generate_changelog(
    "specs/v1.0.0/openapi.yaml",
    "specs/v2.0.0/openapi.yaml",
    "1.0.0",
    "2.0.0"
)

with open("specs/v2.0.0/changelog.md", "w") as f:
    f.write(changelog)

print(f"Changelog generated for v2.0.0")
# Expected output:
# Changelog generated for v2.0.0
# Written to: specs/v2.0.0/changelog.md

Versioning Generated SDKs

# Package version alignment script:
VERSION=$(grep 'version:' specs/v2/openapi.yaml | head -1 | awk '{print $2}')

# Generate and tag SDKs with spec version:
for gen in python-fastapi typescript-fetch swift5 kotlin; do
    echo "Generating $gen SDK at version $VERSION"
    openapi-generator generate \
        -i specs/v2/openapi.yaml \
        -g $gen \
        -o gen/v2/$gen/ \
        --additional-properties=packageVersion=$VERSION

    cd gen/v2/$gen/

    if [ -f package.json ]; then
        npm version $VERSION --no-git-tag-version
    elif [ -f setup.py ]; then
        sed -i "s/version=.*/version='$VERSION',/" setup.py
    fi

    cd ../../..
done

echo "All SDKs tagged with version $VERSION"
# Expected output:
# Generating python-fastapi SDK at version 2.0.0
# Generating typescript-fetch SDK at version 2.0.0
# All SDKs tagged with version 2.0.0

Common Mistakes

1. Not Documenting Deprecation Timeline

Removing an endpoint without warning breaks consumers. Deprecate first with a sunset header, keep the endpoint for at least one major version cycle, then remove. Document deprecation dates in the spec description.

2. Mixing Multiple Versions in One Spec File

Each API version should have its own spec file. Mixing versions leads to confusion, accidental breaking changes, and difficulty maintaining backward compatibility. Use separate files and directories.

3. Ignoring Internal Version vs Published Version

The spec's info.version is the API version, not the build number. Internal build numbers (CI pipeline IDs, git hashes) are different from the published API version. Keep them separate.

4. Not Maintaining a Changelog

A missing changelog forces consumers to compare specs manually. Generate changelogs from diff output during release. Publish changelogs alongside SDK packages.

5. Deleting Old Versions Prematurely

Even deprecated API versions need maintenance (security patches, bug fixes). Keep spec files for all released versions. Archive old versions in a separate directory rather than deleting them.

Practice Questions

  1. What does a major version bump indicate in API Versioning?
  2. How do you maintain multiple API versions simultaneously?
  3. What information should a changelog include?
  4. Why should deprecated endpoints remain available for a transition period?

Answers:

  1. A major version bump indicates breaking changes that require consumers to modify their integration code. Examples include removing endpoints, changing required fields, or altering response structures.
  2. Maintain separate spec files for each version in version-specific directories (specs/v1/, specs/v2/). Generate and publish SDKs for each version independently. Use the latest symlink for the current stable version.
  3. A changelog should include the version number, release date, a list of changes from the previous version organized by type (breaking, non-breaking, fixes), and links to the updated spec file.
  4. Deprecated endpoints need a transition period to give consumers time to migrate. Immediate removal breaks integrations. A standard practice is deprecate in version N, remove in version N+2.

Challenge: Set up a multi-version API management system with three active spec versions, automated changelog generation from spec diffs, version-aligned SDK packages published to npm/PyPI, and a deprecation policy documented in the spec.

FAQ

Should the spec version match the API implementation version?

Yes. The spec version should match the API version it describes. This ensures consumers can correlate the spec with the running API implementation.

How long should old API versions be supported?

A common practice is 12-18 months after deprecation notice. Enterprise APIs often support 3-5 years. Document your support policy in the API documentation.

Can I use git tags for version management?

Yes. Tag spec releases with the API version (v1.0.0, v2.0.0). Git tags provide a clear version history and make it easy to checkout and regenerate SDKs for any released version.

What is the difference between API versioning and SDK versioning?

API versioning tracks the server contract version. SDK versioning tracks the client library version. They should be aligned but may differ when SDKs have bug fixes or new features that don't change the API contract.

How do I handle pre-release versions?

Use pre-release suffixes like 2.0.0-alpha.1, 2.0.0-beta.1, 2.0.0-rc.1. Pre-release versions are excluded from production CI/CD but can be published to test registries or staging environments.

Mini Project

Create three versions of an API spec (v1, v2, v3) with progressively more features, set up an automated changelog generator that compares adjacent versions, create version-aligned SDK generation scripts, and implement a deprecation notice for v1 endpoints removed in v3.

What's Next

Complete Project — build a complete Code Generation system with CI/CD and version management.

OpenAPI Diff — compare API specifications and detect breaking changes.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro