Disclaimer: This website requires JavaScript to function properly. Some features may not work as expected. Please enable JavaScript in your browser settings for the best experience.

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

Examples of Content Management API

Describes examples of how the Optimizely Content Management API might be used.

To keep the examples short, they generally favor using integer-based content references instead of GUIDs.

GET/api/episerver/v3.0/contentGet content by given content URL or by list of GUID or Reference with a given language

Be aware:

  • The API implicitly uses the primary draft when changing and publishing content.
  • Manipulating personalization in content areas is not currently supported. For example, you cannot change or add a specific visitor group on a specific item in a content area through the Optimizely Content Management API.
  • ContentReference in endpoints should not include workID (for example, 5_5). An exception is thrown if workID is included.

A simple content sync

The simplest way to push content to the CMS is to assume the integration process always has right-of-way and that no one else is making significant changes to the same part of the content tree. With these limitations in mind, you can use PUT to upsert objects, which will pave over existing content: /api/episerver/v3.0/contentmanagement/

PUT/api/episerver/v3.0/contentmanagement/{contentGuid}
curl --location --request PUT "http://<YOUR_DOMAIN>/api/episerver/v3.0/contentmanagement/7fa446db-6e02-41c5-9d3a-06e1b4d75cdf" ^ 
--header "Content-Type: application/json" ^
--header "Authorization: Bearer <AUTH_TOKEN>" ^
--data-raw "{'name': 'Alloy Track','language': {'name': 'sv'},'contentType':['ProductPage'],'parentLink': {'id': 5},'status': 'CheckedOut','metaTitle': {'value': 'Alloy Track Updated'},'uniqueSellingPoints': {'value': ['Shared timeline','Project emails','To-do lists','Workflows','Status reports']}}"

You can rely on PUT to control the incoming content and specify Published status from the API to publish the content directly. Using the default Checkout status requires another manual or API action to publish changes. You can use the endpoint to create an existing content item in a specific language.

A smarter content sync

Upserts are easy to work with but can be wasteful when an entire object is sent, even when a single property is updated. You can build a more efficient integration with POST and PATCH (instead of PUT) to determine when an object is new or changed (and which properties were changed) in the source system.

You create a content item by POSTing an object. Use this POST endpoint to create an existing content item in a specific language. See Translating content below for more details.

POST/api/episerver/v3.0/contentmanagement
curl --location --request POST "http://<YOUR_DOMAIN>/api/episerver/v3.0/contentmanagement" ^ 
--header "Content-Type: application/json" ^ 
--header "Authorization: Bearer <AUTH_TOKEN>" ^ 
--data-raw "{'name': 'Alloy Track','language': {'name': 'sv'},'contentType': ['ProductPage'],'parentLink': {'id': 5},'status': 'CheckedOut','metaTitle': {'value': 'Alloy Track SV'},'uniqueSellingPoints': {'value': ['Shared timeline','Project emails','To-do lists','Workflows','Status reports']}}"

Save changes to an existing object by PATCHing an object, which accepts a partial object and only applies changes to the properties included in the payload. For example, if the title of a content object is changed, PATCH can specify just that one property in its payload.

PATCH/api/episerver/v3.0/contentmanagement/{contentReference}
curl --location --request PATCH "http://<YOUR_DOMAIN>/api/episerver/v3.0/contentmanagement/116" ^
--header "Content-Type: application/json" ^
--header "Authorization: Bearer <AUTH_TOKEN>" ^
--data-raw "{'name': 'Alloy Track','language': {'name': 'en'},'metaTitle': {'value': 'Alloy Track Patched'}}"

📘

Notes

  • PATCH only values for culture invariant properties in the master language. That means if you want to update content in a specific language other than the master language, then you must omit culture invariant properties.
  • Pass only Language in the request body if the content type is localizable.
  • Set route segment only for the content that is IRoutable.
  • Set StartPublish, StopPublish, or Status only for content that is versionable.
  • Set StartPublish when a content item is set for scheduled publishing.
  • Ignore validation of content by setting the header x-epi-validation-mode to minimal.

Translate content

When translating content to another language, you should first GET the object in the source language and use that as a template object for the translated content. To use this endpoint, clients must have at least one more privilege higher than Read privilege.

GET/api/episerver/v3.0/contentmanagement/{contentReference}
curl --location --request GET "http://<YOUR_DOMAIN>/api/episerver/v3.0/contentmanagement/116" ^
--header "Authorization: Bearer <AUTH_TOKEN>" ^

Language variations of content are treated as separate content objects with shared culture-invariant properties. That means a newly translated object is POSTed and should specify the correct target language.

