HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Catalogs

Describes how to work with RESTful operations for catalogs in the Optimizely Service API.

The Service API supports published versions of catalogs (from version 1.0 and higher) and common draft versions of catalogs (from version 5.1.0).

Example models

/// <summary>
/// The catalog base model.
/// </summary>
[Serializable]
public abstract class CatalogBase
  {
    /// <summary>
    /// Gets or sets the end date.
    /// </summary>
    /// <value>
    /// The end date.
    /// </value>
    public DateTime EndDate { get; set; }

    /// <summary>
    /// Gets or sets the start date.
    /// </summary>
    /// <value>
    /// The start date.
    /// </value>
    public DateTime StartDate { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether this instance is primary.
    /// </summary>
    /// <value>
    /// <c>true</c> if this instance is primary; otherwise, <c>false</c>.
    /// </value>
    public bool IsPrimary { get; set; }

    /// <summary>
    /// Gets or sets the owner.
    /// </summary>
    /// <value>
    /// The owner.
    /// </value>
    public string Owner { get; set; }

    /// <summary>
    /// Gets or sets the sort order.
    /// </summary>
    /// <value>
    /// The sort order.
    /// </value>
    public int SortOrder { get; set; }

    /// <summary>
    /// Gets or sets the name.
    /// </summary>
    /// <value>
    /// The name.
    /// </value>
    public string Name { get; set; }

    /// <summary>
    /// Gets or sets the default currency.
    /// </summary>
    /// <value>
    /// The default currency.
    /// </value>
    public string DefaultCurrency { get; set; }

    /// <summary>
    /// Gets or sets the default language.
    /// </summary>
    /// <value>
    /// The default language.
    /// </value>
    public string DefaultLanguage { get; set; }

    /// <summary>
    /// Gets or sets the weight base.
    /// </summary>
    /// <value>
    /// The weight base.
    /// </value>
    public string WeightBase { get; set; }

    /// <summary>
    /// Gets or sets the length base.
    /// </summary>
    /// <value>
    /// The length base.
    /// </value>
    public string LengthBase { get; set; }
  }

/// <summary>
/// The catalog model.
/// </summary>
[Serializable]
public class Catalog: CatalogBase
  {
    /// <summary>
    /// Gets or sets a value indicating whether this instance is active.
    /// </summary>
    /// <value>
    ///   <c>true</c> if this instance is active; otherwise, <c>false</c>.
    /// </value>
    public bool IsActive { get; set; }

    /// <summary>
    /// Gets or sets the languages.
    /// </summary>
    /// <value>
    /// The languages.
    /// </value>
    public List<CatalogLanguage> Languages { get; set; }

    /// <summary>
    /// Gets or sets the nodes.
    /// </summary>
    /// <value>The nodes.</value>
    public List<ResourceLink> Nodes { get; set; }

    /// <summary>
    /// Gets or sets the entries.
    /// </summary>
    /// <value>
    /// The entries.
    /// </value>
    public List<ResourceLink> Entries { get; set; }
  }

/// <summary>
/// The draft catalog model.
/// </summary>
[Serializable]
public class DraftCatalog : CatalogBase
  {
    /// <summary>
    /// Gets or sets the route segment.
    /// </summary>
    /// <value>The route segment.</value>
    public string RouteSegment { get; set; }
  }

Published catalog version

Get all catalogs

GETget/episerverapi/commerce/catalogsGet all catalogs

JSON response type

var client = new HttpClient()
  {
    BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
  };

client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);

var result = client.Get("/episerverapi/commerce/catalogs").Result.Content.ReadAsStringAsync().Result;

XML response type

var client = new HttpClient()
 {
   BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
 };

client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));

var result = client.GetAsync("/episerverapi/commerce/catalogs").Result.Content.ReadAsStringAsync().Result;

Response

