Skip to main content
skill CX Codex

api-versioning — Claude Code skill: what it does, how to install

Guides your agent through ASP.NET Core API versioning using the Asp.Versioning library. Useful when adding URL segment versions or deprecating legacy contracts.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add codewithmukesh/dotnet-claude-kit --skill api-versioning -a claude-code
Open on GitHub

What api-versioning does

The skill provides practical patterns for ASP.NET Core versioning with the Asp.Versioning library. It steers the assistant toward URL segment versioning as the default choice, sets up AddApiVersioning with NewApiVersionSet, and configures OpenAPI explorer formatting. It also provides header-based routing with X-Api-Version for service-to-service communication.

Its core rule requires versioning the whole endpoint group rather than single actions. Query string versioning is flagged as bad practice because it hurts REST cacheability.

For sunsetting legacy endpoints, the instructions demonstrate HasDeprecatedApiVersion. That setup injects the api-deprecated-versions response header, giving clients a clear signal before endpoints get removed.

What it helps with

  • configure URL segment API versioning in ASP.NET Core
  • mark an API version as deprecated without breaking existing clients
  • split v1 and v2 route handlers into separate route groups
  • switch to header-based versioning for internal services

Example prompts for the agent

  • Add URL segment versioning to my ASP.NET Core order endpoints using Asp.Versioning
  • Mark v1 as deprecated and scaffold v2 endpoints with updated response models
  • Configure header versioning with X-Api-Version for internal service calls

How to install api-versioning

1Skills CLI (Vercel)

npx skills add codewithmukesh/dotnet-claude-kit --skill api-versioning -a claude-code

2Manually: put the files in place

~/.claude/skills/api-versioning/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/api-versioning/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about api-versioning

How do I install api-versioning in Claude Code?

Run npx skills add codewithmukesh/dotnet-claude-kit --skill api-versioning -a claude-code in your terminal.

What does the api-versioning skill do?

It instructs coding assistants on setting up Asp.Versioning in ASP.NET Core, organizing route groups, and handling breaking contract changes.

When does the skill advise using header versioning?

It recommends header versioning (X-Api-Version) specifically for internal service-to-service APIs to keep URLs cleaner.

Source text

SKILL.md · MIT
---
name: api-versioning
description: >
  API versioning strategies for ASP.NET Core. Covers Asp.Versioning library,
  URL segment, header, and query string strategies, version deprecation, and
  OpenAPI integration.
  Load this skill when adding versioning to an API, evolving an API with breaking
  changes, or when the user mentions "API version", "versioning", "v1/v2",
  "Asp.Versioning", "deprecation", "breaking change", or "backward compatibility".
---

# API Versioning

## Core Principles

1. **Version from day one** — Adding versioning later is painful. Start with a version in the URL even if you only have v1.
2. **URL segment versioning is the default** — `/api/v1/orders` is the most discoverable and cache-friendly strategy.
3. **Never break existing versions** — Add a new version for breaking changes. Deprecate the old version with a timeline.
4. **Version the API, not individual endpoints** — All endpoints in a version group share the same version number.

## Patterns

### Setup with Asp.Versioning

```csharp
// Program.cs
builder.Services.AddApiVersioning(options =>
{
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.ReportApiVersions = true;
    options.ApiVersionReader = new UrlSegmentApiVersionReader();
})
.AddApiExplorer(options =>
{
    options.GroupNameFormat = "'v'VVV";
    options.SubstituteApiVersionInUrl = true;
});
```

### URL Segment Versioning (Recommended)

```csharp
var v1 = app.NewApiVersionSet()
    .HasApiVersion(new ApiVersion(1, 0))
    .Build();

var v2 = app.NewApiVersionSet()
    .HasApiVersion(new ApiVersion(2, 0))
    .Build();

app.MapGroup("/api/v{version:apiVersion}/orders")
    .WithApiVersionSet(v1)
    .WithTags("Orders")
    .MapOrderEndpointsV1();

app.MapGroup("/api/v{version:apiVersion}/orders")
    .WithApiVersionSet(v2)
    .WithTags("Orders")
    .MapOrderEndpointsV2();
```

### Header Versioning (Alternative)

```csharp
options.ApiVersionReader = new HeaderApiVersionReader("X-Api-Version");

// Client sends: X-Api-Version: 2.0
```

