Skip to content

Backward Compatibility

The Grapity Registry diffs every pushed spec against the previous version. Breaking changes are blocked by default. Safe changes are accepted.

What is a breaking change?

A breaking change is any modification that could cause an existing API consumer to fail.

Blocked (breaking)

ChangeExample
Removing an endpoint or HTTP methodDELETE /v1/accounts/{id} disappears
Removing or renaming a required fielduserId removed from response schema
Changing a field typestringinteger
Adding a new required request fieldBody now requires currency
Narrowing an enumRemoving EUR from currency values

Accepted (safe)

ChangeExample
Adding new optional fields to responsesmetadata added to response
Adding new endpoints or methodsNew PATCH /v1/accounts/{id}
Adding optional request parametersNew optional query param ?include=metadata
Widening an enumAdding CHF to currency values
Improving descriptions or examplesBetter docs, no schema change

How it works

When you run grapity registry push, the Registry:

  1. Parses both the old and new spec
  2. Diff the fully-resolved spec trees
  3. Classifies each delta as breaking or safe
  4. Assigns a semver bump based on the classification

If breaking changes are found and you have not declared an explicit major version, the push is blocked with HTTP 409:

json
{
  "error": "breaking_change",
  "message": "Breaking changes detected. Use force: true with a reason to override, or declare an explicit major version.",
  "statusCode": 409,
  "compatReport": {
    "previousVersion": "1.0.0",
    "classification": "major",
    "breakingChanges": [
      {
        "rule": "response-property-removed",
        "description": "Response property 'userId' was removed from GET /users/{id}",
        "path": "/users/{id}/GET/response/200/userId"
      }
    ],
    "safeChanges": [],
    "suggestedVersion": "2.0.0"
  }
}

Resolving a blocked push

You have two options when a push is blocked:

Option 1: Fix the spec

Restore the removed field, widen the enum, or keep the endpoint. Then push again.

Option 2: Declare an intentional major release

Include an explicit target version in your push:

bash
grapity registry push ./openapi.yaml --name payments-api --version 2.0.0

When the declared version is a major bump and breaking changes are detected, the Registry accepts it as an intentional major release.

Option 3: Force push (emergency only)

bash
grapity registry push ./openapi.yaml --name payments-api --force --reason "security fix CVE-2026-1234"

The force reason is recorded in the audit log. Use this only for true emergencies.

Draft endpoints

Endpoints marked with x-draft: true are exempt from backward compatibility checks. Changes to draft endpoints are always safe. Once an endpoint graduates from draft to stable, it is subject to full compatibility enforcement.

See also

Released under the Apache 2.0 License.