Type to search pages and rules.

Browse pages

API Compatibility

API compatibility keeps consumers that release on their own schedule working when the API or its published events change, including public, partner, and mobile clients. This page states how a project classifies each contract and event change, versions breaking ones, keeps supported versions alive, and retires them with notice. A team with such consumers applies it, so its consumers keep working across releases instead of breaking on deploy day.

Markdown31 provisions

Stack: any Layer: web-api

Activation#

Activation scope: project.

Applicable specification kinds: None.

The consumer enables compat for public APIs, partner clients, mobile clients, independently deployed consumers, or consumers of its published events. APIs whose consumers always release together with them stay under litespec/backend/api#treat-openapi-as-a-generated-contract. A project whose first deployment holds no customer data yet defers these rules through the stage extension.

Baseline Relationship#

This extension replaces no baseline provision.

Each domain event stays inside the product; each fact consumed outside it is an integration event, as the behavior page states.

This extension switches on no optional record type.

Standards#

Classify Independent-Consumer Changes#

ruleruleguidance
litespec/ext/compat#classify-independent-consumer-changes
Statement

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

Applies toartifact: any

Why

Every contract change reaches consumers the project does not deploy. Classifying each one decides whether consumers need a new version, a review, or nothing at all. An unclassified change ships the decision to consumers as a surprise.

Checka reviewer answers

Reviewed forWhich independent-consumer contract changes lack a classification? Look at the change reviews.

Marked guidance: a reviewer answers this question.

Classify Breaking Contract Changes#

ruleruleguidance
litespec/ext/compat#classify-breaking-contract-changes
Statement

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

Applies toartifact: any

Why

A consumer can depend on any element of the contract: a field it reads, a status it branches on, an authentication scheme it implements. Removing, renaming, narrowing, or retyping any of them breaks the consumer that depended on it. Calling each such change breaking routes it to versioning instead of silent release.

Checka reviewer answers

Reviewed forWhich removed, renamed, narrowed, retyped, or authentication changes lack a breaking verdict? Look at the change reviews.

Marked guidance: a reviewer answers this question.

Treat Removed Behavior Fields as Breaking#

ruleruleguidance
litespec/ext/compat#treat-removed-behavior-fields-as-breaking
Statement

An API change reviewer MUST classify removal of a query output field, a refusal code, or an integration-event payload field as breaking.

Applies toartifact: any

Why

Consumers read query output fields, branch on refusal codes, and parse integration-event payloads, so a removed field breaks every consumer that relied on it while the route stays green. Calling each such removal breaking routes it to versioning and notice instead of silent release.

Checka reviewer answers

Reviewed forWhich removed output fields, refusal codes, or integration-event payload fields lack a breaking verdict? Look at the change reviews.

Marked guidance: a reviewer answers this question.

Classify Compatible Additions#

ruleruleguidance
litespec/ext/compat#classify-compatible-additions
Statement

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

Applies toartifact: any

Why

An optional field, endpoint, or query parameter asks nothing of existing callers: they send and interpret the same values as before. Classifying these as compatible keeps routine growth cheap. Treating them as breaking would version the API for changes nobody has to adopt.

Checka reviewer answers

Reviewed forWhich optional additions lack a record of why existing behavior stays? Look at the change reviews.

Marked guidance: a reviewer answers this question.

Review Exhaustive Consumer Changes#

ruleruleguidance
litespec/ext/compat#review-exhaustive-consumer-changes
Statement

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

Applies toartifact: any

Why

Generated clients often switch exhaustively over enum values and discriminator cases. A new value that the server now sends reaches a client with no branch for it, which rejects a valid response. Consumer review checks that each client handles the new case before it ships.

Checka reviewer answers

Reviewed forWhich added enum values or discriminator cases shipped without consumer review? Look at the consumer reviews.

Marked guidance: a reviewer answers this question.

Preserve Stable Error Codes#

ruleruleguidance
litespec/ext/compat#preserve-stable-error-codes
Statement

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

Applies toartifact: any

Why

Consumers branch on stable Problem Details codes the way they branch on statuses. Removing or reassigning a code breaks that branch while the status stays green. Treating the code as breaking keeps error handling stable across versions.

Checka reviewer answers

Reviewed forWhich removed or reassigned stable codes lack a breaking verdict? Look at the change reviews.

Marked guidance: a reviewer answers this question.

Resolve Uncertain Classifications Safely#

ruleruleguidance
litespec/ext/compat#resolve-uncertain-classifications-safely
Statement

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

Applies toartifact: any

Why