### Deprecating a Version

```csharp
var v1 = app.NewApiVersionSet()
    .HasDeprecatedApiVersion(new ApiVersion(1, 0))
    .HasApiVersion(new ApiVersion(2, 0))
    .Build();

// Response headers will include: api-deprecated-versions: 1.0
```

### Version-Specific Endpoint Groups

```csharp
public static class OrderEndpointsV1
{
    public static RouteGroupBuilder MapOrderEndpointsV1(this RouteGroupBuilder group)
    {
        group.MapGet("/{id:guid}", GetOrderV1);
        group.MapPost("/", CreateOrderV1);
        return group;
    }

    private static async Task<Results<Ok<OrderResponseV1>, NotFound>> GetOrderV1(
        Guid id, ISender sender, CancellationToken ct)
    {
        // V1 response shape
        var result = await sender.Send(new GetOrder.Query(id), ct);
        return result.IsSuccess
            ? TypedResults.Ok(result.Value.ToV1())
            : TypedResults.NotFound();
    }
}

public static class OrderEndpointsV2
{
    public static RouteGroupBuilder MapOrderEndpointsV2(this RouteGroupBuilder group)
    {
        group.MapGet("/{id:guid}", GetOrderV2);
        group.MapPost("/", CreateOrderV2);
        return group;
    }

    private static async Task<Results<Ok<OrderResponseV2>, NotFound>> GetOrderV2(
        Guid id, ISender sender, CancellationToken ct)
    {
        // V2 response shape — includes new fields
        var result = await sender.Send(new GetOrder.Query(id), ct);
        return result.IsSuccess
            ? TypedResults.Ok(result.Value.ToV2())
            : TypedResults.NotFound();
    }
}
```

## Anti-patterns

### Don't Version Individual Endpoints

```csharp
// BAD — inconsistent versioning within a group
app.MapGet("/api/v1/orders", ListOrdersV1);
app.MapGet("/api/v2/orders/{id}", GetOrderV2); // V2 only for this endpoint?

// GOOD — version the entire group
app.MapGroup("/api/v1/orders").MapOrderEndpointsV1();
app.MapGroup("/api/v2/orders").MapOrderEndpointsV2();
```

### Don't Use Query String Versioning as Default

```csharp
// BAD for REST APIs — version hidden in query string, not cache-friendly
GET /api/orders?api-version=2.0

// GOOD — version in URL, discoverable and cacheable
GET /api/v2/orders
```

## Decision Guide

| Scenario | Recommendation |
|----------|---------------|
| New public API | URL segment versioning from day one |
| Internal API between services | Header versioning (cleaner URLs) |
| Breaking response shape change | New version |
| Adding new optional fields | Same version (backwards compatible) |
| Deprecating a version | Mark deprecated, set sunset date, document migration path |

© codewithmukesh · MIT · codewithmukesh/dotnet-claude-kit

Similar skills

All skills for Backend and APIs →

From the same set47

container-publish Builds OCI images straight from dotnet publish /t:PublishContainer, no Dockerfile involved. Useful when a .NET 10 app has to ship as a container and land in a registry. CX Codex +1 2,800installs workflow-mastery Workflow guide and configurations for .NET development in Claude Code. It introduces parallel sessions via git worktrees, verification loops, and context budgeting. CX Codex +1 2,800installs aspire Guides .NET Aspire setup for local service orchestration, resource wiring, and service discovery. Use it when working with AppHost or shared service defaults. CX Codex +1 2,800installs convention-learner Reads your existing code and turns it into project rules: naming, folder layout, test organisation. Useful when the agent writes code in the wrong style. CX Codex +1 2,800installs caching Guides caching work in .NET 10 applications with HybridCache, response caching, and distributed cache patterns. Use it when reducing database reads or planning cache invalidation. CX Codex +1 2,800installs health-check Grades a .NET project across eight dimensions with letter marks A–F and a rolled-up GPA. Useful at onboarding, before a release, and after a cleanup sprint. CX Codex +1 2,800installs openapi Configures native OpenAPI generation in .NET 10 without Swashbuckle. Helps the agent handle transformers, TypedResults metadata, and security schemes. CX Codex +1 2,800installs configuration Guides .NET 10 configuration with typed options, validation, and secret handling. Use it when working with appsettings files or environment variables. CX Codex +1 2,800installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor