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:

  1. Create the new stop.
  2. Add signs showing the future location.
  3. Keep both stops available temporarily.
  4. 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:

  1. Which changes are breaking changes.
  2. Which changes are backward compatible.
  3. How to run multiple API versions together.
  4. How to notify clients about upcoming changes.
  5. 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:

HeaderPurpose
DeprecationIndicates that the version is deprecated
SunsetSpecifies when support ends
LinkPoints 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:

  1. Create a new API version.
  2. Keep the old version running.
  3. Add deprecation notices.
  4. Monitor usage.
  5. Help clients migrate.
  6. 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

SymptomCauseFix
The app of a partner shows blank fieldsA field was renamed in placeKeep the old name in v1, and rename it in v2
Old app versions crash after a releaseA field type changedTreat type changes as breaking
Requests suddenly fail with 400There is a new required request fieldMake new fields optional
A version is turned off and partners are angryThere was no warningSend 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.