POST/api/episerver/v3.0/contentmanagement
curl --location --request POST "http://<YOUR_DOMAIN>/api/episerver/v3.0/contentmanagement/116" ^
--header "Content-Type: application/json" ^
--header "Authorization: Bearer <AUTH_TOKEN>" ^
--data-raw "{'name': 'Alloy Track','language': {'name': 'sv'},'contentType': ['ProductPage'],'parentLink': {'id': 5},'status': 'CheckedOut','metaTitle': {'value': 'Alloy Track SV'},'uniqueSellingPoints': {'value': ['Shared timeline','Project emails','To-do lists','Workflows','Status reports']}}"

📘

Note

You can set values only for non-branch-specific properties in the master language. When translating content you should omit culture invariant properties.

Move content

The location of content in the content tree is not a mutable property of the content object. Instead of using PUT or PATCH for the object location, a separate endpoint lets you move content to another location in the hierarchy.

POST/api/episerver/v3.0/contentmanagement/{contentGuid}/move
curl --location --request POST "http://<YOUR_DOMAIN>/api/episerver/v3.0/contentmanagement/116/move" ^
--header "Content-Type: application/json" ^
--header "Authorization: Bearer <AUTH_TOKEN>" ^
--data-raw "{'parentLink': {'id': 6},'routeSegment': 'new-segment'"}

📘

Note

System content items such as RootPage and GlobalAssetsRoot cannot be moved.

Delete content

The DELETE request places content in the trash. The content is permanently deleted if you use a DELETE request on content already in the trash. You can skip the trash bin and permanently delete an object by setting the x-epi-permanent-delete header to true.

DELETE/api/episerver/v3.0/contentmanagement/{contentReference}
curl --location --request DELETE "http://<YOUR_DOMAIN>/api/episerver/v3.0/contentmanagement/115" ^
--header "Authorization: Bearer <AUTH_TOKEN>"

📘

Note

You cannot delete system content such as RootPage and GlobalAssetsRoot.

Create a media content

To create a media object in CMS, send a POST multi-part form-data request with the required headers and parameters to the endpoint. The request body consists of two parts.

  • One part must be named content. The body contains property values of media content and its metadata in JSON format. This is similar to the JSON value of a regular content object.
  • The other part contains the media filename and its binary data. This filename must be the same as the name given in the previous part.
  • If the content part and binary part exist in the request, the filename and name property in the content part need to be the same, or an exception is thrown.
Create/api/episerver/v3.0/contentmanagement
curl --location --request POST "https://<YOUR_DOMAIN>/api/episerver/v3.0/contentmanagement" ^
--header "Authorization: Bearer <AUTH_TOKEN>" ^
--form "content={'name': 'sample-image.jpg', 'contentType': ['ImageFile'], 'parentLink': {'id': 7}, 'status': 'published'}" ^
--form "file=@\"<PATH_TO_FILE>\""

Update a media content

Send a PATCH multi-part form-data request bundled with only updated data to the endpoint to partially update media content.

  • If the content part and binary part exist in the request, the filename and name property in the content part must be the same. Otherwise, an exception is thrown.
  • To only patch the binary data, send a PATCH multi-part form-data request with the binary data as a single part. The file extension should match the existing one. Only binary data is updated, and the filename is not impacted.
  • To patch the media content's properties or metadata, send a PATCH multi-part form-data request with the updated data in the content part only without the binary part.
  • When an Optimizely Content Management System (CMS) content type can be of several extensions, such as an ImageFile file extension that can be .jpg or .png, you can update from one extension to the other.
curl --location --request PATCH "https://<YOUR_DOMAIN>/api/episerver/v3.0/contentmanagement/<EXISTING_CONTENT_ID_OR_GUID>" ^
--header "Authorization: Bearer <AUTH_TOKEN>" ^
--form "content={'name': 'another-image.jpg', 'status': 'published'}"

Create or update a media content

The Media content can be created or updated by sending a Put request to the endpoint.

  • If the media content already exists, then this endpoint updates the content media object. In contrast to PATCH, full content media data is sent to the endpoint in this case.
  • If it does not exist, a media content object is created. This endpoint cannot be used to update the content hierarchy.
curl --location --request PUT "https://<YOUR_DOMAIN>/api/episerver/v3.0/contentmanagement/<CONTENT_GUID>" ^
--header "Authorization: Bearer <AUTH_TOKEN>" ^
--form "content={'name': 'sample-image.jpg', 'contentType': ['ImageFile'], 'parentLink': {'id': 44}, 'status': 'published'}" ^
--form "file=@\"<PATH_TO_FILE>\""