# Custom Backoffice API

This article covers how to create a Custom API controller protected by the backoffice authorization policies. It also shows how to enable authorization in Swagger UI.

{% hint style="info" %}
Before proceeding, make sure to read the [Management API](/umbraco-cms/18.latest/develop-with-umbraco/headless-and-apis/management-api.md) article. It provides information about the OpenAPI documentation and Authorization used in this article.
{% endhint %}

The following example can be a starting point for creating a secure custom API with automatic OpenAPI documentation. You can find other examples in the [API versioning and OpenAPI](/umbraco-cms/18.latest/extend-your-project/server-side-extensions/api-versioning-and-openapi.md) article.

1. Create a composer to register the OpenAPI document so that the new API shows in the OpenAPI documentation and Swagger UI:

{% code title="MyApiComposer.cs" lineNumbers="true" %}

```csharp
using Umbraco.Cms.Api.Common.OpenApi;
using Umbraco.Cms.Api.Management.OpenApi;
using Umbraco.Cms.Core.Composing;

namespace Umbraco.Cms.Web.UI.Custom;

public class MyApiComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
        => builder.AddBackOfficeOpenApiDocument(
            "my-api-v1",
            document => document
                .WithTitle("My API v1")
                .WithBackOfficeAuthentication());
}
```

{% endcode %}

`AddBackOfficeOpenApiDocument` registers a custom OpenAPI document with Umbraco's defaults applied. It includes any controller decorated with `[MapToApi("my-api-v1")]`, applies Umbraco's schema and operation ID conventions, and adds the document to the Swagger UI dropdown. `WithBackOfficeAuthentication()` enables OAuth2-based backoffice authorization in Swagger UI.

2. Create a new file `MyApiController.cs` with the following controller:

{% code title="MyApiController.cs" lineNumbers="true" %}

```csharp
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.Attributes;
using Umbraco.Cms.Api.Common.Filters;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Web.Common.Authorization;

namespace Umbraco.Cms.Web.UI.Custom;

[ApiController]
[ApiVersion("1.0")]
[MapToApi("my-api-v1")]
[Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)]
[JsonOptionsName(Constants.JsonOptionsNames.BackOffice)]
[Route("api/v{version:apiVersion}/my")]
public class MyApiController : Controller
{
    private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;

    public MyApiController(IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
        => _backOfficeSecurityAccessor = backOfficeSecurityAccessor;

    [HttpGet("say-hello")]
    [MapToApiVersion("1.0")]
    [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
    public IActionResult SayHello()
    {
        IUser currentUser = _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser
                            ?? throw new InvalidOperationException("No backoffice user found");
        return Ok($"Hello, {currentUser.Name}");
    }
}
```

{% endcode %}

3. Run the project and navigate to `{yourdomain}/umbraco/openapi`.
4. Choose the OpenAPI document created with the code above named **My API v1** from **Select a definition**.

![Created Custom API in OpenAPI documentation](/files/VoypBf4pkoVFasELnWaM)

Here, you can find the endpoint that was created:

```http
GET /api/v1/my/say-hello
```

5. Click on the **Authorize** button to authenticate.
6. Try out the endpoint using the **Try it out** button.
7. Click on **Execute**.

![Trying out the endpoint](/files/EBPV6u2XufxB4MoctLSU)

You now get the response you have set up using the code: `"Hello, <user name>"`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.umbraco.com/umbraco-cms/18.latest/extend-your-project/server-side-extensions/custom-backoffice-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
