Type to search pages and rules.

Browse pages

API Compatibility

OpenAPI freshness proves that committed artifacts match source code.

Markdown25 provisions

Intent#

OpenAPI freshness proves that committed artifacts match source code. It does not prove that independently deployed consumers can continue using the API.

Activation#

Activation scope: project.

Applicable specification kinds: None.

The consumer enables compat for public APIs, partner clients, mobile clients, or independently deployed consumers. Same-release internal APIs retain litespec/backend/api#treat-openapi-as-a-generated-contract. A project in its pre-production stage defers these rules through the stage extension.

Baseline relationship#

This extension replaces no baseline provision.

This extension switches on no optional record type.

Standards#

Classify independent-consumer changes#

ruleguidance
litespec/ext/compat#classify-independent-consumer-changes
Requirement

An API change reviewer MUST classify each contract change that affects an independently deployed consumer.

Why

Classification determines whether consumers need a new contract version, review, or no action.

Checka reviewer answers

Does the reviewer classify each independent-consumer contract change?

Marked guidance: a reviewer answers this question.

Classify breaking contract changes#

ruleguidance
litespec/ext/compat#classify-breaking-contract-changes
Requirement

An API change reviewer MUST classify removal, rename, required input, narrowed value, response, status, or authentication changes as breaking.

Why

Existing consumers can depend on every removed, renamed, narrowed, or retyped contract element.

Checka reviewer answers

Does the reviewer mark each removed, renamed, narrowed, retyped, or authentication change as breaking?

Marked guidance: a reviewer answers this question.

Classify compatible additions#

ruleguidance
litespec/ext/compat#classify-compatible-additions
Requirement

An API change reviewer MUST classify an optional field, endpoint, or query parameter as compatible when existing clients retain behavior.

Why

Optional additions do not require existing callers to send or interpret new values.

Checka reviewer answers

Does the reviewer record why each optional addition preserves existing behavior?

Marked guidance: a reviewer answers this question.

Review exhaustive consumer changes#

ruleguidance
litespec/ext/compat#review-exhaustive-consumer-changes
Requirement

An API change reviewer MUST require consumer review for an added enum value or polymorphic subtype.

Why

Generated exhaustive clients can reject a newly valid enum value or discriminator case.

Checka reviewer answers

Do added enum values and discriminator cases receive consumer review?

Marked guidance: a reviewer answers this question.

Preserve stable error codes#

ruleguidance
litespec/ext/compat#preserve-stable-error-codes
Requirement

An API change reviewer MUST classify removal or reassignment of a stable Problem Details code as breaking.

Why

A consumer can branch on a stable code even when the HTTP status remains unchanged.

Checka reviewer answers

Does the reviewer classify each removed or reassigned stable code as breaking?

Marked guidance: a reviewer answers this question.

Resolve uncertain classifications safely#

ruleguidance
litespec/ext/compat#resolve-uncertain-classifications-safely
Requirement

An API change reviewer MUST classify an unclear contract change as breaking and require consumer review.

Why

A conservative outcome protects consumers when a structural diff cannot prove compatibility.

Checka reviewer answers

Does the reviewer treat each unclear change as breaking with consumer review?

Marked guidance: a reviewer answers this question.

Retain release baselines#

ruleguidance
litespec/ext/compat#retain-release-baselines
Requirement

An API owner MUST store each release OpenAPI document as a retained baseline artifact.

Why

A retained document gives later changes an immutable comparison target.

Checka reviewer answers

Does each release retain its OpenAPI document as an immutable baseline?

Marked guidance: a reviewer answers this question.

Diff release contracts#

ruleguidance
litespec/ext/compat#diff-release-contracts
Requirement

The project MUST compare the current OpenAPI document with the selected supported baseline, both locally and in continuous integration.

Why

The same diff detects structural compatibility changes locally and during continuous integration.

Checka reviewer answers

Do the local run and continuous integration compare against the selected baseline?

Marked guidance: a reviewer answers this question.

Reject unapproved breaking diffs#

ruleguidance
litespec/ext/compat#reject-unapproved-breaking-diffs
Requirement

Continuous integration MUST fail a breaking diff unless a new API version or approved consumer decision authorizes it.

Why

The failure makes a compatibility decision explicit before release.

Checka reviewer answers

Does a breaking diff fail without a new version or an approved decision?

Marked guidance: a reviewer answers this question.

Assign operation IDs#

ruleguidance
litespec/ext/compat#assign-operation-ids
Requirement

Every operation exposed to an independent consumer MUST have a deliberate operationId, except an endpoint whose shape a specification outside the project fixes.

Why

Generated clients and tools use the identifier as an operation-level contract name.

Example