A structural diff cannot prove every change compatible: some changes need a person to judge their effect on consumers. Classifying the unclear ones as breaking routes them to consumer review instead of release. The cost of a needless review is smaller than the cost of a broken consumer.

Checka reviewer answers

Reviewed forWhich unclear changes shipped as compatible without consumer review? Look at the change reviews.

Marked guidance: a reviewer answers this question.

Record Breaking Behavior Changes as Decisions#

ruleruleguidance
litespec/ext/compat#record-breaking-behavior-changes-as-decisions
Statement

After production, a breaking Behavior change MUST travel as a decision naming its consumer impact.

Applies toartifact: record:decision

Why

A breaking change past production breaks promises consumers release against, so the decision states the impact: which consumers break, what they must change, and when the old shape leaves. A developer review alone cannot accept breaking what the product promised.

Checka reviewer answers

Reviewed forWhich breaking Behavior changes past production lack a decision naming their consumer impact? Look at the decisions.

Marked guidance: a reviewer answers this question.

Retain Release Baselines#

ruleruleguidance
litespec/ext/compat#retain-release-baselines
Statement

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

Applies toartifact: any

Why

Each release stores its OpenAPI document as an immutable baseline. Later changes diff against it instead of against memory or a mutable file. Without a retained baseline, the project cannot prove what changed between two releases.

Checka reviewer answers

Reviewed forWhich releases lack a retained OpenAPI baseline? Look at the release artifacts.

Marked guidance: a reviewer answers this question.

Diff Release Contracts#

ruleruleguidance
litespec/ext/compat#diff-release-contracts
Statement

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

Applies toartifact: any

Why

The diff against the supported baseline runs both locally and in continuous integration. The local run catches a breaking change while it is cheap to rework. The CI run catches it when the local run was skipped.

Checka reviewer answers

Reviewed forWhich changes skipped the local or continuous integration diff against the baseline? Look at the local runs and the CI runs.

Marked guidance: a reviewer answers this question.

Reject Breaking Diffs Without Authorization#

ruleruleguidance
litespec/ext/compat#reject-breaking-diffs-without-authorization
Statement

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

Applies toartifact: any

Why

A breaking diff that fails CI stops until a new API version or a recorded consumer decision authorizes it. The failure forces the compatibility decision before release, while versioning is still possible. A warning nobody has to answer authorizes nothing.

Checka reviewer answers

Reviewed forWhich breaking diffs passed without a new version or a recorded decision? Look at the CI runs.

Marked guidance: a reviewer answers this question.

Assign Operation IDs#

ruleruleguidance
litespec/ext/compat#assign-operation-ids
Statement

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

Applies toartifact: endpoint

Why

Generated clients turn each operationId into a method name, and tools use it to reference the operation. A deliberate identifier keeps those names stable and meaningful. An endpoint whose shape an outside specification fixes is exempt, because the project does not own that contract.

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

Reviewed forWhich independent-consumer operations lack a deliberate operationId? Look at the OpenAPI document.

Marked guidance: a reviewer answers this question.

Retain Compatible Operation IDs#

ruleruleguidance
litespec/ext/compat#retain-compatible-operation-ids
Statement

A compatible API change MUST retain the existing operationId.

Applies toartifact: endpoint

Why

A compatible change promises existing consumers keep working. Renaming the operationId breaks that promise for every generated client and every stored operation reference. The identifier stays until a new version takes over.

Checka reviewer answers

Reviewed forWhich compatible changes renamed the operationId? Look at the OpenAPI diff.

Marked guidance: a reviewer answers this question.

Assign Versioned Operation IDs#

ruleruleguidance
litespec/ext/compat#assign-versioned-operation-ids
Statement

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

Applies toartifact: endpoint

Why

The new version needs its own contract names so the retained version keeps its own. A new operationId for each changed operation separates the two. Sharing one identifier across versions would let the new contract rename the old one.

Checka reviewer answers

Reviewed forWhich new versions reuse the operation ID of a changed contract? Look at the versioned OpenAPI documents.

Marked guidance: a reviewer answers this question.

Version Breaking Contracts#

ruleruleguidance
litespec/ext/compat#version-breaking-contracts
Statement

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

Applies toartifact: endpoint

Why

Breaking changes need a boundary: a new route or a documented media-type version. Both contracts then serve at once, and each consumer moves on its own schedule. Without the boundary, one contract serves two incompatible expectations.

Checka reviewer answers

Reviewed forWhich breaking contracts ship without a new route or media-type version? Look at the versioned API surface.

Marked guidance: a reviewer answers this question.

Retain Supported Versions#

ruleruleguidance
litespec/ext/compat#retain-supported-versions
Statement

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

Applies toartifact: any

