Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
eaccc2a
Update documentation for Microsoft.AspNetCore.OpenApi
lauraneto Dec 19, 2025
ef567f7
Add Umbraco 18 upgrade notes for OpenAPI changes
lauraneto Dec 19, 2025
c61c752
Add documentation for ExcludeFromDefaultOpenApiDocument attribute
lauraneto Jan 6, 2026
431a75e
Fix OpenAPI documentation issues discovered during testing
lauraneto Jan 6, 2026
9fea065
Update OpenAPI documentation for UmbracoOpenApiOptions
lauraneto Jan 7, 2026
0f8a284
Update OpenAPI documentation for v18 URL changes
lauraneto Jan 7, 2026
6a3b49d
Update OpenAPI examples to use AddOpenApiDocumentToUi
lauraneto Jan 15, 2026
3070883
Update docs for AddDeliveryApiOpenApiMemberAuthentication extension m…
lauraneto Jan 15, 2026
4a456c5
Merge branch 'main' into cms/v18/microsoft-open-api-docs
lauraneto Apr 16, 2026
67d829e
Move OpenAPI documentation changes from v17 to v18
lauraneto Apr 16, 2026
a5e2a84
Address vale linter feedback from PR review
lauraneto Apr 29, 2026
97578c9
Merge branch 'main' into cms/v18/microsoft-open-api-docs
lauraneto May 7, 2026
75764e9
Sync v18 OpenAPI docs with current code
lauraneto May 7, 2026
34b59fc
Document new IUmbracoPipelineFilter PreMapEndpoints / PostMapEndpoint…
lauraneto May 7, 2026
a6c7a4c
Document MapToApi filtering for custom OpenAPI documents in v18
lauraneto May 7, 2026
8168e00
Trim v18 OpenAPI upgrade notes to link out to reference docs
lauraneto May 11, 2026
9322dae
Restructure API versioning and OpenAPI reference
lauraneto May 11, 2026
fb894ad
Tidy custom-backoffice-api walkthrough wording
lauraneto May 11, 2026
b8ef878
Slim adding-a-custom-openapi-document tutorial
lauraneto May 11, 2026
c4ea685
Tighten umbraco-schema-and-operation-ids tutorial wording
lauraneto May 11, 2026
bf392c7
Sharpen custom-generated-client AllowAnonymous behavior and heading c…
lauraneto May 11, 2026
d9419cd
Remove migrating-macros tutorial
lauraneto May 11, 2026
04855b3
Tighten OpenAPI wording in management-api and documenting-your-contro…
lauraneto May 11, 2026
f3f59ab
Fix schema ID example and use composer pattern for custom backoffice API
lauraneto May 11, 2026
6ce8224
Document AddBackOfficeOpenApiDocument as the recommended path for bac…
lauraneto May 11, 2026
e43c6ba
Add more details to the OpenAPI upgrade notes
lauraneto May 11, 2026
d6bdadd
Minor grammar
sofietoft May 12, 2026
701a067
Grammar fixes
sofietoft May 12, 2026
5d579d2
Fix description punctuation in OpenAPI document tutorial
sofietoft May 12, 2026
ea0dbae
Revert v18 upgrade notes changes (already added in #8049)
lauraneto May 12, 2026
a5b5f50
Merge branch 'main' into cms/v18/microsoft-open-api-docs
lauraneto May 15, 2026
6df2238
Restore links in v18 upgrade notes
lauraneto May 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions 18/umbraco-cms/.gitbook.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,7 @@ redirects:
fundamentals/get-to-know-umbraco: README.md
reference/dive-into-the-code: develop-with-umbraco/application-code/README.md
reference/property-editor-uis: extend-your-project/backoffice-extensions/extending-overview/extension-types/property-editor-ui/property-editor-uis.md
reference/custom-swagger-api: extend-your-project/server-side-extensions/custom-backoffice-api.md
extend-your-project/server-side-extensions/custom-swagger-api: extend-your-project/server-side-extensions/custom-backoffice-api.md
tutorials/creating-a-backoffice-api/adding-a-custom-swagger-document: extend-your-project/tutorials/creating-a-backoffice-api/adding-a-custom-openapi-document.md
extend-your-project/tutorials/creating-a-backoffice-api/adding-a-custom-swagger-document: extend-your-project/tutorials/creating-a-backoffice-api/adding-a-custom-openapi-document.md
5 changes: 2 additions & 3 deletions 18/umbraco-cms/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
* [Minor Upgrades for Umbraco 8](get-started/upgrading-and-migrating/version-specific/minor-upgrades-for-umbraco-8.md)
* [Upgrade to Umbraco 7](get-started/upgrading-and-migrating/version-specific/upgrade-to-umbraco-7.md)
* [Minor Upgrades for Umbraco 7](get-started/upgrading-and-migrating/version-specific/minor-upgrades-for-umbraco-7.md)
* [Migrating Macros](get-started/upgrading-and-migrating/version-specific/migrating-macros.md)
* [Single Block Migration for Umbraco 18](get-started/upgrading-and-migrating/version-specific/single-block-migration.md)
* [Upgrade Unattended](get-started/upgrading-and-migrating/upgrade-unattended.md)
* [Downgrades and Re-Running Migrations](get-started/upgrading-and-migrating/downgrades-and-rerunning-migrations.md)
Expand Down Expand Up @@ -444,7 +443,7 @@
* [Using Azure Blob Storage for Media and ImageSharp Cache](extend-your-project/server-side-extensions/filesystemproviders/azure-blob-storage.md)
* [Custom Routing](extend-your-project/server-side-extensions/custom-routing/README.md)
* [Adding a Hub with SignalR and Umbraco](extend-your-project/server-side-extensions/custom-routing/adding-a-hub-with-signalr-and-umbraco.md)
* [Custom Swagger API](extend-your-project/server-side-extensions/custom-swagger-api.md)
* [Custom Backoffice API](extend-your-project/server-side-extensions/custom-backoffice-api.md)
* [Embedded Media Providers](extend-your-project/server-side-extensions/embedded-media-providers.md)
* [Flag Providers](extend-your-project/server-side-extensions/flag-providers.md)
* [JSON Serialization](extend-your-project/server-side-extensions/json-serialization.md)
Expand Down Expand Up @@ -502,7 +501,7 @@
* [Connecting Umbraco Forms and Zapier](extend-your-project/tutorials/connecting-umbraco-forms-and-zapier.md)
* [Creating a Backoffice API](extend-your-project/tutorials/creating-a-backoffice-api/README.md)
* [Documenting Your Controllers](extend-your-project/tutorials/creating-a-backoffice-api/documenting-your-controllers.md)
* [Adding a Custom Swagger Document](extend-your-project/tutorials/creating-a-backoffice-api/adding-a-custom-swagger-document.md)
* [Adding a Custom OpenAPI Document](extend-your-project/tutorials/creating-a-backoffice-api/adding-a-custom-openapi-document.md)
* [Versioning Your API](extend-your-project/tutorials/creating-a-backoffice-api/versioning-your-api.md)
* [Polymorphic Output in the Management API](extend-your-project/tutorials/creating-a-backoffice-api/polymorphic-output-in-the-management-api.md)
* [Umbraco Schema and Operation IDs](extend-your-project/tutorials/creating-a-backoffice-api/umbraco-schema-and-operation-ids.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ You can use Umbraco pipeline filters in case you want to add your own middleware
* `PostRouting` - executed after the routing middleware is added and can be used to [configure Cross-origin resource sharing (CORS)](https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-7.0).
* `PostPipeline` - executed after all Umbraco-specific middleware is added.
* `Endpoints` - executed right before the Umbraco-specific endpoints are added using `WithEndpoints()`.
* `PreMapEndpoints` - executed inside `UseEndpoints`, before Umbraco maps its own endpoints. The callback receives an `IEndpointRouteBuilder`, so endpoints can be mapped directly without nesting another `UseEndpoints` block.
* `PostMapEndpoints` - the same as `PreMapEndpoints`, but runs after Umbraco's endpoints have been mapped.

The addition of the `PostRouting` callback is to allow correctly configuring the Cross-Origin Resource Sharing (CORS) middleware without having to use the `WithCustomMiddleware()` method.

Expand Down Expand Up @@ -43,11 +45,11 @@ public class CorsComposer : IComposer
.AddCors(options => options.AddPolicy(AllowAnyOriginPolicyName, policy => policy.AllowAnyOrigin()))
.Configure<UmbracoPipelineOptions>(options => options.AddFilter(new UmbracoPipelineFilter("Cors", postRouting: app => app.UseCors())))
// For testing only
.Configure<UmbracoPipelineOptions>(options => options.AddFilter(new UmbracoPipelineFilter("CorsTest", endpoints: app => app.UseEndpoints(endpoints =>
.Configure<UmbracoPipelineOptions>(options => options.AddFilter(new UmbracoPipelineFilter("CorsTest", preMapEndpoints: endpoints =>
{
endpoints.MapGet("/echo", context => context.Response.WriteAsync("echo")).RequireCors(AllowAnyOriginPolicyName);
endpoints.MapGet("/echo2", context => context.Response.WriteAsync("echo2"));
}))));
})));
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ Returns single or multiple items.
| **401**: Unauthorized | Missing permissions after protection is set up. |
| **404**: Not Found | Content item not found. |

All endpoints are documented in a Swagger document at `{yourdomain}/umbraco/swagger`. This document is not available in production mode by default. For more information read the [API versioning and OpenAPI](https://docs.umbraco.com/umbraco-cms/reference/api-versioning-and-openapi) article.
All endpoints are documented in an OpenAPI document at `{yourdomain}/umbraco/openapi`. This document is not available in production mode by default. For more information read the [API versioning and OpenAPI](../../../extend-your-project/server-side-extensions/api-versioning-and-openapi.md) article.

You can also configure the Delivery API to emit per-content-type schemas in its OpenAPI document. See the [Content type schemas in OpenAPI](content-type-schemas-in-openapi.md) article.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,27 +379,32 @@ GET /umbraco/delivery/api/v1/security/member/userinfo

## Testing with Swagger

The Delivery API Swagger document can be configured to support member authentication.
The Delivery API OpenAPI document can be configured to support member authentication.

Before we can do that, we need two things in place:

1. We have to implement a login page [as described above](./#logging-in-members).
2. We must add `https://{server-host}/umbraco/swagger/oauth2-redirect.html` to the configured `LoginRedirectUrls`.
2. We must add `https://{server-host}/umbraco/openapi/oauth2-redirect.html` to the configured `LoginRedirectUrls`.

With these in place, we can enable member authentication in Swagger for the Delivery API by adding the following to `Program.cs`:

{% code title="Program.cs" %}
```csharp
using Umbraco.Cms.Api.Delivery.OpenApi;

builder.CreateUmbracoBuilder()
.AddBackOffice()
.AddWebsite()
.AddDeliveryApi()
.AddComposers()
.Build();
builder.Services.ConfigureOptions<Umbraco.Cms.Api.Delivery.Configuration.ConfigureUmbracoMemberAuthenticationDeliveryApiSwaggerGenOptions>();

builder.Services.AddDeliveryApiOpenApiMemberAuthentication();
```
{% endcode %}

The `AddDeliveryApiOpenApiMemberAuthentication()` extension method adds the OAuth2 security scheme and marks the Delivery API as supporting member authorization via Swagger UI.

The Swagger UI will now feature authorization.

{% hint style="info" %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ The Management API can also be used for Custom apps or Workflows with OpenID Con
The Management API is a replacement for the backoffice controllers that lacked RESTful capabilities.
{% endhint %}

### Swagger Documentation
### OpenAPI Documentation

Umbraco ships with Swagger to document the Management API. Swagger and the Swagger UI are based on [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/) and is available at `{yourdomain}/umbraco/swagger`. For security reasons, both are disabled in production environments.
Umbraco uses [Microsoft.AspNetCore.OpenApi](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/openapi/overview) to document the Management API. The OpenAPI document and Swagger UI are both available at `{yourdomain}/umbraco/openapi`, and both are disabled in production environments for security reasons.

The Swagger documentation allows you to select a definition and go to either Umbraco Management API or Content Delivery API. If you are extending the Management API with your own controllers, you can also create custom documentation for these in Swagger. See [Custom Swagger API](../../../extend-your-project/server-side-extensions/custom-swagger-api.md) and [Creating a backoffice API](../../../extend-your-project/tutorials/creating-a-backoffice-api/) articles for details.
The OpenAPI documentation allows you to select a definition and go to either Umbraco Management API or Content Delivery API. If you are extending the Management API with your own controllers, you can also create custom documentation for these. See [Custom Backoffice API](../../../extend-your-project/server-side-extensions/custom-backoffice-api.md) and [Creating a backoffice API](../../../extend-your-project/tutorials/creating-a-backoffice-api/) articles for details.

![Umbraco Management API documentation in Swagger](../../../.gitbook/assets/management-api-swagger.png)
![Umbraco Management API documentation in Swagger UI](../../../.gitbook/assets/management-api-swagger.png)

In the Swagger Umbraco Management API, you can find a collection of available endpoints in this version of Umbraco.
In the Umbraco Management API OpenAPI document, you can find a collection of available endpoints in this version of Umbraco.

### Authorization

Expand All @@ -36,7 +36,7 @@ Then a popup will appear with some setup information and a login form for author

![Umbraco Management API Authorize Login](../../../.gitbook/assets/management-api-swagger-authorize-instructions.png)

The available integration for the authorization is done via a backoffice user with the integration of `OAuth2, authorizationCode with PKCE`. Swagger is only enabled in non-production environments, so if you need to access the Management API in production, you need a different client.
The available integration for the authorization is done via a backoffice user with the integration of `OAuth2, authorizationCode with PKCE`. The OpenAPI UI is only enabled in non-production environments. To access the Management API in production, you need a different client.

{% hint style="info" %}
In production environment, only `umbraco-back-office` **client** is allowed to connect to the Management API. In non-production environments, the `umbraco-swagger` and `umbraco-postman` **clients** can be used.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ This guide covers the following:

## Importing the collection

1. Open the swagger UI at `{yourdomain}/umbraco/swagger`.
1. Open the OpenAPI UI at `{yourdomain}/umbraco/openapi`.
2. Choose **Umbraco Management API** from **Select a definition**.
3. Open the JSON file, which you can find right underneath the **Title**:

![JSON file location](../../../.gitbook/assets/postman-setup-swagger-json-file.png)

4. Save the JSON file to disk. The name of the file will be saved by default with the name of `swagger.json`.
4. Save the JSON file to disk. The default file name is `management.json`.
5. Click to [create a new collection](https://learning.postman.com/docs/collections/using-collections/#creating-collections) in Postman.
6. Import the `swagger.json` file.
6. Import the JSON file.
7. Choose **Postman Collection** when prompted.

![Postman import JSON file as collection](../../../.gitbook/assets/postman-setup-swagger-import.png)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ This command creates a new folder called `MyExtension` with the following files

The `-ex` flag indicates that you want to include examples of how to use the extension. This flag is optional, but it is recommended to include it if you are new to building extensions for Umbraco. It will additionally give you:

* `Composers`: A folder containing an example composer that registers a custom Swagger API.
* `Composers`: A folder containing an example composer that registers a custom OpenAPI document for the API.
* `Controllers`: A folder containing an example API controller for a dashboard.
* `Client/src/api`: A folder containing an example API client that calls the API controller.
* `Client/src/dashboards`: A folder containing an example dashboard Web Component that uses the API client.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Your generated client needs the correct base URL, credentials, and authenticatio
The [Umbraco Extension Template](../../development-flow/umbraco-extension-template.md) already includes this setup. If you scaffolded your extension with `dotnet new umbraco-extension`, authentication works out of the box β€” no additional configuration needed.
{% endhint %}

### Using `runtimeConfigPath` (Recommended)
### Using `runtimeConfigPath` (recommended)

To pass plugin options like `runtimeConfigPath`, create a config file instead of using CLI flags.

Expand All @@ -50,7 +50,7 @@ To pass plugin options like `runtimeConfigPath`, create a config file instead of
import { defineConfig } from '@hey-api/openapi-ts';

export default defineConfig({
input: 'https://localhost:44339/umbraco/swagger/myextension/swagger.json',
input: 'https://localhost:44339/umbraco/openapi/myextension.json',
output: 'src/api',
plugins: [
{
Expand Down Expand Up @@ -119,33 +119,30 @@ The resolved shape is what `umbHttpClient` checks before invoking the `auth` cal

### Management API (automatic)

If your controllers are part of the Umbraco Management API β€” tagged with `[MapToApi("management")]` β€” Umbraco writes the `operation.security` requirement into the OpenAPI spec automatically. This is done by `BackOfficeSecurityRequirementsOperationFilter`, a Swashbuckle operation filter registered as part of the Management API configuration. It inspects each operation at startup. If neither the controller class nor the action method carries `[AllowAnonymous]`, it adds a security requirement referencing the globally registered `"Backoffice-User"` scheme.
If your controllers are part of the Umbraco Management API β€” tagged with `[MapToApi("management")]` β€” Umbraco writes the `operation.security` requirement into the OpenAPI spec automatically. This is done by an `IOpenApiOperationTransformer` registered as part of the Management API configuration. It inspects each operation at document generation time. If the operation is marked `[AllowAnonymous]` (either on the action or the controller), the transformer explicitly clears its security. Otherwise, it adds a security requirement referencing the globally registered `"Backoffice-User"` scheme.

When hey-api generates your client from that spec, it resolves the scheme and emits the runtime security metadata into each SDK function. No extra setup needed.

### Custom separate API

If you expose a separate API with its own Swagger document, security requirements are not added automatically. You must apply them to each operation in your OpenAPI specification, for example via an operation filter. Umbraco provides `BackOfficeSecurityRequirementsOperationFilterBase` as a public base class you can subclass:
If you expose a separate API with its own OpenAPI document, security requirements are not added automatically. The Management API ships an `AddBackofficeSecurityRequirements()` extension method that registers both the document-level Bearer scheme and the per-operation requirement (skipping any operation marked with `[AllowAnonymous]`).

Call it on the `OpenApiOptions` passed into `AddOpenApi`:

```csharp
using Umbraco.Cms.Api.Management.OpenApi;

internal sealed class MyExtensionSecurityRequirementsOperationFilter : BackOfficeSecurityRequirementsOperationFilterBase
builder.Services.AddOpenApi("myextension", options =>
{
// Must match the [MapToApi("...")] attribute on your controllers
protected override string ApiName => "myextension";
}
```
// ...other configuration

Register it in your SwaggerGen configuration:

```csharp
swaggerGenOptions.OperationFilter<MyExtensionSecurityRequirementsOperationFilter>();
options.AddBackofficeSecurityRequirements();
});
```

No `AddSecurityDefinition` call is needed β€” Umbraco already registers the required Bearer security scheme globally, and the base filter references it automatically. Once in place, hey-api will generate SDK functions with the correct `security` metadata.
No `AddSecurityDefinition` call is needed β€” `AddBackofficeSecurityRequirements()` adds it. Once in place, hey-api will generate SDK functions with the correct `security` metadata.

For a full walkthrough of setting up a custom API, see [Creating a Backoffice API](../../../tutorials/creating-a-backoffice-api/README.md).
For a complete walkthrough of setting up a custom API, see [Creating a Backoffice API](../../../tutorials/creating-a-backoffice-api/README.md), [Custom Backoffice API](../../../server-side-extensions/custom-backoffice-api.md), and [API versioning and OpenAPI](../../../server-side-extensions/api-versioning-and-openapi.md).

### Direct calls without a generated client

Expand Down
Loading
Loading