0Pricing
C# Academy · Lesson

Documenting Versioned APIs

Expose docs for multiple API versions.

Documenting Versioned APIs is a free C# Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

One Document per Version

When an API has several versions, you typically want a separate OpenAPI document for each version so consumers see only the endpoints relevant to them.

// /openapi/v1.json -> only v1 endpoints
// /openapi/v2.json -> only v2 endpoints

The API Version Description Provider

Asp.Versioning exposes IApiVersionDescriptionProvider, which lists every discovered API version. You loop over it to register a document per version.

var provider = app.Services
    .GetRequiredService<IApiVersionDescriptionProvider>();

foreach (var desc in provider.ApiVersionDescriptions)
{
    // desc.GroupName is e.g. "v1", "v2"
}

Registering a Document per Version

Call AddOpenApi once per version group, naming each document after the group.

builder.Services
    .AddApiVersioning()
    .AddApiExplorer(o =>
    {
        o.GroupNameFormat = "'v'VVV";
        o.SubstituteApiVersionInUrl = true;
    });

builder.Services.AddOpenApi("v1");
builder.Services.AddOpenApi("v2");

Filtering Endpoints into the Right Document

Use a document transformer or the ShouldInclude predicate so each document contains only its version's endpoints, matched by group name.

builder.Services.AddOpenApi("v1", options =>
{
    options.ShouldInclude = description =>
        description.GroupName == "v1";
});

Mapping the Documents

MapOpenApi with the default pattern serves every named document at /openapi/{documentName}.json.

app.MapOpenApi();
// /openapi/v1.json and /openapi/v2.json both available

Setting Per-Document Info

Give each version document its own title and version in a transformer so the docs are self-describing.

builder.Services.AddOpenApi("v2", options =>
{
    options.AddDocumentTransformer((doc, ctx, ct) =>
    {
        doc.Info.Title = "Catalog API v2";
        doc.Info.Version = "2.0";
        return Task.CompletedTask;
    });
});

Marking Deprecated Versions in Docs

If a version is deprecated, surface that in its document description so consumers see the warning in the UI.

options.AddDocumentTransformer((doc, ctx, ct) =>
{
    if (ctx.DocumentName == "v1")
        doc.Info.Description = "DEPRECATED - migrate to v2.";
    return Task.CompletedTask;
});

Substituting the Version in URLs

SubstituteApiVersionInUrl = true rewrites the {version:apiVersion} route token into the concrete version (e.g. v1) in the document, so paths read cleanly.

// Without: /api/v{version}/products
// With:    /api/v1/products

A UI Tab per Version

Most viewers can show a dropdown of all documents. Configure the UI to point at each version's JSON.

app.MapScalarApiReference(options =>
{
    options.AddDocument("v1", "API v1", "/openapi/v1.json");
    options.AddDocument("v2", "API v2", "/openapi/v2.json");
});

Documenting Request and Response Shapes

Because v2 may change DTOs, give each version its own DTO types. OpenAPI then renders distinct schemas per document automatically.

// V1 DTO
public record ProductV1(int Id, string Name);
// V2 DTO (breaking change)
public record ProductV2(int Id, string Title, decimal Price);

Putting It Together

The full flow: configure versioning + API explorer, register one OpenApi document per version with a filter, map them, and point your UI at each.

builder.Services.AddApiVersioning().AddApiExplorer(o =>
{
    o.GroupNameFormat = "'v'VVV";
    o.SubstituteApiVersionInUrl = true;
});
builder.Services.AddOpenApi("v1");
builder.Services.AddOpenApi("v2");
// ...
app.MapOpenApi();
app.MapScalarApiReference();

Quick Check

Confirm how versioned docs are produced.

Recap

You documented versioned APIs:

  • Register one named OpenAPI document per version with AddOpenApi("vN").
  • IApiVersionDescriptionProvider enumerates versions; ShouldInclude filters endpoints.
  • SubstituteApiVersionInUrl renders concrete versioned paths.
  • Point the UI at each document for a per-version view.

That completes the versioning and OpenAPI course.

Frequently asked questions

Is the “Documenting Versioned APIs” lesson free?

Yes — the full text of “Documenting Versioned APIs” is free to read here on the web, and the C# Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO.

What will I learn in “Documenting Versioned APIs”?

Expose docs for multiple API versions. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C# Academy?

No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Documenting Versioned APIs” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C# Academy lesson?

Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. API Versioning Strategies
  2. Configuring Asp.Versioning
  3. Generating OpenAPI Documents
  4. Documenting Versioned APIs
← Back to C# Academy