Andreas Ylivainio
OMVPPaaS CMS Administrator Certificationworkspace_premium +2
Feb 6, 2026
visibility 1033
star star star star star
(4 votes)

Using Scalar with Optimizely CMS

OpenAPI, Content Delivery API, and Modern API Documentation

Modern Optimizely CMS solutions are increasingly API-first. Whether you are building a headless frontend, integrating external services, or exposing internal platform APIs, having clear and discoverable API contracts is essential. With .NET 8, this becomes even more relevant, as the way API documentation is handled has subtly but importantly changed.

This article shows how to combine OpenAPI, Scalar, and Optimizely CMS to create a clean, future-proof API documentation setup. We’ll look at custom APIs, Optimizely Content Delivery, and how everything fits together in a single developer-friendly UI.

A complete working example is available here:
github.com/andreas-valtech/OptimizelyScalarContentDelivery


Swagger UI, .NET 8, and What Actually Changed

When upgrading to .NET 8+, many teams notice that Swagger UI no longer appears automatically in new ASP.NET Core projects. This can feel like something has been removed, but in practice it reflects a deliberate architectural shift.

In recent ASP.NET Core versions, Microsoft has separated OpenAPI document generation from API documentation user interfaces. The framework now focuses on producing a standards-compliant OpenAPI specification, while leaving the choice of UI entirely up to the application. Swagger UI is still fully supported via libraries such as Swashbuckle, but it is no longer assumed to be the default.

This separation reinforces an important idea: OpenAPI is the contract, not the UI. Once that contract exists, it can be rendered using Swagger UI, Scalar, or any other compatible tool. For Optimizely CMS solutions—where custom APIs, content delivery, search, and external integrations often live side by side—this flexibility is a clear advantage.


Generating OpenAPI in .NET 8

Swashbuckle remains the most common way to generate OpenAPI documents in ASP.NET Core.

After adding the Swashbuckle.AspNetCore package, you can configure OpenAPI generation directly in Startup.cs:

public class Startup(IWebHostEnvironment webHostingEnvironment)
{
    public void ConfigureServices(IServiceCollection services)
    {
... services.
AddCms(); // Content Delivery API services.AddContentDeliveryApi(options => { options.SiteDefinitionApiEnabled = true; }); // Content Delivery Search API services.AddContentSearchApi(options => { options.MaximumSearchResults = 10; }); // Swashbuckle services.AddEndpointsApiExplorer(); services.AddSwaggerGen(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... app.UseSwagger(); app.UseSwaggerUI(); app.UseEndpoints(endpoints => { endpoints.MapContent(); // Maps both Content Delivery API and Commerce Content Delivery API endpoints.MapSwagger("/openapi/{documentName}.json", options => { options.OpenApiVersion = OpenApiSpecVersion.OpenApi3_1; }); endpoints.MapScalarApiReference(options => { options.WithTitle("Alloy Example API"); }); }); } }

At this stage, it is worth clarifying what is happening in the pipeline. The MapSwagger() call comes from Microsoft’s OpenAPI support in ASP.NET Core and is responsible for exposing the generated OpenAPI document as JSON. It does not provide any user interface. Scalar is added separately and uses its MapScalarApiReference() extension method to build an API documentation UI on top of that contract. This includes all API controllers defined in the application, as well as any external OpenAPI (swagger.json) documents added to the project, such as those provided by Optimizely or other services. In this way, ASP.NET Core owns the generation of the OpenAPI specification, while Scalar is responsible for presenting both internal and external APIs in a single, unified view.


Scalar as the API Documentation UI

Scalar is a modern OpenAPI UI that consumes the same OpenAPI JSON but presents it in a cleaner, faster, and more developer-focused way. Because Scalar only depends on the OpenAPI specification, it fits perfectly with the direction ASP.NET Core has taken.

To set up scalar you can follow their getting started guide for ASP.NET Core here: https://scalar.com/products/api-references/integrations/aspnetcore/integration or use my linked GitHub project for reference.

Once Scalar is wired up, it automatically renders everything described in your OpenAPI document, including custom controllers, schemas, and authentication definitions.

To confirm everything works, a simple controller is enough:


[ApiController] 
[Route("api/hello")]
public class HelloController : ControllerBase
{ 
    [HttpGet]
    public IActionResult Get() => Ok(new { message = "Hello from Optimizely + Scalar" });
}


This endpoint is auto-discovered, included in the OpenAPI document, and immediately visible in Scalar without any additional configuration.


Bringing in Optimizely Content Delivery API

Optimizely provides official OpenAPI (swagger.json) definitions for its Content Delivery APIs. These can be downloaded from the Optimizely developer documentation:

https://docs.developers.optimizely.com/content-management-system/v1.5.0-content-delivery-api/reference/content-delivery-class-libraries-and-apis

By adding these JSON files directly to your project and serving them as static OpenAPI documents, Scalar can display Optimizely’s APIs alongside your own. This creates a single API surface where frontend and integration developers can explore both custom endpoints and content delivery endpoints in one place.

The Content Delivery API is central to headless Optimizely solutions, exposing pages, blocks, and content structures as JSON. Documenting it explicitly makes content contracts clearer and reduces friction between backend and frontend teams.


Content Management and Content Search APIs

In addition to content delivery, Optimizely’s Content Management and Content Search APIs are often part of larger integrations and automation workflows. Including their OpenAPI definitions in the same documentation UI improves internal developer experience and makes search queries, filters, and response structures easier to reason about.

Scalar handles multiple OpenAPI documents well, which makes it suitable as a lightweight internal API portal for Optimizely-based platforms.


External APIs and a Unified API View

Many Optimizely solutions integrate with external services such as commerce platforms, DAM systems, or personalization engines. When those services provide OpenAPI definitions, they can be included alongside Optimizely and custom APIs, giving teams a single, consistent documentation experience.


Example Repository

All of this is demonstrated in a runnable .NET 8 example here:
https://github.com/andreas-valtech/OptimizelyScalarContentDelivery/


What’s Next: Authentication with Keycloak

This article focuses on unauthenticated APIs. In the next part of the series, we’ll introduce authentication using Keycloak, covering OAuth 2.0 and OpenID Connect, securing both custom APIs and Optimizely Content Delivery endpoints, and documenting authentication flows in OpenAPI and Scalar.


Closing Thoughts

By treating OpenAPI as the primary contract and using a modern UI like Scalar, Optimizely CMS solutions align naturally with the direction of ASP.NET Core and modern headless architectures. The result is clearer APIs, better developer experience, and a setup that scales well as platforms grow more composable.

Feb 06, 2026

Comments

Daniil Zaiets
Daniil Zaiets Feb 6, 2026 11:46 AM

Andreas, excellent post!

error Please login to comment.
Latest blogs
Building UI Extensions for Optimizely SaaS CMS

Introduction Developers have been extending the functionality of Optimizely PaaS CMS for years using addons built in C# and deployed as NuGet...

Mark Stott | Oct 15, 2026

Cheapskate AI Translator: Because Translation Should Not Require a Second Mortgage

There is a particular kind of software project that begins with a detailed architecture document, a product roadmap, and a carefully assembled...

Linh Doan Cuu | Oct 15, 2026

Computed Fields in CMS 13 Content Contracts with Optimizely Graph

Content Contracts in Optimizely CMS 13 allow different content types to share a common structure when querying Optimizely Graph. But what if the...

Mardy | Oct 14, 2026

Opal Workflow Agents And The Graph Webhook Trap

What we did? We built a compliance review workflow agent in Opal. The job was simple: when an editor submits a page for review in Optimizely CMS 13...

Ritu Madan | Oct 14, 2026