API Architecture and Integration Design · Designing Robust APIs

Versioning and Evolving APIs

Change APIs without breaking clients, and retire old versions gracefully.

Prefer backward-compatible evolution: add optional fields, new endpoints and new enum values (if clients tolerate unknowns). For breaking changes, introduce a new version (/v2, a header, or date-based versions like Stripe), run versions side by side, communicate with Deprecation and Sunset headers plus changelogs, measure remaining usage per client, and remove old versions only after the sunset date.

HTTP/1.1 200 OK
Deprecation: @1767225600
Sunset: Wed, 30 Jun 2027 00:00:00 GMT
Link: <https://developer.example.com/migrate/v2>; rel="deprecation"

Breaking: remove/rename field, change type or meaning, new required input, stricter validation
Usually safe: add optional field/endpoint, add response field, relax validation

Common pitfalls

  • Breaking changes shipped in place.
  • Clients that fail on unknown fields/enum values (tell them to be tolerant readers).
  • Versioning every small additive change.

Key points

  • Evolve compatibly by default
  • Version only for breaking changes
  • Deprecate with headers, data and dates

Further reading: RFC 9745: Deprecation header

Practice questions

Why can adding an enum value be a breaking change?

Answer

Clients with exhaustive switches or strict deserialization may crash on unknown values; document that clients must handle unknown values gracefully.

How do you know when it's safe to remove an old API version?

Answer

Measure usage per client/key, contact remaining consumers, and remove only after the announced sunset date when traffic is near zero.

Open in the app to mark lessons complete, take notes and track your progress.