<ArrayOfCatalog xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Catalog>
    <EndDate>2022-01-16T05:51:00Z</EndDate>
    <StartDate>2012-01-16T05:51:00Z</StartDate>
    <IsPrimary>false</IsPrimary>
    <SortOrder>0</SortOrder>
    <Name>Departmental Catalog</Name>
    <DefaultCurrency>usd</DefaultCurrency>
    <DefaultLanguage>en</DefaultLanguage>
    <WeightBase>lbs</WeightBase>
    <LengthBase />
    <IsActive>true</IsActive>
    <Languages>
      <CatalogLanguage>
        <LanguageCode>en</LanguageCode>
        <Catalog>Departmental Catalog</Catalog>
        <UriSegment>departmental-catalog</UriSegment>
      </CatalogLanguage>
    </Languages>
    <Nodes>
      <ResourceLink>
        <Title>Departments</Title>
        <Type>CatalogNode</Type>
        <Href>/episerverapi/commerce/nodes/Departments</Href>
        <Properties>
          <NameValue>
            <Name>Code</Name>
            <Value>Departments</Value>
          </NameValue>
        </Properties>
      </ResourceLink>
    </Nodes>
    <Entries />
  </Catalog>
</ArrayOfCatalog>

Get a specific catalog

GETget/episerverapi/commerce/catalogs/{catalogName}Get a specific catalog

JSON response type

var client = new HttpClient()
 {
   BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
 };

client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);

var result = client.Get("/episerverapi/commerce/catalogs/Departmental Catalog").Result.Content.ReadAsStringAsync().Result;

XML response type

var client = new HttpClient()
 {
   BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
 };

client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));

var result = client.GetAsync("episerverapi/commerce/catalogs/Departmental Catalog").Result.Content.ReadAsStringAsync().Result;

Response

<Catalog xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <EndDate>2022-01-16T05:51:00Z</EndDate>
  <StartDate>2012-01-16T05:51:00Z</StartDate>
  <IsPrimary>false</IsPrimary>
  <SortOrder>0</SortOrder>
  <Name>Departmental Catalog</Name>
  <DefaultCurrency>usd</DefaultCurrency>
  <DefaultLanguage>en</DefaultLanguage>
  <WeightBase>lbs</WeightBase>
  <LengthBase />
  <IsActive>true</IsActive>
  <Languages>
    <CatalogLanguage>
      <LanguageCode>en</LanguageCode>
      <Catalog>Departmental Catalog</Catalog>
      <UriSegment>departmental-catalog</UriSegment>
    </CatalogLanguage>
  </Languages>
  <Nodes>
    <ResourceLink>
      <Title>Departments</Title>
      <Type>CatalogNode</Type>
      <Href>/episerverapi/commerce/nodes/Departments</Href>
      <Properties>
        <NameValue>
          <Name>Code</Name>
          <Value>Departments</Value>
        </NameValue>
      </Properties>
    </ResourceLink>
  </Nodes>
  <Entries />
</Catalog>

Create catalog

POSTpost/episerverapi/commerce/catalogsCreate catalog

JSON response type

var model = new Catalog()
  {
    DefaultCurrency = "usd",
    DefaultLanguage = "en",
    EndDate = DateTime.UtcNow.AddYears(1),
    IsActive = true,
    IsPrimary = true,
    Languages = new List<CatalogLanguage>()
      {
        new CatalogLanguage()
          {
            Catalog = "Test Post",
            LanguageCode = "en",
            UriSegment = "Test-Post"
          }
      },
    Name = "Test Post",
    StartDate = DateTime.UtcNow,
    WeightBase = "lbs"
  };                

var json = JsonConvert.SerializeObject(model);
var client = new HttpClient()
 {
   BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
 };
client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);

var result = client.PostAsync("/episerverapi/commerce/catalogs", new StringContent(json, Encoding.UTF8, "application/json")).Result.Content.ReadAsStringAsync().Result;

XML response type

