Most CI pipelines test your code. Few of them notice when a dependency’s JSON shape quietly changes — a renamed field in a payments API, a pagination default that jumps from 20 to 25, a null that used to be a string.
Those breaks show up in production dashboards, not unit tests. The fix is not another one-off curl script. It’s treating the live response as a contract you can gate on.
A minimal CI pattern
- Capture a known-good response as a baseline (checked into the repo or stored by a monitor).
- On every PR / deploy, fetch the same endpoint.
- Diff the bodies. Fail the job on breaking changes (removed fields, type changes).
npx --yes @apidiffguard/cli check \
--baseline ./fixtures/users.json \
--url "$API_URL/users" \
--header "Authorization: Bearer $API_TOKEN" \
--schema-only \
--fail-on breakingUnder the hood that’s a JSON compare with severity rules — the same engine behind our free JSON Diff tool and the open-source @apidiffguard/diff package. The CLI ships on npm as @apidiffguard/cli — npx apidiff alone resolves an unrelated package, so use the scoped name.
What counts as breaking?
- Field removed
- Type changed (string → number, object → null)
- HTTP status class change (200 → 4xx/5xx)
Value churn on volatile fields (request_id, timestamps) should be ignored — otherwise every check is noise.
Where hosted monitoring helps
CI catches changes you trigger. Scheduled monitoring catches changes someone else shipped overnight. If your product depends on Stripe, Shopify, or a partner API, you want both.