Custom Generated Client
Learn how to create a custom-generated client with TypeScript types for your OpenAPI specification.
Umbraco uses @hey-api/openapi-ts to generate its HTTP client for the OpenAPI specification of the Management API. It is available through the @umbraco-cms/backoffice/http-client package.
The following examples show how to generate a client from an OpenAPI specification and how to use it in the project. Below, the @hey-api/openapi-ts library is used, but the same principles apply to any other library that generates a TypeScript client.
Generate your own client
The generated client provides a convenient way to make requests to the specified API with type-safety without having to manually write the requests yourself. Consider generating a client to save time and reduce effort when working with custom API controllers.
To get started, install the generator using the following command:
npm install @hey-api/openapi-tsThen, use the openapi-ts command to generate a client from your OpenAPI specification:
npx openapi-ts --input https://example.com/openapi.json --output ./my-clientThis will generate a TypeScript client in the ./my-client folder. Import the generated client into your project to make requests to the Management API.
To learn more about OpenAPI and how to define your API specification, visit the OpenAPI Documentation.
Connecting to the Management API
Your generated client needs the correct base URL, credentials, and authentication to talk to the Management API. The recommended approach uses hey-api's runtimeConfigPath to inherit these settings automatically from the built-in backoffice HTTP client (umbHttpClient).
The Umbraco Extension Template already includes this setup. If you scaffolded your extension with dotnet new umbraco-extension, authentication works out of the box — no additional configuration needed.
Using runtimeConfigPath (recommended)
To pass plugin options like runtimeConfigPath, create a config file instead of using CLI flags.
Create
openapi-ts.config.tsin your project root:
Run the generator, which will pick up the config file automatically:
Create a
src/hey-api.tsfile and add the following:
This copies baseUrl, credentials, auth, and headers from the backoffice HTTP client into your generated client at initialization time. Extensions load after the backoffice is fully configured, so all values are available.
When the generator runs, the generated client.gen.ts will automatically import createClientConfig and apply it during client creation. Your SDK functions will be authenticated without any entrypoint setup.
Passing umbHttpClient directly
If you only have a few requests, you can skip client configuration entirely and pass umbHttpClient as the client parameter on each call:
The example above uses the backoffice HTTP client directly instead of the generated client. The umbHttpClient already has authentication and the correct base URL configured.
How security metadata works
The auth callback on umbHttpClient only fires when a request carries security metadata. Here is how that metadata flows from your API to the generated client:
Each operation in your OpenAPI spec has an optional
securityfield listing the security schemes it requires. Example:[{ "Backoffice-User": [] }].Those scheme names are defined in
components.securitySchemes, where their type (OAuth2, HTTP Bearer, and so on) is declared.When hey-api generates your client, it reads both and resolves them into its own runtime shape -
security: [{ type: 'http', scheme: 'bearer' }]- emitted directly into each generated SDK function.
The resolved shape is what umbHttpClient checks before invoking the auth callback.
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 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 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:
No AddSecurityDefinition call is needed — AddBackofficeSecurityRequirements() adds it. Once in place, hey-api will generate SDK functions with the correct security metadata.
For a complete walkthrough of setting up a custom API, see Creating a Backoffice API, Custom Backoffice API, and API versioning and OpenAPI.
Direct calls without a generated client
When calling umbHttpClient directly — without a generated SDK function — there is no spec to derive security metadata from. Pass it explicitly on each call:
See Umbraco HTTP Client for more details.
Fetch API
If you only have a few requests, you can also use the fetch function directly. Read more about that here:
Further reading
Last updated
Was this helpful?