Why

A consumer the project does not deploy moves on its own release cadence. The declared support window states how long the previous version stays available for that move. Removing it early strands consumers that kept to the published plan.

Checka reviewer answers

Reviewed forWhich previous versions left before their support window? Look at the deployed versions beside the declared window.

Marked guidance: a reviewer answers this question.

Record Version Retirement#

ruleruleguidance
litespec/ext/compat#record-version-retirement
Statement

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

Applies toartifact: record:decision

Why

A removal touches consumers the project does not control, so the decision names each affected consumer, the deadline, and the removal condition. Recording happens before any removal, while the plan can still change. An unrecorded retirement removes first and notifies whoever complains.

Checka reviewer answers

Reviewed forWhich retirements lack affected consumers, a deadline, a removal condition, or recording before removal? Look at the versioning decisions.

Marked guidance: a reviewer answers this question.

Signal Planned Public Removal#

ruleruleguidance
litespec/ext/compat#signal-planned-public-removal
Statement

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

Applies toartifact: endpoint

Why

Consumers discover a planned removal only when the API tells them. A documented deprecation signal, such as Deprecation and Sunset headers, announces the removal on the operation itself. A removal with no signal arrives as an outage to every consumer that missed the release notes.

Checka reviewer answers

Reviewed forWhich operations scheduled for removal lack a deprecation signal? Look at the public operations.

Marked guidance: a reviewer answers this question.

Publish Deprecation Context#

ruleruleguidance
litespec/ext/compat#publish-deprecation-context
Statement

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

Applies toartifact: any

Why

Headers announce the removal on the operation, but consumers plan from release notes. The consumer CHANGELOG.md names each operation scheduled for removal in the one place consumers already read. A deprecation missing from the changelog reaches only the consumers that inspect headers.

Checka reviewer answers

Reviewed forWhich operations scheduled for removal are missing from the consumer changelog? Look at the consumer CHANGELOG.md.

Marked guidance: a reviewer answers this question.

Record Deprecation Conditions#

ruleruleguidance
litespec/ext/compat#record-deprecation-conditions
Statement

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

Applies toartifact: record:decision

Why

A deprecation decision records the sunset date and the replacement operation, so each consumer knows when to move and where to go. Nothing is removed before the decision is recorded. A removal without a recorded replacement strands the consumer that depended on the old operation.

Checka reviewer answers

Reviewed forWhich deprecations lack a sunset date, a replacement, or recording before removal? Look at the deprecation decisions.

Marked guidance: a reviewer answers this question.

Treat Errors as Contracts#

ruleruleguidance
litespec/ext/compat#treat-errors-as-contracts
Statement

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

Applies toartifact: any

Why

Error handling is consumer code: it branches on Problem Details type, code, field-error codes, and documented statuses. Versioning those elements with the contract keeps error handling working across releases. An error shape that changes outside versioning breaks the consumer's failure path, which is the path least tested.

Checka reviewer answers

Reviewed forWhich type, code, field-code, or status changes shipped outside versioning? Look at the versioned error surface.

Marked guidance: a reviewer answers this question.

Gate New Error Outcomes#

ruleruleguidance
litespec/ext/compat#gate-new-error-outcomes
Statement

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

Applies toartifact: any

Why

A new error outcome reaches consumers written before it existed. Adding it only when existing consumers handle an unknown code safely keeps old clients working against the new contract. An outcome old clients cannot parse turns their error path into a crash.

Checka reviewer answers

Reviewed forWhich added error outcomes break existing consumers on unknown codes? Look at the consumer error handling.

Marked guidance: a reviewer answers this question.

Exercise Generated Consumers#

ruleruleguidance
litespec/ext/compat#exercise-generated-consumers
Statement

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

Applies toartifact: test

Why

A structural diff compares documents; it never compiles a client. Testing each first-party generated client against the changed document compiles it and exercises its changed operations. The client's compiler and its exhaustive switches catch the breaks the diff cannot see.

Checka reviewer answers

Reviewed forWhich first-party clients skip compiling or exercising the changed contract? Look at the client test runs.

Marked guidance: a reviewer answers this question.

Declare Published Facts as Integration Events#

ruleruleguidance
litespec/ext/compat#declare-published-facts-as-integration-events
Statement

A fact consumed outside the product MUST be declared as an integration event with its direction, payload, and trust.

Applies toartifact: record:integration-event

Why

A consumer outside the product reads the fact without reading the product's code, so the integration-event record states what the consumer may rely on: the direction, the payload with its classifications, and the trust readers place in it. litespec/core/edges#describe-every-integration-event-for-its-direction states the record. An undeclared fact reaches outside consumers as an implementation detail that changes without notice.

