Every change api-contract reports has a kind. Each kind has a default
severity:
breaking fails check by default.
potentially breaking is reported, and fails only with --fail-on
potentially-breaking (or fail_on in the config).
safe is reported and never fails.
The tables below list all 74 kinds (25 breaking, 16 potentially breaking, 33
safe). They are generated from api_contract.rules.DEFAULT_RULES; if this page
and the code ever disagree, the code wins.
Direction: why most schema kinds come in request- / response- pairs¶
A client sends requests and reads responses, and the server does the
opposite. So the same edit to a schema can break clients in one direction and
be harmless in the other:
In a request, the server became stricter if it now needs something
clients may not send: a new required field, a removed enum value, a
maxLength that shrank. Clients that worked before can now be rejected.
Accepting more (a new optional field, a new enum value) is safe.
In a response, the server became less predictable if it may now return
something clients do not expect: a removed field, a field that may be
null, a new enum value a strict client cannot parse. Returning more
(a new field) or less variety (a removed enum value) is safe.
Edit
In a request body
In a response body
Add a required field
breaking
safe
Remove a field
potentially breaking
breaking
Add an enum value
safe
potentially breaking
Remove an enum value
breaking
safe
Become nullable
safe
breaking
Tighten a constraint (maxLength, ...)
potentially breaking
safe
Here is one pair of specs where the same two edits are made on the request and
on the response of POST /echo: a required currency field is added, and
on_hold is added to the status enum.
$ api-contractdiffold.yamlnew.yaml
API contract: 4 changes (1 breaking)BREAKING POST /echo new required request field "currency" id: POST /echo:request:currency:required-request-field-addedPOTENTIALLY BREAKING POST /echo response field "status" enum value added: "on_hold" id: POST /echo:response:200:status:response-enum-value-added:"on_hold"SAFE POST /echo request field "status" enum value added: "on_hold" POST /echo new response field "currency"Fix the change, or acknowledge it: api-contract allow 'POST /echo:request:currency:required-request-field-added' --reason \"...\" --expires 2026-11-24
Each edit appears twice, once per direction, with a different severity: the new
required currency is breaking in the request and safe in the response, and the
new on_hold value is safe in the request and potentially breaking in the
response (a strict client may not know it). That is why the kind names carry
request- or response-, and why a severity override can target one
direction (see Overriding severities).
Kinds with no direction in their name (type-changed, format-changed,
default-changed, ...) have the same severity either way.
Every change has a stable id, printed by check for anything that is not safe:
GET /api/orders/{}/:response:200:total:type-changed
POST /api/orders/:request:currency:required-request-field-added
GET /api/orders/{}/:response:200:status:response-enum-value-added:on_hold
The shape is METHOD path:location:field:kind[:detail]. Path parameters are
positional ({}), so renaming {id} to {order_id} is not a change.
application/json is left out of the location; other media types stay in.
A few details have their own format:
Enum value details are JSON-encoded, so string values are quoted, for
example ...:request-enum-value-removed:"void".
Anonymous oneOf / anyOf variant details are the member's type, or
type#<8-char hash> when that is ambiguous.
A security alternative detail may be scheme[scopes], for example
oauth[read].
Set severities under [tool.api-contract.rules]. A key is either a full kind
or a direction-less alias:
[tool.api-contract.rules]# Exact kind: only the response direction.response-enum-value-added="breaking"# Alias (kind without "request-"/"response-"): both directions.enum-value-added="safe"# Single-kind keys work too.param-removed="safe"
An exact kind beats an alias, so the first two lines above combine as
"response enum additions are breaking, request ones are safe".
Values are breaking, potentially-breaking or safe.
An unknown kind or severity is a configuration error (exit code 2). It is not
ignored.