var model = new Catalog()
  {
    DefaultCurrency = "usd",
    DefaultLanguage = "en",
    EndDate = DateTime.UtcNow.AddYears(1),
    IsActive = true,
    IsPrimary = true,
    Languages = new List<CatalogLanguage>()
      {
        new CatalogLanguage()
          {
            Catalog = "Test Post",
            LanguageCode = "en",
            UriSegment = "Test-Post"
          }
      },
    Name = "Test Post",
    StartDate = DateTime.UtcNow,
    WeightBase = "lbs"
  };       

var client = new HttpClient()
  {
   BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
  };

client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);

var serializer = new XmlSerializer(typeof(Catalog));
var xml = string.Empty;
using (var ms = new MemoryStream())
 {
   serializer.Serialize(ms, model);
   xml = Encoding.Default.GetString(ms.ToArray());
 }

var result = client.PostAsync("/episerverapi/commerce/catalogs", new StringContent(xml, Encoding.UTF8, "text/xml")).Result.Content.ReadAsStringAsync().Result;

Response

<Catalog xmlns:xsd="http://www.w3.org/2001/XMLSchema"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <EndDate>2019-11-05T07:00:34.0493309Z</EndDate>
  <StartDate>2018-11-05T07:00:34.0498153Z</StartDate>
  <IsPrimary>true</IsPrimary>
  <SortOrder>0</SortOrder>
  <Name>Test Post</Name>
  <DefaultCurrency>usd</DefaultCurrency>
  <DefaultLanguage>en</DefaultLanguage>
  <WeightBase>lbs</WeightBase>
  <IsActive>true</IsActive>
  <Languages>
    <CatalogLanguage>
      <LanguageCode>en</LanguageCode>
      <Catalog>Test Post</Catalog>
      <UriSegment>Test-Post</UriSegment>
    </CatalogLanguage>
  </Languages>
  <Nodes />
  <Entries />
</Catalog>

Update catalog

PUTput/episerverapi/commerce/catalogs/{catalogName}Update catalog

JSON response type

var model = new Catalog()
  {
    DefaultCurrency = "vnd",
    DefaultLanguage = "en",
    EndDate = DateTime.UtcNow.AddYears(1),
    IsActive = true,
    IsPrimary = true,
    Languages = new List<CatalogLanguage>()
      {
        new CatalogLanguage()
          {
            Catalog = "Test Post",
            LanguageCode = "en",
            UriSegment = "Test-Post"
          }
      },
    Name = "Test Post",
    StartDate = DateTime.UtcNow,
    WeightBase = "lbs"
  };                

var json = JsonConvert.SerializeObject(model);
var client = new HttpClient()
  {
    BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
   };
client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);

var result = client.PutAsync("/episerverapi/commerce/catalogs/Test Post", new StringContent(json, Encoding.UTF8, "application/json")).Result.Content.ReadAsStringAsync().Result;

XML response type

var model = new Catalog()
  {
    DefaultCurrency = "usd",
    DefaultLanguage = "en",
    EndDate = DateTime.UtcNow.AddYears(1),
    IsActive = true,
    IsPrimary = true,
    Languages = new List<CatalogLanguage>()
      {
        new CatalogLanguage()
          {
            Catalog = "Test Post",
            LanguageCode = "en",
            UriSegment = "Test-Post"
          }
      },
    Name = "Test Post",
    StartDate = DateTime.UtcNow,
    WeightBase = "lbs"
  };                

var serializer = new XmlSerializer(typeof(Catalog));
var xml = string.Empty;
using (var ms = new MemoryStream())
  {
    serializer.Serialize(ms, model);
    xml = Encoding.Default.GetString(ms.ToArray());
  }

var result = client.PutAsync("/episerverapi/commerce/catalogs/Test Post", new StringContent(xml, Encoding.UTF8, "text/xml")).Result.Content.ReadAsStringAsync().Result;

Response

204 No Content

Delete catalog

DELETEdelete/episerverapi/commerce/catalogs/{catalogName}Delete catalog

