APIs Are Contracts
Once an API has consumers, it becomes a contract. Breaking changes — removing fields, changing response structures, altering authentication — break consumer integrations. API versioning and deprecation strategies enable APIs to evolve without breaking existing consumers. At Nexis Limited, Bondorix's API serves dozens of integration partners, making versioning and backward compatibility critical.
Versioning Approaches
URL Path Versioning
Include the version in the URL path: /api/v1/shipments, /api/v2/shipments. This is the most explicit and widely understood approach. Consumers can see which version they are using in every request. It is easy to route different versions to different backend implementations.
Header Versioning
Specify the version in a request header: Accept: application/vnd.nexis.v2+json. This keeps URLs clean but is less discoverable — consumers must read documentation to know about versioning. It is harder to test in a browser.
Query Parameter Versioning
Include the version as a query parameter: /api/shipments?version=2. Simple to implement and test but can conflict with other query parameters and is not considered RESTful by purists.
Our Recommendation
Use URL path versioning. It is the most explicit, easiest to understand, and simplest to implement. Most major APIs (Stripe, Twilio, GitHub) use this approach.
When to Create a New Version
Create a new version only for breaking changes. Non-breaking changes should be added to the current version:
- Breaking: Removing a field, changing a field's type, changing authentication, restructuring the response.
- Non-breaking: Adding a new field (with a default value), adding a new endpoint, adding optional query parameters.
Backward Compatibility Practices
- Add new fields — never remove or rename existing fields in the current version.
- Use optional parameters with sensible defaults for new functionality.
- Return consistent response structures — do not change array to object or string to number.
- Document all fields and mark new fields in changelog entries.
Deprecation Workflow
- Announce: Notify consumers of deprecation with at least 6 months notice. Include the deprecation date, migration guide, and support contact.
- Warn: Add deprecation headers (Sunset, Deprecation) to responses from deprecated endpoints. Log deprecated endpoint usage to identify remaining consumers.
- Migrate: Provide migration guides, updated SDKs, and support for consumers transitioning to the new version.
- Monitor: Track usage of deprecated endpoints. Reach out directly to consumers who have not migrated.
- Sunset: After the deprecation date, return 410 Gone with a message directing consumers to the new version.
API Changelog
Maintain a public changelog documenting every API change — new endpoints, new fields, deprecated features, and breaking changes. Consumers should be able to subscribe to change notifications through email, RSS, or webhooks.
SDK and Client Library Versioning
If you provide client SDKs, version them alongside the API. SDK version 2.x should target API v2, making it clear which SDK version works with which API version. Use semantic versioning (major.minor.patch) for SDKs.
Conclusion
Good API versioning and deprecation practices show respect for your consumers' time and investment. Version explicitly, maintain backward compatibility, deprecate gracefully with ample notice, and provide migration support. Your API's reputation depends on how reliably it can be integrated with.
Designing a public API? Our team has experience building APIs that serve external integration partners.