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

Customize data returned to clients

Describes how to customize data returned to clients in the Optimizely Content Delivery API.

The following approaches customize how response data is returned for requests.

  1. Use Select parameter in endpoints.
  2. Use IContentFilter and IContentApiModelFilter.
  3. Use IPropertyConverter and IPropertyConverterProvider to convert from IContent to ContentApiModel. This approach is not addressed in this article.

(1) and (2) are described below, respectively, while (3) is addressed in Customize conversion from IContent to ContentApiModel.

Select parameter in endpoints

Endpoints in Content Delivery API let you filter data returned to requests by using the select parameter.

Assign the property names expected in the response to the parameter, separated by a comma. The value of this parameter is extracted and passed to ConverterContext.SelectedProperties for later use.

The following image shows an example with a Get endpoint, but the result format is the same for others also. For endpoints related to GetChildren and GetAncestor, data filtering is applied for each item returned to clients. Property names are not case-sensitive, and contentLink, name, and language are returned regardless of parameter value.


This feature cannot be applied to expanded values. Where clients send a request and expect properties to be expanded, the expanded value still shows full data without filtering it according to select. The following image shows this. Although some properties are passed in param, the expanded value pageImage still shows full data as normal.


Use IContentFilter and IContentApiModelFilter

Although IContentFIlter and IContentApiModelFilter was marked as Preview for safety purposes; they were stable and worth being used for customization. The preview may be removed in a coming .NET Core version of Content Delivery API.

The following diagram shows how IContent is converted into ContentAPIModel, which is then serialized and returned to clients. The select parameter in the request (described in Select parameter in endpoints) is extracted and passed to ConverterContext. It is then used by ContentApiModelMinifier to filter data.

This section focuses on two other ways to filter data with IContentFilter and IContentApiModelFilter.


The IContent Filtering phase takes responsibility to filter IContent data before it is converted to ContentApiModel. Within this phase, the IContent properties can be filtered according to specific rules. The following code sample shows an example of how to filter data using IContentFilter. The filter impactsExpandedValue also.

[ServiceConfiguration(typeof (IContentFilter), Lifecycle = ServiceInstanceScope.Singleton)]
internal class CustomContentFilter: ContentFilter < IContent > {
  public override void Filter(IContent content, ConverterContext converterContext) {

The code sample is simple, but you can use other services or HttpContext to do more filtering within the class (for example, pass some parameters in the request and extract them by using HttpContext or injected services for more data manipulation).

With the previous code example, the properties PageImage and MainContentArea are removed from IContent, meaning that they will not display in the conversion phase later. As a result, they will disappear in the result returned to clients. The downside of IContentFilter is that it is still not possible to remove some default properties of ContentApiModel like ExistingLanguages, MasterLanguage, and so on.



Some properties are mandatory (such as, PageLink and PageTypeID, if content is a page) and those should not be removed in the filter. Otherwise, exceptions are thrown in the conversion phase later on.


After IContent is converted to ContentApiModel, and before data is returned to clients (or minified based on a select parameter), you can filter the ContentApiModel data in the ContentApiModel Filtering phase, as shown in the following code sample. The sample uses the select parameter.

[ServiceConfiguration(typeof (IContentApiModelFilter), Lifecycle = ServiceInstanceScope.Singleton)]
internal class CustomContentApiModelFilter: ContentApiModelFilter < ContentApiModel > {
  public override void Filter(ContentApiModel contentApiModel, ConverterContext converterContext) {
    // Select param mentioned in the first part of article is retrieved and passed to ConverterContext.SelectedProperties
    // but it's only for the parent content. In case that clients contain childs that can be expanded, the param value is not served for them.
    // so that we need to extract param like the following if we want to apply select param for child elements.

    var selectedParamValue = string.Empty;
    if (HttpContext.Current.Request.QueryString["select"] == null) {

    selectedParamValue = HttpContext.Current.Request.QueryString["select"].ToString();
    var selectedProperties = string.IsNullOrWhiteSpace(selectedParamValue) ? new HashSet < string > () : new HashSet < string > (selectedParamValue.Split(',').Select(x => x.Trim()), StringComparer.OrdinalIgnoreCase);

    try {
      var dictProp = new Dictionary < string,
        object > ();
      contentApiModel.Properties = contentApiModel.Properties.Where(entry => selectedProperties.Contains(entry.Key))
        .ToDictionary(entry => entry.Key, entry => entry.Value);

      // Set those values below as null, and configure ContentApiOption.IncludeNullValues = false in Initialization
      // then, response data will not include those ones. 
      contentApiModel.ExistingLanguages = null;
      contentApiModel.MasterLanguage = null;
      contentApiModel.ParentLink = null;
      contentApiModel.Language = null;
      contentApiModel.StartPublish = null;
      contentApiModel.StopPublish = null;
    } catch (Exception ex) {

As in the previous example, IContentApiModelFilter lets you remove the default ContentApiModel properties and filter data returned by using select parameters. The filter is activated each time an IContent is converted to ContentApiModel. This means it affects nested elements or items in ContentArea in an expanded scenario, which also makes the response body much cleaner and lighter. ContentApiOption.IncludeNullValue should be set to false in the configuration for this sample.



In a case where the whole conversion phase should be customized for a specific reason, you can use ContentConvertingService (a public service) to fulfill the requirement. However, this is not recommended due to the complexity to handle IContent.