JSON response type

var client = new HttpClient()
  {
     BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
  };

client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);

var result = client.DeleteAsync("/episerverapi/commerce/catalogs/Test Catalog").Result.Content.ReadAsStringAsync().Result;

XML response type

var client = new HttpClient()
   {
     BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
   };

client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));

var result = client.DeleteAsync("/episerverapi/commerce/catalogs/Test Catalog).Result.Content.ReadAsStringAsync().Result;

Response

200 OK

Common draft catalog version [New in 5.1.0]

From version 5.1.0, the Service API supports working with a common draft catalog. By adding endpoints described in the following, you can get common draft catalog versions, create new common drafts, and update or delete existing common draft catalogs.

Get common draft catalog

GETget/episerverapi/commerce/catalogs/{catalogName}/commondraft/{lang}Get common draft catalog

JSON response type

C# code sample

var client = new HttpClient()
  {
    BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
  };

client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);

var result = client.GetAsync("/episerverapi/commerce/catalogs/Integration Test/commondraft/en").Result.Content.ReadAsStringAsync().Result;

XML response type

var client = new HttpClient()
  {
    BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
  };

client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));

var result = client.GetAsync("/episerverapi/commerce/catalogs/Integration Test/commondraft/en").Result.Content.ReadAsStringAsync().Result;

Response

<?xml version="1.0" encoding="UTF-8"?>
<DraftCatalog>
  <DefaultCurrency>eur</DefaultCurrency>
  <DefaultLanguage>en</DefaultLanguage>
  <EndDate>2020-07-26T07:28:44.733Z</EndDate>
  <IsPrimary>true</IsPrimary>
  <Name>Integration Test</Name>
  <Owner null="true"/>
  <RouteSegment>integration-test</RouteSegment>
  <SortOrder>0</SortOrder>
  <StartDate>2017-07-26T07:28:44.733Z</StartDate>
  <WeightBase>kgs</WeightBase>
</DraftCatalog>

Create common draft catalog

📘

Note

Optimizely does not support creating common drafts for non-existing content. You can create a first draft version by using an endpoint for published content (without “commondraft”) and setting IsActive to “false”.

POSTpost/episerverapi/commerce/catalogs/commondraft/{lang}Create common draft catalog

JSON response type

var _model = new DraftCatalog()
  {
    DefaultCurrency = "usd",
    DefaultLanguage = "en",
    EndDate = DateTime.UtcNow.AddYears(1),
    IsPrimary = true,
    Name = "Test Common Draft Catalog Post",
    StartDate = DateTime.UtcNow,
    WeightBase = "lbs",
    LengthBase = "cms",
    RouteSegment = "common_drart_catalog.aspx"
  };

var json = JsonConvert.SerializeObject(_model);
var client = new HttpClient()
  {
    BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
  };
client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);

var result = client.PostAsync("/episerverapi/commerce/catalogs/commondraft/en", new StringContent(json, Encoding.UTF8, "application/json")).Result.Content.ReadAsStringAsync().Result;

XML response type

var _model = new DraftCatalog()
  {
    DefaultCurrency = "usd",
    DefaultLanguage = "en",
    EndDate = DateTime.UtcNow.AddYears(1),
    IsPrimary = true,
    Name = "Test Common Draft Catalog Post",
    StartDate = DateTime.UtcNow,
    WeightBase = "lbs",
    LengthBase = "cms",
    RouteSegment = "common_drart_catalog.aspx"
  };
var client = new HttpClient()
  {
    BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
  };

client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);
			
var serializer = new XmlSerializer(typeof(DraftCatalog));
var xml = string.Empty;
using (var ms = new MemoryStream())
  {
    serializer.Serialize(ms, _model);
    xml = Encoding.Default.GetString(ms.ToArray());
  }

var result = client.PostAsync("/episerverapi/commerce/catalogs/commondraft/en", new StringContent(xml, Encoding.UTF8, "text/xml")).Result.Content.ReadAsStringAsync().Result;

