API Versioning
By the Syncfusion DevTutorials team · Last updated
Change an API without breaking its clients: spot breaking changes, serve /v1 and /v2 side by side, and retire old versions with Deprecation and Sunset headers.
API versioning allows you to improve an API without breaking existing applications that depend on it. When a change would cause older clients to stop working, you create a new version of the API instead of changing the existing one. Existing clients continue using the old version, while newer clients can move to the new version when they are ready.
This approach helps you evolve your API safely while maintaining compatibility with applications that are already in production.
Watch One Rename Break a Partner
A developer decides to rename customerName to name, because it looks cleaner. Press Run.
Program.cs — one rename breaks a partner
The response still looks correct. The server still returns: 200 OK
However, the delivery partner's application expects the field customerName. When that field disappears, the application cannot find the customer name.
As a result, delivery labels print with blank names. The server appears healthy, and no errors appear in the logs, but the application of the partner is broken.
In simple words: even a small improvement can break someone else's application if it changes the API contract.
TL;DR
- A breaking change causes existing clients to fail.
- Examples of breaking changes include renaming fields, removing fields, changing field types, removing endpoints, and adding required request fields.
- A safe change adds functionality without breaking clients.
- Examples of safe changes include adding optional fields, adding new endpoints, and adding optional parameters.
- Put breaking changes into a new version.
- Keep older versions working for existing users.
- Notify clients before removing an old version.
- Use Deprecation, Sunset, and Link headers to guide migrations.
- Use automated tools to detect breaking changes before release.
A Real-World Example
Think about a city bus stop. The city wants to move the stop to a new location.
If the old stop disappears overnight, passengers wait in the wrong place, people miss the bus, and complaints increase.
A better approach is:
- Create the new stop.
- Add signs showing the future location.
- Keep both stops available temporarily.
- Remove the old stop later.
API versioning works the same way. You release a new version, notify users, and allow time for migration before removing the old version.
Release a new version, communicate the change, and retire older versions only after clients have had time to migrate.
What You Will Learn
In this lesson, you will learn:
- Which changes are breaking changes.
- Which changes are backward compatible.
- How to run multiple API versions together.
- How to notify clients about upcoming changes.
- How to detect breaking changes automatically.
Breaking and Non-Breaking Changes
Breaking Changes
These changes can cause existing clients to fail: renaming a field, removing a field, changing a field type, removing an endpoint, renaming an endpoint, adding a required request property, and changing the response structure.
Examples: {"customerName": "Asha"} changed to {"name": "Asha"} is breaking. {"total": 450} changed to {"total": "450"} is also breaking.
Safe Changes
These changes are usually backward compatible: adding optional fields, adding new endpoints, adding optional query parameters, and adding new response fields.
Example: before the change, the response is {"id": 101, "customerName": "Asha"}. After the change, it is {"id": 101, "customerName": "Asha", "phone": "555-1234"}.
Most existing clients continue working because they ignore unknown fields.
Two Versions Side by Side
Instead of changing an existing API version, create a new version.
Program.cs — /v1 and /v2 side by side
Version 1 returns: {"customerName": "Asha", "total": 450}
Version 2 returns: {"name": "Asha", "total": {"amount": 450, "currency": "INR"}}
Both versions can read the same underlying order data. The benefits are that existing clients continue using /v1, new clients can adopt /v2, and migration happens gradually.
In ASP.NET Core, route groups such as these help keep versions separate: app.MapGroup("/v1") and app.MapGroup("/v2"). Larger projects often use dedicated API versioning libraries, but the basic idea stays the same.
Tell Clients Before Removing a Version
API versions should not remain forever. When a version is going away, tell clients directly in API responses.
Program.cs — Deprecation and Sunset headers
Common headers include:
| Header | Purpose |
|---|---|
Deprecation | Indicates that the version is deprecated |
Sunset | Specifies when support ends |
Link | Points to the replacement version |
Example headers: Deprecation: @1782864000, Sunset: Fri, 01 Jan 2027 00:00:00 GMT, and Link: </v2/orders>; rel="successor-version"
This tells the client that the current version is deprecated, that support will end on a specific date, and that a newer version exists.
Track which clients still use deprecated versions. Contact them well before the Sunset date, so that they have time to move safely.
Versioning with Headers
Some APIs keep the same URL and let clients choose a version through a header.
Program.cs — version in a header
Example header: X-Api-Version: 2
Possible behavior: with no header, the API uses Version 1. With X-Api-Version: 2, it uses Version 2. With an unknown version, it returns 400 Bad Request.
URL Versioning
Examples: /v1/orders and /v2/orders
Advantages: it is easy to see, easy to document, and easy to test.
Header Versioning
Example: X-Api-Version: 2
Advantages: the URLs are cleaner, and the routes are easier to manage.
Choose one approach and apply it consistently across the API.
Detect Breaking Changes Automatically
Developers often forget that a change is breaking. Automated tools help identify dangerous changes before release.
BreakingChanges.cs — detect breaking changes
Typical checks include removed fields, renamed fields, type changes, removed endpoints, and changed request requirements.
Example report: BREAKING: customerName removed, BREAKING: total changed from number to object, SAFE: phone added, and SAFE: email added
Automated checks reduce the risk of accidentally breaking client applications.
Adding a required request field is also a breaking change. Older clients do not send the new field, so their requests start failing at once. Prefer optional fields with sensible default values.
Migration Strategy
A typical version migration follows these steps:
- Create a new API version.
- Keep the old version running.
- Add deprecation notices.
- Monitor usage.
- Help clients migrate.
- Remove the old version after the Sunset date.
This approach gives clients enough time to update their applications without service interruptions.
Where You See This
- Payment APIs often support old versions for many years.
- Mobile applications frequently depend on versioning because old app versions remain installed on devices.
- Public APIs publish migration guides and deprecation schedules.
- Large organizations use automated compatibility checks before deployment.
Common mistakes
| Symptom | Cause | Fix |
|---|---|---|
| The app of a partner shows blank fields | A field was renamed in place | Keep the old name in v1, and rename it in v2 |
| Old app versions crash after a release | A field type changed | Treat type changes as breaking |
Requests suddenly fail with 400 | There is a new required request field | Make new fields optional |
| A version is turned off and partners are angry | There was no warning | Send Deprecation and Sunset headers early |
Exercises
What to Remember
- Breaking changes remove, rename or retype. Safe changes add.
- Ship breaking changes in a new version, and keep the old one working.
- Warn clients with the Deprecation, Sunset and Link headers.
- Check every change automatically.
Next: API Authentication. You will make sure that only the right callers can reach each endpoint.