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.