Lesson 4 of 17
24. APIs and Idempotency

24.3 How do you version an API?

3 min read+10 XP

At the machine: The station installs a new model where prices show in a different format. Old customers who memorised the old buttons would be confused, so the station keeps the old machine running beside the new one for a while, with a sign: "old machine leaving on 1 March".

In the system: Once clients depend on your API, some changes break them:

  • Breaking: removing or renaming a field, changing its type or meaning, making an optional field required, changing error codes. In the chapter's code, v2 changes price from a number (499.0) to an object ({amount: 49900, currency: "INR"}), and a v1 client reading it crashes.
  • Non-breaking: adding a new optional field, a new endpoint, a new optional parameter. Clients that ignore unknown fields keep working.

How to version:

  • In the URL: /v1/books/42, /v2/books/42. Simple and visible; the common choice.
  • In a header: Accept: application/vnd.bookstore.v2+json or a custom API-Version: 2026-10-01 (Stripe uses dated versions pinned per account).
  • For gRPC and events, evolve the schema compatibly: add fields with new numbers, never reuse old ones (Chapter 23).

Rules that save pain:

  • Prefer additive changes; most changes never need a new version.
  • Run old and new side by side, translate old requests to the new internals, and announce a sunset date (there's even a Sunset HTTP header).
  • Measure who still calls v1 before turning it off.

Memory code: "Add freely; to change a button, put in a new machine and keep the old one running."