An OAuth redirect endpoint, an OIDC discovery document, a provider webhook receiver, and a well-known resource each carry a shape the other party defines.

Checka reviewer answers

Does each independent-consumer operation carry a deliberate operationId?

Marked guidance: a reviewer answers this question.

Retain compatible operation IDs#

ruleguidance
litespec/ext/compat#retain-compatible-operation-ids
Requirement

A compatible API change MUST retain the existing operationId.

Why

A changed identifier can break generated client names and operation references.

Checka reviewer answers

Does each compatible change retain the existing operationId?

Marked guidance: a reviewer answers this question.

Assign versioned operation IDs#

ruleguidance
litespec/ext/compat#assign-versioned-operation-ids
Requirement

A new API version MUST assign a new operation ID when its operation contract changes.

Why

A new version can own a contract name without mutating the retained version.

Checka reviewer answers

Does a new version assign a new operation ID for each changed contract?

Marked guidance: a reviewer answers this question.

Version breaking contracts#

ruleguidance
litespec/ext/compat#version-breaking-contracts
Requirement

An API owner MUST use a new route or documented media-type version for a breaking contract.

Why

A version boundary lets existing and changed contracts coexist.

Checka reviewer answers

Does each breaking contract use a new route or media-type version?

Marked guidance: a reviewer answers this question.

Retain supported versions#

ruleguidance
litespec/ext/compat#retain-supported-versions
Requirement

An API owner MUST keep the previous version available for its declared support window.

Why

Independently deployed consumers need the published support interval to adopt a changed contract.

Checka reviewer answers

Does the previous version stay available through its support window?

Marked guidance: a reviewer answers this question.

Record version retirement#

ruleguidance
litespec/ext/compat#record-version-retirement
Requirement

A versioning decision MUST name the owner of each affected consumer, the deadline, and the removal condition, with the decision approved before any removal.

Why

Named ownership makes a future removal reviewable rather than implicit.

Checka reviewer answers

Does the versioning decision name its consumer owners, deadline, removal condition, and ownership?

Marked guidance: a reviewer answers this question.

Signal planned public removal#

ruleguidance
litespec/ext/compat#signal-planned-public-removal
Requirement

A public operation scheduled for removal MUST expose a documented deprecation signal.

Why

Deprecation and Sunset headers are examples of observable deprecation signals.

Checka reviewer answers

Does each operation scheduled for removal expose its deprecation signal?

Marked guidance: a reviewer answers this question.

Publish deprecation context#

ruleguidance
litespec/ext/compat#publish-deprecation-context
Requirement

A public operation scheduled for removal MUST appear in the consumer CHANGELOG.md.

Why

The CHANGELOG.md gives consumers one release-note location for planned removal.

Checka reviewer answers

Does the consumer CHANGELOG.md name each operation scheduled for removal?

Marked guidance: a reviewer answers this question.

Record deprecation conditions#

ruleguidance
litespec/ext/compat#record-deprecation-conditions
Requirement

A deprecation decision MUST record the sunset date and replacement operation, with nothing removed while the decision is draft.

Why

Consumers need a fixed end date and a named supported alternative.

Checka reviewer answers

Does the deprecation decision record the sunset date, replacement, and ownership?

Marked guidance: a reviewer answers this question.

Treat errors as contracts#

ruleguidance
litespec/ext/compat#treat-errors-as-contracts
Requirement

An API owner MUST treat Problem Details type, code, field-error codes, and documented statuses as versioned contract elements.

Why

Consumers can branch on error structures as well as successful response structures.

Checka reviewer answers

Does the owner treat type, code, field codes, and statuses as versioned contract elements?

Marked guidance: a reviewer answers this question.

Gate new error outcomes#

ruleguidance
litespec/ext/compat#gate-new-error-outcomes
Requirement

An API owner MUST add an error outcome only when existing consumers safely handle an unknown code.

Why

Safe fallback behavior avoids consumer failure on an unseen outcome.

Checka reviewer answers

Do existing consumers safely handle each added unknown code?

Marked guidance: a reviewer answers this question.

Exercise generated consumers#

ruleguidance
litespec/ext/compat#exercise-generated-consumers
Requirement

An API owner MUST test each first-party generated client against the changed OpenAPI document, with each client compiling and exercising its changed operations.

Why

Generated clients expose exhaustive handling and schema differences that a structural diff can miss.

Checka reviewer answers

Does each first-party client compile and exercise the changed contract?

Marked guidance: a reviewer answers this question.

Conventions#

Store current OpenAPI source#

conventionguidance
litespec/ext/compat#store-current-openapi-source
Default

Store the current source artifact at apps/api/openapi/{ProjectName}.json.

ReplacementA consumer records a departure from this default as an Exception record with reason and review date.

Why

