Versioning and breaking-change detection

OpenAPI · Expert · 12 min

Breaking a published API breaks other people's software; catching it in review is cheap.

Because the document describes the whole contract, you can diff two versions mechanically. Tools like oasdiff compare the base branch document with the proposed one and classify each change.

Breaking for clients (typical list):

  • Removing or renaming a path, operation, parameter, property or enum value in a response.
  • Adding a required request parameter or required request property.
  • Tightening constraints on requests (maxLength smaller, new pattern), or changing types.
  • Making a response property optional or nullable that clients relied on.
  • Changing security requirements or a successful status code.

Usually compatible: adding optional request fields, adding response fields (if clients ignore unknown fields), new operations, new optional parameters. Adding enum values to responses is a grey zone: strict clients and generated enums may break.

Strategy:

  • Run the diff in CI and fail on breaking changes unless explicitly approved.
  • Mark operations, parameters and schema properties deprecated: true, announce a sunset date (the Sunset and Deprecation HTTP headers help), and remove later.
  • Choose a versioning scheme deliberately: URL major versions (/v2), a header, or date-based versions per request (Stripe style). Keep one OpenAPI document per supported version.
  • Keep info.version meaningful and publish a changelog generated from the diffs.

Example

# Diff the PR's document against main and fail on breaking changes
git show origin/main:openapi.yaml > /tmp/base.yaml
oasdiff breaking /tmp/base.yaml openapi.yaml --fail-on ERR
# error [request-parameter-became-required] at openapi.yaml
#   in API GET /books
#     the 'query' request parameter 'genre' became required

# Human-readable changelog between versions
oasdiff changelog /tmp/base.yaml openapi.yaml

# Deprecate before removing
#   /books/{bookId}/legacy-cover:
#     get:
#       deprecated: true
#       description: Use /books/{bookId}/cover. Removed after 2027-01-31.

Remember

  • Diff documents in CI and block unapproved breaking changes
  • Required inputs added or outputs removed are breaking
  • Deprecate with deprecated: true and a sunset date before removal
  • Pick one versioning scheme and keep a document per version

Watch out for

  • Assuming new response enum values are always safe; generated SDK enums may reject them.

Check yourself

  1. Which change is breaking for existing clients?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: learn.openapis.org/best-practices.html