About this template
"We only added a field" — and every client got a 422
Because the field was added to a request body as required. In a response, that exact change would have been perfectly safe.
That asymmetry is where API breakages come from, and a reviewer scanning a spec diff doesn't reliably notice which side they're looking at.
The rule everyone gets backwards
- In a REQUEST: adding a required field breaks existing clients. Removing one, or making it optional, is safe.
- In a RESPONSE: removing a field breaks existing clients. Adding one is safe.
Every finding states which side it's on, first.
Seven breaking changes it detects
- Endpoint removed or path changed — including trailing-slash and casing
- Method removed from an existing path
- Required request field added, or an optional one made required
- Response field removed, or its type narrowed
- Type change anywhere —
string→integer, narrowed enums - Status code removed, or a success code changed
- Auth requirement added to a previously open endpoint
Enum changes come back CONDITIONAL with the condition stated: removing a value breaks everyone; adding one breaks clients that switch exhaustively.
It says who breaks, not just what changed
"A client sending the old request body now gets a 422."
Not "field x changed". A diff line isn't a finding — the consequence sentence is
what makes a reviewer care.
Additive changes get a short list too. Not problems, but the surface grew, and an undocumented addition today is a support ticket later.
And it stops rather than half-parsing
If either spec fails to parse it reports which and stops. A partial parse invents breaking changes, which is worse than no report at all.
If the contract didn't change, it says so in one line. A detector that pads its output is one people stop reading.
What you supply
gh auth login with repo read + PR comment, plus your own Claude Code login. gh
ships at ~/.local/bin/gh.
Point it at a PR touching your spec, or drop before.yaml and after.yaml into
~/apicontract/specs/. OpenAPI 3.x and plain JSON Schema.
Where this stops
It detects and comments when asked. It does not block a PR, set a required status, approve, or merge — whether a breaking change is acceptable is a product decision.
It won't tell you how many clients break (it can't see who calls what), won't claim the spec matches your implementation (it compares spec to spec unless you supply traffic or tests), and gives the semver rule that applies rather than deciding your version bump.
Verified on build: the skill, the working tree, the NEVER_BLOCK_OR_MERGE guard, the
request/response direction rules, all seven checks and a working gh are present on a
fresh fork. Running it on your own spec is yours to do.