API breaking change detection: how to catch upstream breakage before it ships
detection 84,125 tracked change records 20 providers
An upstream API breaking change almost never announces itself. Of the 84,125 change records in the mendapi database, 3,227 are breaking or restrictive — and the majority were published as routine release notes, a bumped major version, or a one-line schema edit inside a spec file thousands of lines long. Detection is the problem of turning that stream into a precise answer to one question: which of these will break my code?
The three channels breaking changes arrive through
- Changelogs and release feeds. The cheapest signal and the least reliable one: vendors under-label severity, and the phrase "breaking change" is applied inconsistently. Keyword classification is a starting point, not a verdict.
- SDK releases. A major-version bump in an official SDK is a contract change even when the wire API is untouched — runtime requirements, removed types, renamed parameters. These break your build, not your requests, so wire-level monitoring misses them entirely.
- OpenAPI spec diffs. The most honest channel, because the spec cannot under-report what the changelog forgot to mention. It is also the hardest to read: a single
$refre-anchor can fan out to hundreds of derived diffs, and the changes that break readers — a required field going optional, a type quietly widening — hide in the noise.
A detection system that only watches one channel has a structural blind spot. mendapi ingests all three into one change database and classifies each record with an explainable verdict.
Why default severity gates stay silent
Generic spec-diff tools ship severity levels, and default breaking gates only alert at the top level. That policy is defensible in general and exactly wrong for reader code: a property that goes from required to optional defaults to a warning, yet every consumer that reads the field breaks the day it comes back absent. In a measured comparison on 47 real Stripe spec pairs, 163 real breaking units were invisible to a default breaking gate — 58 because the engine classified them as warnings, 105 because the engine did not complete within a 15-minute timeout on 3 of the pairs. To be precise about the first group: the comparison engine detected those changes and filed them at warning level; it did not miss them. A default gate just never looks there. Full methodology and the honest-citation rules are on the when-to-use page.
Precision is the whole game
The failure mode that kills detection tools is not a miss — it is the false alarm. One wrong "this will break you" and the alerts get muted. mendapi's diff engine currently emits 35 distinct change kinds (parameter removals, type replacements, enum tightenings, required-flag flips, discriminated-union branch changes and more), and every kind is built fail-closed: when the spec evidence is ambiguous — an untyped schema, a plain union without a discriminator — the engine stays silent rather than guessing. Each kind is locked by golden-fixture regression tests with negative controls, so a rule that starts over-firing fails the build before it reaches you.
Measured on real spec corridors
Precision claims are cheap; the honest way to test a detection engine is to run it across long corridors of real, consecutive spec releases and adjudicate every disagreement. mendapi maintains six such corridors (Stripe, PayPal, Twilio, Vercel, Cloudflare, OpenAI), each with archived evidence and drift-recheck gates that re-run in CI. A sample of what the raw diff stream looks like versus what actually breaks client code:
| Corridor | Raw diff volume | Client-breaking outcome |
|---|---|---|
| Stripe, 47 consecutive API versions | 47 spec pairs | 163 adjudicated-real breaking units invisible to a default gate; 0 false positives across all adjudications |
| Cloudflare, 2025-11 to 2026-03 | 7,863 raw diff records | 14 client-breaking removals |
| Cloudflare, 2026-03 to 2026-07 | 6,354 raw diff records | 17 client-breaking removals; 119 raw removals excluded, each with machine-checked survival evidence |
| Vercel SDK, v1.28.13 to v1.28.14 | 136 raw diff records | 12 client-breaking removals |
| OpenAI, 2026-05 to 2026-07 | 821 raw diff records | 3 breaking changes, all transport-level |
Two things this table shows. First, the ratio: on the 2026 Cloudflare corridor, 119 of 136 raw path removals turned out to be spec refactoring — paths consolidated into generic routes, parameters renamed with identical runtime URLs — and every exclusion carries machine-checked survival evidence, so nothing real is silently dropped. A tool that alerted on all 6,354 raw records would be muted within a week. Second, the honest negative: the OpenAI corridor produced 821 diff records and only 3 breaking changes over two and a half months, all at the transport layer. A detection engine that cannot say "almost nothing broke" is not measuring — it is marketing. Each corridor baseline is re-checked against live diff runs (2 OpenAI pairs currently verify record-for-record stable), so the published numbers cannot silently drift from the engine that produced them.
From detection to "does this hit my code"
A feed of upstream changes is trivia until it is joined against your codebase. That join is local and takes about 30 seconds, with no code leaving your machine:
npx mendapi sync # -> one network call: pulls the change feed into a local database npx mendapi scan # -> findings: file, line, provider, confidence mendapi deps --match # -> which tracked upstream changes touch the API surfaces you use
The scanner builds a per-repo dependency map — provider × API surface × location — and matches it against the change database, so an upstream release turns into "you are affected at these lines" instead of a changelog link. For the changes that are mechanically fixable, 47 migration packs draft the fix as a reviewable diff; nothing is applied without your review, and zero network calls is the default and only mode.
Related
- Self-maintaining APIs — what the wider goal means, and the measured split between what a codemod fixes and what it must not.
- When to use mendapi vs generic spec diff tools — the measured comparison in full.
- Stripe payment_records migration — four silent breaking changes in one pattern.
- Agent integration — run detection inside Claude Code or Cursor via MCP.