Versioning interfaces: how to change without breaking
What counts as a breaking change
Removing a field or route, changing a type, making an optional field required, changing the meaning of an existing value, and tightening limits. Adding an optional field doesn't break — as long as consumers ignore fields they don't recognize, which is a rule worth documenting.
How to manage a transition
Run the new version alongside the old, measure who still uses the old, and turn it off only after usage hits zero or you've given enough notice.
Fewer versions with meaningful content beat a version per small change. Every live version is code to maintain and test.
Deprecating gradually
Mark fields and routes as slated for removal in the docs and a response header, with a date. Send a notice to active consumers. And finally, before turning off — run a “controlled darkness”: shut it down for a few minutes and see who shouts.
Going deeper
Keep metrics by version and by consumer, not just by route. Without it, turning off an old version is a gamble, and whoever gets hurt will discover it in their production — that is, in an urgent call that reaches you.