You must make a breaking change to an API used by 200 internal services and 40 external partners. Design the change and the migration.
Show the full answer Hide the answer
First, verify it must break
Many "breaking" changes are avoidable. Adding a field is safe if clients ignore unknown fields — which should be a documented expectation. Widening an accepted range is safe. Only removals, renames, type changes and semantic changes genuinely break.
If a rename is purely cosmetic, do not do it. Compatibility is worth more than naming.
Know exactly who is affected
Per-consumer usage data on every endpoint, field and version. This is the difference between an enforceable deprecation and an aspirational one: it lets you contact the ten affected teams directly rather than broadcasting to 240, and it lets you say honestly that a field has not been read in six months.
If you do not have it, instrument first. Everything else depends on it.
Consumer-driven contracts answer the same question at build time — a field no registered consumer reads can be removed safely; a field one reads cannot. Without them, nothing is ever removed and the API only accretes.
Run both versions
URI versioning (/v2/...) is the pragmatic default: visible in logs, easy to route, easy to
document. Header-based versioning is purer and materially harder to debug.
Run v1 and v2 concurrently. Where the change is narrow, an adapter layer translating v1 requests into v2 internally avoids maintaining two implementations — the usual sustainability problem with versioning.
The migration, differentiated by consumer
Internal (200 services): the platform team can migrate consumers directly rather than asking each team to schedule work. Publish a generated client, migrate in batches, track by usage data. This typically moves 80% quickly.
External (40 partners): a stated support window — commonly 12–24 months for a major version — with notice, migration guides, and a sandbox running v2 so partners can test without ceremony.
The techniques that actually finish it
Deprecation and Sunset headers, so clients detect it programmatically, plus notices in the spec
and generated clients.
Brownouts — brief scheduled outages of v1, announced in advance and lengthening over time. This is the technique that reliably surfaces the remaining users, because the last 5% never respond to email.
A published policy stating the support window, notice period and triggers, agreed before you need it. Negotiating it during a migration guarantees the longest possible timeline.