In essence, they transform requests from the latest API version back to the (older) versions by writing an adapter for each response for every breaking change. Not sure what they do for new endpoints, or when a future response no longer includes a field that used to be included before.
Some nice things though:
- timeline they suggest seems to be longer than GitHub (implied by the “a power company should not change its voltage every 2 years” statement)
- instead of a header, it’s linked to the account of the user and the time of the first API call. That might be a good default for GH rather than the oldest available version at that time as suggested elsewhere in the comments. (drives adoption, least surprise, longest expected validity of the interface)
Stripe also allows a header to declare the version, which is how you should upgrade (test each endpoint one by one, and when they're all migrated, upgrade the account api version).
I personally find this a much saner way to declare api versions (version in header). Specially if the platform supports Webhooks which have urls in the payload: if your API declares version in the path, which version do you use in the webhooks urls?
The major problem it seems to me with these versioning approaches is that at some point you want a non-breaking change that arrived after a breaking change. Then what?