Why API Versioning Matters and When to Use It
As your API evolves, you’ll likely introduce changes that could break existing clients — like renaming fields or changing response formats. API versioning helps you avoid this by allowing you to support multiple versions of your API side by side. It ensures backward compatibility and will enable clients to upgrade at their own pace.
Versioning is especially important when external apps, front-ends, or third-party integrations use your API. It also makes your API easier to maintain, debug, and document over time.
When should you implement API versioning? The short answer is that as soon as your API is consumed by more than just yourself.
Also, explicit API versioning is a must, according to Microsoft REST API Guidelines.
ASP.NET API Versioning
ASP.NET API Versioning is an excellent project that offers packages for various ASP.NET frameworks, including:
- ASP.NET Core Minimal API
- ASP.NET Web API
- ASP.NET Core MVC
Additionally, it supports OData v4.0 and provides API Explorers for all project types, allowing you to document your REST APIs using OpenAPI.
Getting Started
Let’s see how easy and fast we can configure API versioning. I’ll show you how to do that for Minimal API, but it’s very similar for other project types.
First, install the Asp.Versioning.Http package:
dotnet add package Asp.Versioning.Http
The initial configuration looks as follows:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddApiVersioning();
var app = builder.Build();
ApiVersionSet apiVersionsSet = app.NewApiVersionSet()
.HasApiVersion(new ApiVersion(1))
.HasApiVersion(new ApiVersion(2))
.Build();
app.MapGet("/todo", () =>
{
return "Version 1";
})
.WithApiVersionSet(apiVersionsSet)
.HasApiVersion(1);
app.MapGet("/todo", () =>
{
return "Version 2";
})
.WithApiVersionSet(apiVersionsSet)
.HasApiVersion(2);
app.Run();
Let’s break down what this code does:
- builder.Services.AddApiVersioning() registers the API versioning system in the DI container.
- app.NewApiVersionSet() creates a reusable version set, which groups multiple API versions under a shared identity.
- .HasApiVersion(new ApiVersion(1)) and .HasApiVersion(new ApiVersion(2)) declare that this set supports v1 and v2.
- Each endpoint is associated with the previously defined apiVersionsSet. It declares that this endpoint belongs to version 1 using .HasApiVersion(1).
And that’s it. Let’s send the request:

Where to Specify a Version?
As you can see in the example above, the version is passed through the query parameter. This is the default behavior, but you can change it.
The Asp.Versioning.Http supports a few version readers:
- UrlSegmentApiVersionReader – the version in the endpoint route like /v1/todo.
- QueryStringApiVersionReader – the default version in the query params like /todo?api-version=1
- HeaderApiVersionReader – the version in the HTTP headers like /todo -H ‘Api-Version: 1’
- MediaTypeApiVersionReader – the version in the media type like /todo – H ‘ContentType: application/json;v=1’
You can set the version reader using the ApiVersionReader option:
builder.Services.AddApiVersioning(options =>
{
options.ApiVersionReader = new UrlSegmentApiVersionReader();
});
When you want to use the QueryStringApiVersionReader, you must also put a version in the endpoint routes:
app.MapGet("v{version:apiVersion}/todo", () =>
{
return "Version 1";
})
.WithApiVersionSet(apiVersionsSet)
.HasApiVersion(1);
Then, we can use the version in the endpoint route:

All version readers implement the IApiVersionReader interface, so you can implement it if you need a custom version reader.
Other Options
The API Versioning libraries are very flexible. Let’s see some useful options:
builder.Services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
options.ApiVersionReader = new UrlSegmentApiVersionReader();
});
You can specify a default version with a DefaultApiVersion option.
Having the default version, you use it when no version is sent with an AssumeDefaultVersionWhenUnspecified option.
Also, the ReportApiVersions option is helpful. When it’s enabled, the response headers contain information about supported and deprecated versions:

You can mark the version as deprecated with the HasDeprecatedApiVersion method for ApiVersionSet or a single endpoint:
ApiVersionSet apiVersionsSet = app.NewApiVersionSet()
.HasApiVersion(new ApiVersion(1))
.HasApiVersion(new ApiVersion(2))
.HasDeprecatedApiVersion(new ApiVersion(1))
.Build();
Conclusion
If you’re building public APIs or evolving microservices, versioning is necessary.
ASP.NET API Versioning is a great project that allows you to manage API versioning easily. It’s open-sourced but was absorbed into the .NET organization.
With just a few configuration lines, you can support multiple versions side by side, confidently introduce changes, and give consumers the flexibility to upgrade on their timeline.