Versioning Checklist
A practical guide for assessing changes to APIs and events — how to distinguish breaking from non-breaking changes and what to verify before deploying.
Why a checklist?
Every time you modify an API or an event schema, you need to assess the impact of the change. This checklist helps you classify changes, identify risks, and take the right actions before the change reaches production.
Classifying changes
Non-breaking changes (safe)
These changes are backward compatible and can generally be deployed without coordination:
- ✅ Adding a new optional field to an API response
- ✅ Adding a new endpoint
- ✅ Adding a new optional query parameter
- ✅ Adding a new optional field to an event (with a default)
- ✅ Adding a new event type
- ✅ Expanding documentation or descriptions
- ✅ Improving error messages without changing status codes
- ✅ Adding new status codes for cases that weren’t covered before
Breaking changes (require coordination)
These changes break existing consumers and require a migration strategy:
- ❌ Removing a field from an API response
- ❌ Renaming an existing field
- ❌ Changing a field’s type (string → number, object → array)
- ❌ Making a previously optional field required
- ❌ Removing an endpoint
- ❌ Changing an endpoint’s URL
- ❌ Removing a field from an event
- ❌ Changing the semantics of an existing field
- ❌ Reducing the accepted values in an enum
- ❌ Changing HTTP status codes for existing cases
Gray-area changes (evaluate case by case)
These changes may or may not be breaking depending on context:
- ⚠️ Adding a new value to an enum — breaking if consumers do an exhaustive switch
- ⚠️ Changing an optional field to required in a request — breaking for consumers that weren’t sending it
- ⚠️ Adding stricter validation — breaking for consumers that were sending previously accepted data
- ⚠️ Changing the order of fields in a response — breaking if some consumer depends on the order
Checklist for API changes
Before deploying a change to an API, check each of these points:
1. Impact analysis
- Have you identified all consumers of this endpoint?
- Have you reviewed the contract tests (if any) for this endpoint?
- Is the change backward compatible?
- If it’s breaking, have you defined a migration strategy?
2. Versioning
- Does the change require a new API version?
- If it’s non-breaking, can it be included in the current version?
- Have you updated the API documentation (OpenAPI/Swagger)?
- Have you added the change to the changelog?
3. Communication
- Have you notified the consuming teams?
- If it’s breaking, have you defined a coexistence period?
- Have you added deprecation headers where applicable?
- Is the sunset date communicated and documented?
4. Testing
- Do the contract tests pass with the change?
- Have you verified that existing consumers still work?
- Have you added tests for the new behavior?
- Have you run can-i-deploy (or equivalent)?
5. Deployment
- Is the deploy order correct? (generally producer first for non-breaking changes)
- Do you have a rollback plan if something fails?
- Have you set up monitoring to catch post-deploy errors?
Checklist for event changes
1. Compatibility analysis
- Is the change backward compatible? (new consumers can read old events)
- Is the change forward compatible? (old consumers can read new events)
- Do new fields have default values?
- Do existing consumers ignore unknown fields?
2. Schema Registry
- Have you registered the new schema in the schema registry?
- Did the compatibility validation pass?
- Have you updated the schema version?
- Have you documented the schema changes?
3. Upcasting (if applicable)
- Do you need an upcaster for historical events?
- Is the upcaster deterministic and free of side effects?
- Have you tested the full upcaster chain?
- Do consumers that reprocess historical events work correctly?
4. Consumers
- Can all consumers handle the new format?
- Do consumers have error handling for unexpected schemas?
- Is the deploy order correct? (generally consumers first for backward-compatible changes)
Recommended process for changes
For non-breaking changes
- Implement the change in the producer
- Update documentation and changelog
- Deploy the producer
- Notify consumers about the new capabilities
- Consumers adopt the change at their own pace
For breaking changes
- Communicate the change in advance
- Create the new version (API) or schema (events)
- Implement a coexistence period
- Deploy the new version alongside the previous one
- Coordinate consumer migration
- Monitor adoption of the new version
- Deprecate the previous version with a sunset date
- Retire the previous version once it has no traffic
Warning signs
Pay attention to these signs that indicate problems in your versioning process:
- 🚩 You don’t know how many consumers your API has
- 🚩 You don’t have contract tests
- 🚩 Breaking changes are discovered in production
- 🚩 There’s no changelog or version documentation
- 🚩 Teams are afraid to change APIs because they don’t know what will break
- 🚩 There are multiple active versions with no sunset date
- 🚩 Events don’t have a version field in their schema