Response

<?xml version="1.0"?>
<DraftCatalog xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <EndDate>2019-06-08T09:55:58.9975809Z</EndDate>
  <StartDate>2018-06-08T09:55:58.9975809Z</StartDate>
  <IsPrimary>true</IsPrimary>
  <SortOrder>0</SortOrder>
  <Name>Test Common Draft Catalog Post</Name>
  <DefaultCurrency>usd</DefaultCurrency>
  <DefaultLanguage>en</DefaultLanguage>
  <WeightBase>lbs</WeightBase>
  <RouteSegment>common_drart_catalog.aspx</RouteSegment>
</DraftCatalog>

Update common draft catalog

📘

Note

If common draft content is in a “Published” state, then a new common draft version is created (same behavior as Post common draft). If a common draft content is in DelayedPublish/AwaitingApproval/CheckedIn state, then content update is skipped, and a Conflict status code (409) is returned.

PUTput/episerverapi/commerce/catalogs/{catalogName}/commondraft/{lang}Update common draft catalog

JSON response type

ar catalogName = "Integration Test";
var catalogContents = ContentLoader.GetChildren<CatalogContent>(ReferenceConverter.GetRootLink());
var catalogContent = catalogContents.FirstOrDefault(c => c.Name.Equals(catalogName, StringComparison.OrdinalIgnoreCase));
if (catalogContent != null)
  {
    _model = ServiceLocator.Instance.GetInstance<CatalogModelFactory>() .GetDraftCatalog(catalogContent);
    _model.RouteSegment = "New_Route_Segment";
    var json = JsonConvert.SerializeObject(_model);
    var client = new HttpClient()
      {
       	BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
      };
    client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);
    var result = client.PutAsync($"/episerverapi/commerce/catalogs/{catalogName}/commondraft/en",
      new StringContent(json, Encoding.UTF8, "application/json")).Result.Content.ReadAsStringAsync().Result;
  }

XML response type

var catalogName = "Integration Test";
var catalogContents = ContentLoader.GetChildren<CatalogContent>(ReferenceConverter.GetRootLink());
var catalogContent = catalogContents.FirstOrDefault(c => c.Name.Equals(catalogName, StringComparison.OrdinalIgnoreCase));
if (catalogContent != null)
  {
    _model = ServiceLocator.Instance.GetInstance<CatalogModelFactory>() .GetDraftCatalog(catalogContent);
    _model.RouteSegment = "New_Route_Segment";
    var client = new HttpClient()
      {
        BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
      };
    client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);
    var serializer = new XmlSerializer(typeof(DraftCatalog));
    var xml = string.Empty;
    using (var ms = new MemoryStream())
      {
        serializer.Serialize(ms, _model);
        xml = Encoding.Default.GetString(ms.ToArray());
      }
    var result = client.PutAsync($"/episerverapi/commerce/catalogs/{catalogName}/commondraft/en",
      new StringContent(xml, Encoding.UTF8, "text/xml")).Result.Content.ReadAsStringAsync().Result;
  }

Response

204 No Content

Delete common draft catalog

DELETEdelete/episerverapi/commerce/catalogs/{catalogName}/commondraft/{lang}Delete common draft catalog

JSON response type

var client = new HttpClient()
  {
    BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
  };

client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);

var result = client.DeleteAsync("/episerverapi/commerce/catalogs/Integration Test/commondraft/en").Result.Content.ReadAsStringAsync().Result;

XML response type

var client = new HttpClient()
   {
     BaseAddress = new Uri(ConfigurationManager.AppSettings["integrationUrl"])
   };
client.DefaultRequestHeaders.Authorization = new AuthorizationHeaderValue("Bearer", token.AccessToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
var result = client.DeleteAsync("/episerverapi/commerce/catalogs/Integration Test/commondraft/en").Result.Content.ReadAsStringAsync().Result;

Response

200 OK