Checka reviewer answers

Reviewed forWhich outside-consumed facts lack an integration-event record with direction, payload, and trust? Look at the integration-event records beside the outside consumers.

Marked guidance: a reviewer answers this question.

Classify Integration Event Changes#

ruleruleguidance
litespec/ext/compat#classify-integration-event-changes
Statement

An API change reviewer MUST classify each integration-event change as breaking, compatible, or needing consumer review under litespec/ext/compat#classify-breaking-contract-changes, litespec/ext/compat#classify-compatible-additions, and litespec/ext/compat#review-exhaustive-consumer-changes.

Applies toartifact: any

Why

An integration event is a contract with consumers the project does not deploy, so its changes need the same verdicts as HTTP contract changes. Reusing the contract classification keeps one meaning of breaking, compatible, and needs-review across both surfaces. A separate event verdict would let one change read as compatible for events and breaking for HTTP.

Checka reviewer answers

Reviewed forWhich integration-event changes lack a breaking, compatible, or needs-review verdict? Look at the event reviews.

Marked guidance: a reviewer answers this question.

Version Breaking Integration Events#

ruleruleguidance
litespec/ext/compat#version-breaking-integration-events
Statement

An API owner MUST carry a breaking integration-event change in a new event version beside the retained version.

Applies toartifact: record:integration-event

Why

Outside consumers move on their own release cadence, so the breaking change ships beside the retained version instead of replacing it. Each consumer moves to the new version on its own schedule. Without the retained version, one event serves two incompatible expectations.

Checka reviewer answers

Reviewed forWhich breaking event changes ship without a new version beside the retained one? Look at the integration event versions.

Marked guidance: a reviewer answers this question.

Retire Integration Events with Notice#

ruleruleguidance
litespec/ext/compat#retire-integration-events-with-notice
Statement

An API owner MUST retire an integration event version only after its declared support window with a deprecation notice to its consumers.

Applies toartifact: any

Why

A retired version strands every consumer still reading it, so the declared support window states how long the version stays available and the notice tells consumers when to move. Retiring early or silently turns a planned removal into an outage for the consumers that kept to the published plan.

Checka reviewer answers

Reviewed forWhich retired event versions left before their support window or without notice? Look at the retirement records beside the event consumers.

Marked guidance: a reviewer answers this question.

Conventions#

Store Current OpenAPI Source#

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

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

ReplacementA consumer records a contract-source convention naming where its current OpenAPI artifact lives.

Applies toartifact: any

Why

Source generation and contract review both need the current OpenAPI artifact. One predictable path keeps generation, review, and the diff reading the same file. A second copy drifts from the first.

Checka reviewer answers

Reviewed forWhich current OpenAPI artifacts live outside the documented path or the recorded local convention? Look at apps/api/openapi/.

Marked guidance: a reviewer answers this question.

Keep Baseline References Immutable#

conventiondefaultguidance
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 baseline convention naming where its immutable baselines live.

Applies toartifact: any

Why

A diff proves nothing when its comparison target can move. Baselines beside their contract owner or under an immutable release reference stay fixed. A mutable baseline lets a breaking change hide by moving the target.

Checka reviewer answers

Reviewed forWhich baselines move, or live outside the recorded local convention? Look at the baseline references.

Marked guidance: a reviewer answers this question.

Use One Diff Tool#

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

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

ReplacementA consumer records a diff-tool convention naming the OpenAPI diff tool its local run and continuous integration share.

Applies toartifact: any

Why

The local run and CI have to agree on what breaking means. One diff tool in both places gives one classification for each change. Two tools disagree on edge cases and teach developers to distrust the check.

Checka reviewer answers

Reviewed forWhich local runs or CI runs use a different diff tool than the recorded local convention? Look at the local runs and the CI runs.

Marked guidance: a reviewer answers this question.

Keep Problem Details Codes Stable#

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

Keep Problem Details error codes stable across compatible versions.

ReplacementA consumer records an error-code convention naming how its Problem Details codes evolve.

Applies toartifact: any

Why

Consumer error handling branches on these codes for years. Keeping them stable across compatible versions lets that handling survive routine releases. A renamed code forces every consumer to update its failure path for no behavior gain.

Checka reviewer answers

Reviewed forWhich Problem Details codes changed across compatible versions, or outside the recorded local convention? Look at the versioned error surface.

Marked guidance: a reviewer answers this question.

Dependencies#

Packages: None. A project that introduces an OpenAPI diff tool pins its version in the manifest.

Related extensions: stage for deferring these rules before first customer data.

Guides: None.