The path gives source generation and contract review one predictable location.

Checka reviewer answers

Is the generated OpenAPI at the documented path or a recorded Exception?

Marked guidance: a reviewer answers this question.

Keep baseline references immutable#

conventionguidance
litespec/ext/compat#keep-baseline-references-immutable
Default

Store each supported baseline beside its contract owner or under an immutable retained-release reference.

ReplacementA consumer records a departure from this default as an Exception record with reason and review date.

Why

Immutable baseline references prevent a diff from comparing against a mutable artifact.

Checka reviewer answers

Are baseline references immutable, or is there a recorded Exception?

Marked guidance: a reviewer answers this question.

Use one diff tool#

conventionguidance
litespec/ext/compat#use-one-diff-tool
Default

Use the same OpenAPI diff tool in local verification and continuous integration.

ReplacementA consumer records a departure from this default as an Exception record with reason and review date.

Why

One classifier avoids differences between local and continuous integration outcomes.

Checka reviewer answers

Do the local run and continuous integration invoke the same diff tool?

Marked guidance: a reviewer answers this question.

Keep Problem Details codes stable#

conventionguidance
litespec/ext/compat#keep-problem-details-codes-stable
Default

Keep Problem Details error codes stable across compatible versions.

ReplacementA consumer records a departure from this default as an Exception record with reason and review date.

Why

A stable code supports consumer error handling over time.

Checka reviewer answers

Do Problem Details codes stay stable across compatible versions?

Marked guidance: a reviewer answers this question.

Dependencies#

The extension adds no required package. An introduced OpenAPI diff tool needs a manifest pin.

Verification#

IDMarkEvidence
litespec/ext/compat#classify-independent-consumer-changesguidanceDoes the reviewer classify each independent-consumer contract change?
litespec/ext/compat#classify-breaking-contract-changesguidanceDoes the reviewer mark each removed, renamed, narrowed, retyped, or authentication change as breaking?
litespec/ext/compat#classify-compatible-additionsguidanceDoes the reviewer record why each optional addition preserves existing behavior?
litespec/ext/compat#review-exhaustive-consumer-changesguidanceDo added enum values and discriminator cases receive consumer review?
litespec/ext/compat#preserve-stable-error-codesguidanceDoes the reviewer classify each removed or reassigned stable code as breaking?
litespec/ext/compat#resolve-uncertain-classifications-safelyguidanceDoes the reviewer treat each unclear change as breaking with consumer review?
litespec/ext/compat#retain-release-baselinesguidanceDoes each release retain its OpenAPI document as an immutable baseline?
litespec/ext/compat#diff-release-contractsguidanceDo the local run and continuous integration compare against the selected baseline?
litespec/ext/compat#reject-unapproved-breaking-diffsguidanceDoes a breaking diff fail without a new version or an approved decision?
litespec/ext/compat#assign-operation-idsguidanceDoes each independent-consumer operation carry a deliberate operationId?
litespec/ext/compat#retain-compatible-operation-idsguidanceDoes each compatible change retain the existing operationId?
litespec/ext/compat#assign-versioned-operation-idsguidanceDoes a new version assign a new operation ID for each changed contract?
litespec/ext/compat#version-breaking-contractsguidanceDoes each breaking contract use a new route or media-type version?
litespec/ext/compat#retain-supported-versionsguidanceDoes the previous version stay available through its support window?
litespec/ext/compat#record-version-retirementguidanceDoes the versioning decision name its consumer owners, deadline, removal condition, and ownership?
litespec/ext/compat#signal-planned-public-removalguidanceDoes each operation scheduled for removal expose its deprecation signal?
litespec/ext/compat#publish-deprecation-contextguidanceDoes the consumer CHANGELOG.md name each operation scheduled for removal?
litespec/ext/compat#record-deprecation-conditionsguidanceDoes the deprecation decision record the sunset date, replacement, and ownership?
litespec/ext/compat#treat-errors-as-contractsguidanceDoes the owner treat type, code, field codes, and statuses as versioned contract elements?
litespec/ext/compat#gate-new-error-outcomesguidanceDo existing consumers safely handle each added unknown code?
litespec/ext/compat#exercise-generated-consumersguidanceDoes each first-party client compile and exercise the changed contract?
litespec/ext/compat#store-current-openapi-sourceguidanceIs the generated OpenAPI at the documented path or a recorded Exception?
litespec/ext/compat#keep-baseline-references-immutableguidanceAre baseline references immutable, or is there a recorded Exception?
litespec/ext/compat#use-one-diff-toolguidanceDo the local run and continuous integration invoke the same diff tool?
litespec/ext/compat#keep-problem-details-codes-stableguidanceDo Problem Details codes stay stable across compatible versions?