I need to enable headless architecture in Optimizely CMS 13

Vote:
 

Hi,

 

I have setup Optimizely CMS 13 now I wanted to enable headless. I need to understant what changes I need to do in the code and how API would be accessible? Content Delivery API are not supported in CMS 13? .

 

Startup.cs

public class Startup(IWebHostEnvironment webHostingEnvironment)
{
    public void ConfigureServices(IServiceCollection services)
    {
        if (webHostingEnvironment.IsDevelopment())
        {
            AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(webHostingEnvironment.ContentRootPath, "App_Data"));

            services.Configure<SchedulerOptions>(options => options.Enabled = false);
        }

        services.Configure<DataAccessOptions>(o => o.UpdateDatabaseCompatibilityLevel = true);

        services
            .AddCmsAspNetIdentity<ApplicationUser>()
            .AddCms()
            .AddAlloy()
            .AddAdminUserRegistration()
            .AddEmbeddedLocalization<Startup>();


        // Required by Wangkanai.Detection
        services.AddDetection();

        services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromSeconds(10);
            options.Cookie.HttpOnly = true;
            options.Cookie.IsEssential = true;
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        // Required by Wangkanai.Detection
        app.UseDetection();
        app.UseSession();

        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapContent();
        });
    }
}

 

Regards

-Owais

#342812
Jun 17, 2026 12:37
Vote:
 

Hey Owais,

You're right to ask - the delivery story changed in CMS 13.

The old REST Content Delivery API is gone. 
In CMS 13, delivery happens through 
Optimizely Graph (GraphQL).
It's not something you "enable" with a NuGet package like before - it's a separate service that syncs your content to a global index and exposes a GraphQL endpoint
.

What you do get out of the box with AddCms() is the CMS REST API - but that's for content management (creating/updating content programmatically), not for headless delivery.

So what do you actually need to do?

  1. Set up an Optimizely Graph subscription (it's a separate offering).

  2. Configure the connection in your app settings (endpoint + API key).

  3. Your frontend hits the GraphQL endpoint, not your CMS directly.

Your Startup.cs looks fine for a traditional CMS setup - you don't need to change anything there for headless delivery. The headless part happens outside your CMS app.

Hope that clears it up

#342813
Jun 17, 2026 15:46
Vote:
 

Hi Nikhil,

How can I enable graph on my local CMS 13. I have demo keys. 

Regards

-Owais

#342824
Jun 18, 2026 9:42
Vote:
 

Hey Owais,

So your Startup.cs looks good for a regular CMS setup. But to enable headless delivery through Graph, you need to add a few things.

First, install these two NuGet packages:

 

dotnet add package Optimizely.Graph.Cms
dotnet add package EPiServer.Cms.UI.ContentManager

 

The first one handles syncing your content to Graph and the actual GraphQL delivery. The second one gives you the Content Manager UI which is now powered by Graph in CMS 13. In CMS 13, the Graph integration comes with the platform so you don't need a separate sync package like you might have used in CMS 12.

Now for the code changes. Update your ConfigureServices method. The order matters here - you need to call AddContentGraph() first, then AddContentManager() right after. If you do it the other way around, you'll get dependency errors.

Here's what your updated ConfigureServices should look like:

public void ConfigureServices(IServiceCollection services)
{
    if (webHostingEnvironment.IsDevelopment())
    {
        AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(webHostingEnvironment.ContentRootPath, "App_Data"));
        services.Configure<SchedulerOptions>(options => options.Enabled = false);
    }

    services.Configure<DataAccessOptions>(o => o.UpdateDatabaseCompatibilityLevel = true);

    services
        .AddCmsAspNetIdentity<ApplicationUser>()
        .AddCms()
        .AddAlloy()
        .AddAdminUserRegistration()
        .AddEmbeddedLocalization<Startup>();

    // Add these two lines in this order
    services.AddContentGraph();
    services.AddContentManager();

    services.AddDetection();
    services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromSeconds(10);
        options.Cookie.HttpOnly = true;
        options.Cookie.IsEssential = true;
    });
}

You also need to add the Graph configuration to your appsettings.json:

```json

{
  "Optimizely": {
    "ContentGraph": {
      "GatewayAddress": "https://cg.optimizely.com",
      "AllowSendingLog": "true",
      "AppKey": "your-app-key-here",
      "Secret": "your-secret-here",
      "SingleKey": "your-single-key-here"
    }
  }
}


```

The AppKey and Secret are your admin credentials - these are used by the sync agent to push content from your CMS to Graph. Keep these server-side only. The SingleKey is what your frontend uses for public queries. And the GatewayAddress is the base endpoint for the GraphQL service.

Now about your keys. Since you mentioned you have demo keys, those are what you should use here. If you're not sure where to find them - if you're on DXP, you can find them in the PaaS Portal under the API tab for your project. If you're on SaaS, you can generate them yourself from CMS > Settings > API Keys.

Once you've made these changes and deployed, the integration agent will do an initial handshake with the Graph service to set up the schemas. You'll see log entries confirming that the schema has been provisioned. After that, your content will start syncing to Graph and you can query it from your frontend using the GraphQL endpoint with your SingleKey.

Your existing Startup.cs looks fine otherwise - you don't need to change AddCms() or AddAlloy(). You're just adding Graph on top of what you already have.

Hope that helps !

#342826
Edited, Jun 18, 2026 14:14
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.