HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Set up headless Optimizely Forms API

Describes the most important steps to get started with Optimizely Headless Form API.

👍

Beta

Headless Optimizely Forms is in beta. Its functionality may change drastically during the development. This should be used only for internal testing and not be used in production.

See Optimizely Forms for information about generally available Forms.

📘

Note

Headless Optimizely Forms is only supported by MVC-based websites and HTML5-compliant browsers.

Install packages

Prerequisite: install Episerver.Forms using the NuGet Package Manager in Visual Studio or with the command line:

dotnet add package EPiServer.Forms

Optimizely Headless Form API consists of one main NuGet package, Optimizely.Headless.Form.Service, and some additional NuGet packages let you install only the necessary functionality.

Install the NuGet packages in your solution using the NuGet Package Manager in Visual Studio or with the command line:

dotnet add package Optimizely.Headless.Form.Service

For authentication, install Episerver.OpenIDConnect package using the NuGet Package Manager in Visual Studio or with the command line:

dotnet add package Episerver.OpenIDConnect

Configure form headless API options

Configure the API in ConfigureServices in startup.cs.

services.AddOptimizelyHeadlessFormService(options => {
  options.EnableOpenApiDocumentation = true;
  options.FormCorsPolicy = new FormCorsPolicy {
    AllowOrigins = new string[] {
        "*"
      }, //Enter '*' to allow any origins, multiple origins separate by comma  
      AllowCredentials = true
  };
  options.OpenIDConnectClients.Add(new() {
    Authority = "" //Enter the client's domain that needs authentication.  
  });
});

Configure encryption key for OpenIDConnect.

public class HeadlessFormServiceOptionsPostConfigure: IPostConfigureOptions < HeadlessFormServiceOptions > {
  private readonly OpenIddictServerOptions _options;

  public HeadlessFormServiceOptionsPostConfigure(IOptions < OpenIddictServerOptions > options) {
    _options = options.Value;
  }

  public void PostConfigure(string name, HeadlessFormServiceOptions options) {
    foreach(var client in options.OpenIDConnectClients) {
      foreach(var key in _options.EncryptionCredentials.Select(c => c.Key)) {
        client.EncryptionKeys.Add(key);
      }
    }
  }
}

Configure OpenIdConnect in Startup.cs.

services.AddOpenIDConnect < ApplicationUser > (
  useDevelopmentCertificate: true,
  signingCertificate: null,
  encryptionCertificate: null,
  createSchema: true,
  options => {
    options.AllowResourceOwnerPasswordFlow = true;
    options.AccessTokenLifetime = TimeSpan.FromHours(8);
    options.RequireHttps = false;
    options.Applications.Add(new OpenIDConnectApplication {
      ClientId = "ClientId",
        Scopes = {
          Scopes.OpenId,
        },
    });
  });

services.TryAddEnumerable(ServiceDescriptor.Singleton < IPostConfigureOptions < HeadlessFormServiceOptions > , HeadlessFormServiceOptionsPostConfigure > ());

Test and verify the API.

POST or GET endpoint description

You should have the following endpoints available on your host site:

  • GET – /_form/v1/form/{ContentGuid}?language={Language} – Retrieve form data with form elements by content guid
  • POST – /_form/v1/form/ – Submit the form.

To verify that the API is working properly, open the Form Headless API in your browser:

http://<your-site-url>/_form/v1/form/<ContentGuid>?language=en

You should now get a 200 OK response and see the site and its associated properties:

{
  "key": "41A07E4D3A634CC581F399CAAC75789C",
  "properties": {
    "title": "",
    "allowToStoreSubmissionData": true,
    "description": "",
    "showSummarizedData": false,
    "confirmationMessage": "",
    "resetConfirmationMessage": "",
    "redirectToPage": "",
    "submitSuccessMessage": "",
    "allowAnonymousSubmission": false,
    "allowMultipleSubmission": false,
    "showNavigationBar": false
  },
  "formElements": [{
      "key": "2933aa8d3e794ccf89ff63bd9746d9f8",
      "contentType": "SelectionElementBlock",
      "displayName": "Selection",
      "properties": {
        "label": "Selection",
        "description": "",
        "validators": [{
          "type": "RequiredValidator",
          "description": null,
          "model": {
            "message": "This field is required.",
            "validationCssClass": "ValidationRequired",
            "additionalAttributes": {
              "required": "",
              "aria-required": "true"
            }
          }
        }],
        "allowMultiSelect": false,
        "feed": "FormsFeed_UseManualInput",
        "items": [{
            "caption": "Value1",
            "value": "Value1",
            "checked": true
          },
          {
            "caption": "Value2",
            "value": "Value2",
            "checked": false
          }
        ],
        "placeHolder": "",
        "autoComplete": "",
        "satisfiedAction": "",
        "conditionCombination": "All",
        "conditions": ""
      },
      "localizations": {
        "selectionDefaultPlaceholder": "-- Select an option --"
      }
    },
    {
      "key": "362b97255ed0483aa096f062e189d857",
      "contentType": "NumberElementBlock",
      "displayName": "Number",
      "properties": {
        "label": "Number",
        "description": "",
        "validators": [{
          "type": "NumericValidator",
          "description": null,
          "model": {
            "message": "Enter a valid number.",
            "validationCssClass": null,
            "additionalAttributes": null
          }
        }],
        "placeHolder": "",
        "autoComplete": "",
        "satisfiedAction": "",
        "conditionCombination": "All",
        "conditions": ""
      },
      "localizations": {}
    },
    {
      "key": "05524d25f3084ba6b2437e4529ddcdcb",
      "contentType": "FormStepBlock",
      "displayName": "Form step",
      "properties": {
        "label": "",
        "description": "",
        "attachedContentLink": "",
        "dependCondition": "",
        "dependValue": ""
      },
      "localizations": {
        "previousButtonLabel": "Previous step",
        "nextButtonLabel": "Next step",
        "pageButtonLabel": "Step"
      }
    },
    {
      "key": "426f2661d0da4751955bfc67503c556d",
      "contentType": "TextareaElementBlock",
      "displayName": "Text area",
      "properties": {
        "label": "Text area",
        "description": "",
        "validators": [],
        "placeHolder": "",
        "autoComplete": "",
        "satisfiedAction": "",
        "conditionCombination": "All",
        "conditions": ""
      },
      "localizations": {}
    },
    {
      "key": "97dd12c78d88450695dd231216c8dc1d",
      "contentType": "SubmitButtonElementBlock",
      "displayName": "Submit button",
      "properties": {
        "finalizeForm": false,
        "label": "Submit",
        "image": "",
        "description": "",
        "redirectToPage": "",
        "satisfiedAction": "",
        "conditionCombination": "All",
        "conditions": ""
      },
      "localizations": {
        "label": "Submit"
      }
    }
  ],
  "locale": "en",
  "localizations": {
    "allowAnonymousSubmissionErrorMessage": "You must be logged in to submit this form. If you are logged in and still cannot post, make sure \"Do not track\" in your browser settings is disabled.",
    "allowMultipleSubmissionErrorMessage": "You already submitted this form."
  }
}

Configure Swagger

Install the NuGet packages in your solution using the NuGet Package Manager in Visual Studio or with the command line:

dotnet add package Swashbuckle.AspNetCore

Configure Swagger in startup.cs.

services.AddSwaggerGen(c => {
  c.SwaggerDoc("v1", new OpenApiInfo {
    Title = "AlloySampleSite Custom API",
      Version = "v1",
  });
});

app.UseSwagger();

app.UseSwaggerUI(options => {
  options.SwaggerEndpoint("/_form/v1/docs/openapi.json", "Optimizely Headless Form API V1");
  options.SwaggerEndpoint("/swagger/v1/swagger.json", "AlloySampleSite Custom API V1");
  options.OAuthClientId("ClientId");
  options.OAuthClientSecret("ClientSecret");
});

Use Postman

Postman (postman.com) is a free tool that you can use as an API client to send REST calls. With Postman, you can connect to APIs and simulate calls to endpoints and their responses without setting up a backend server.
To test the Form Headless API, you can use a tool such as Postman and send a request to one of the endpoints mentioned in the above section.