intermediate 2 min answer

A developer platform's users repeatedly build integrations that break on the platform's next release. What communication failure caused this?

supabaseapi-docscompatibilitycontractexpectations
Show the full answer Hide the answer

The failure

The compatibility contract was never stated. Users built against observed behaviour, which includes everything the platform happens to do rather than everything it commits to doing — undocumented fields, incidental ordering, error message text, response timing.

When the platform changes any of those, it has not broken its contract; it has broken an assumption users had no way of knowing was unsafe.

What must be documented explicitly

  • The tolerant-reader contract: unknown fields are ignored, unknown enum values fall to a documented default, field order is not meaningful, additional fields may appear at any time. Stated before the first release, because integrators who never received that instruction write parsers that break on an added field.
  • What is guaranteed and what is incidental. Which fields are stable, which are experimental, which ordering is meaningful, which error codes are part of the contract and which messages are not.
  • The versioning and deprecation policy, with a real notice period.
  • Behaviour under failure: what a timeout means, whether retries are safe, which operations are idempotent. These are contract, and their absence is why integrations behave badly in exactly the conditions that matter.
  • Rate limits and their headers, so a client can pace itself rather than discovering the limit by failing.

The communication channel that actually reaches integrators

In-band, not email. The original developer has left, the account contact is in finance, and the notification goes to an unmonitored address. What works: deprecation headers in every response, warnings in the dashboard the developer uses daily, changelog entries surfaced in the SDK, and — as the final step — brief scheduled brownouts that make a deadline real while it is still reversible.

The artefact that prevents most of it

A machine-readable specification plus a client library you maintain. Most integrators use the SDK, so the SDK's behaviour becomes the de facto contract — which means the tolerant-reader behaviour can be implemented once, correctly, by you, rather than relied upon in thousands of hand-written parsers.

That single decision removes the majority of the breakage class, and it is a documentation problem solved by engineering.