An API Change Is a Product Migration, Not a Release Note

An interface can be redesigned overnight; an API becomes part of another company’s operating system. Once customers automate around a field, status code or timing assumption, a small server change can become a large product incident. The responsible unit of work is not the endpoint release. It is the customer migration.
1. The contract is larger than the schema
A schema describes paths, parameters and payloads, but real integrations also depend on status codes, ordering, nullability, pagination, retries, latency and error language. Before changing anything, write the complete observable contract and ask what a strict client, an old SDK and a delayed webhook consumer can see. A field marked optional may still be treated as always present because production never omitted it. Behaviour creates a contract even when documentation did not intend one. Preserve sanitized real examples and promote them into contract tests so the promise is tested against use, not only a specification file.
2. Classify changes before scheduling them
Use explicit classes: additive, conditionally compatible and breaking. Adding an optional response field is usually additive, yet it can break clients that reject unknown properties. Tightening validation, changing a default or adding an enum value is conditionally compatible. Renaming a field, changing its meaning or removing a state is breaking. The class should be based on observed clients and tests, not the server team’s intuition. Every conditionally compatible change needs a test population, success criteria and a fallback.
3. Give every request a stable identity
A migration is manageable only when the system can distinguish API version, client, operation and outcome. Record a request identifier, authenticated tenant, SDK version, selected contract version, response category and latency without logging sensitive payloads by default. For state-changing operations, support an idempotency strategy so a timeout does not force the customer to choose between losing an action and creating it twice. Observability should answer who still uses the old behaviour, what fails in the new one and which callers lack an accountable owner.
4. Design errors as part of the interface
RFC 9457 defines a machine-readable problem-details format for HTTP APIs. The product lesson is consistency: an error needs a stable type, human summary, request context and structured details that software can act on. Do not silently repurpose an existing code. Separate validation, authorization, conflict, rate-limit and temporary dependency failures. A customer can build a safe retry only when the difference is legible. Documentation should also state whether retry is safe and which input the client must change.
5. Run old and new contracts in parallel
A safe migration creates an overlap period. Route selected customers to the new path, replay non-sensitive fixtures, compare semantic outcomes and expand gradually. Shadow comparison should ignore harmless differences such as timestamps while detecting changed amounts, permissions or state transitions. Keep the old path operational until exit criteria are met. The ability to revert traffic is more useful than a promise that the new version is correct. Test the reversion itself, including the case in which data has already been written in the new form.
6. Deprecation is an adoption programme
A sunset notice is not a plan. Publish the replacement, migration guide, test environment, examples and exact end of support. Notify customers through channels they use, including dashboards and account contacts. Measure active callers rather than guide downloads. Segment abandoned credentials, low-volume integrations, critical enterprise workflows and unknown owners; each needs different treatment. The final date needs a decision owner, an exception policy and a control that prevents a temporary exception from becoming a permanent legacy version.
7. Budget compatibility like reliability
Teams track uptime budgets but often spend compatibility without measuring it. Define how many behavioural changes customers can absorb, how long dual support can run and which clients are too old to protect indefinitely. Review that budget with product, engineering, support, security and commercial owners. Compatibility is not resistance to progress. It is the mechanism that lets progress reach customers without converting automation into operational risk. When the budget is exhausted, choose explicitly between delaying the change, investing in migration tooling or simplifying the target.
8. Define evidence for completion
The migration is complete when traffic, outcomes and support evidence agree. Set thresholds for adoption, error-rate parity, latency, reconciliation differences, unresolved customer cases and rollback readiness. Preserve a decision record explaining why the old version can close. If an issue appears later, the team should reconstruct which contract handled a request and which documentation applied. That is the standard for an API treated as a product rather than a private implementation detail. Dor Arad’s product perspective is to make this a cross-functional decision because the risk lives at the boundary between the company and its customers.