---
title: Manage content using the REST API
slug: cms-saas/docs/manage-content-using-the-rest-api
createdAt: 2026-07-30T20:18:07.000Z
---

The Content API lets you manage content items and their versions in Optimizely CMS (SaaS) programmatically. The following sections describe how to create, copy, retrieve, update, transition the status of, and delete content through the API.

## Create a content item

You can create a content item using the Content API with an initial content version.

The request must contain a `contentType`, `container`, and `displayName`. If the content type is localized, it must also contain a `locale`.

```http
POST https://api.cms.optimizely.com/v1/content
Content-Type: application/json
```

```json
{
    "key": "6946107a8ad6414f8f1786364dab1ec2",
    "contentType": "story",
    "container": "98eb33cfa7df48d1b987442c522984c8",
    "initialVersion": {
        "displayName": "Example story",
        "locale": "en",
        "properties": {
            "heading": {
                "value": "The main story"
            }
        }
    }
}
```

See [Create content](docId\:p9XgSvFtr8nSot5JGYOq0) API Reference.

## Copy a content item

Use the content API to create a content item as a copy of an existing content item. A copy includes items contained under the content item. The content API copies only each content item's published or latest version and locale.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2:copy
```

The copy is created in the same container as the original unless the `container` parameter is provided.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2:copy
Content-Type: application/json
```

```json
{
    "container": "98eb33cfa7df48d1b987442c522984c8"
}
```

You can specify an `owner` to assign the copied content as an asset of another content item.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2:copy
Content-Type: application/json
```

```json
{
    "owner": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
}
```

The `container` and `owner` fields are mutually exclusive.

To make a copy of a deleted content item you must include the `cms-accept-resource` header with a `deleted` or `*` value.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2:copy
Content-Type: application/json
cms-accept-resource: deleted
```

See [Copy content](docId\:gOoPScichl4wAkaeQ9PB5) API reference.

## Get content node information

You can retrieve content node information (shared by all versions) by using the content API with the unique key of the content item.

```http
GET https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2
```

```json
{
  "key": "6946107a8ad6414f8f1786364dab1ec2",
  "contentType": "story",
  "container": "98eb33cfa7df48d1b987442c522984c8",
  "primaryLocale": "en",
  "locales": ["en"],
  "created": "2023-01-01T10:46:08.293+00:00",
  "createdBy": "steve",
  "lastModified": "2023-01-01T10:46:08.293+00:00",
  "lastModifiedBy": "steve"
}
```

See [Get content node](docId:-nmnz8mpTturb3pohkcer) API reference.

## Get the content hierarchy path

Use the `path` API to retrieve the content hierarchy of a content item

```http
GET https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/path
```

This method returns a list of content items that creates the hierarchical path to the content. This list includes the requested content. It returns an empty list if it does not find content with the provided key.

See [Get content path](docId\:JuyuTpKSCaKwX71LE-OYA) API reference.

## Get the content under an instance

Use the `items` API to retrieve the content hierarchy of a content item.

```http
GET https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/items
```

Use the `contentTypes` parameter to filter the list based on content types or base types such as `page`.

```http
GET https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/items?contentTypes=story,page
```

See [List content items](docId\:sGq_h4iUB7YuRkn73NoV8) API reference.

## Move a content item to a container

Use the Content API to move a content item to another container by updating the container field.

```http
PATCH https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2
Content-Type: application/merge-patch+json
```

```json
{
  "container": "98eb33cfa7df48d1b987442c522984c8"
}
```

See [Patch content](docId\:dJ5Y6lUfe3sHQyS9QKtMf) API reference.

## List versions of a content item

Use `versions` to retrieve a list of content versions through the Content API by providing the unique
key of the content item.

```http
GET https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions
```

You can filter the list on locales and statuses.

```http
GET https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions?locales=fr,de&statuses=draft,ready
```

See [List versions](docId\:ssNuMuILL6Eqbr_JzWyku) API reference.

## Retrieve a specific content version

Use the content key and the version identifier to retrieve a specific content version.

```http
GET https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions/523
```

See [Get version](docId\:tKOMWlOlnT8PeKqI1B2pk) API reference.

## Update a content item

You can update an existing content version using the Content API.

```http
PATCH https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions/1253
Content-Type: application/merge-patch+json
```

```json
{
  "displayName": "Updated name"
}
```

See [Update version](docId\:KWNwcu1ZxsEBv8ImPOK2Y) API reference.

You can also create a new version of an existing content item.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions
```

```json
{
    "displayName": "Example story",
    "locale": "en",
    "properties": {
        "heading": {
            "value": "The main story"
        }
    }
}
```

To create a locale version of an existing content item, provide a new locale.

See [Create version](docId\:qSPcUK4nE2-noWWANl-yH) API reference.

## Transition content version status

The Content API lets you transition a version between statuses using dedicated endpoints. You cannot change the `status` field through `PATCH`.

When you create content, omit the `status` field from `initialVersion`. New content starts in `draft` status, and you must use the dedicated status transition endpoints (`:ready`, `:publish`, `:draft`, `:approve`, `:reject`) to change the status.

All transition endpoints support optimistic concurrency checks through ETags. You should provide an `If-Match` precondition header with the ETag of the content version you want to update anytime that you call a transition endpoint.

### Mark a version as ready

Transition a draft version to `ready` status. If an approval workflow is configured, the system automatically submits the version for approval and transitions it to `inReview` instead.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions/1253:ready
```

You can include an optional request body with a `comment` (max 255 characters). When an approval definition exists and the version transitions to `inReview`, the comment is attached to the approval start. If the approval definition requires a comment at start, the `comment` field is mandatory.

### Publish a version

Publish a version to make it the live version. Publishing moves any existing published version to `previous` status.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions/1253:publish
```

### Schedule a version for future publication

Use the `:publish` endpoint with a `delayUntil` timestamp to schedule publishing for a future time. This sets the version status to `scheduled`.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions/1253:publish
```

```json
{
  "delayUntil": "2023-12-25T07:00:00.000+00:00"
}
```

If the `delayUntil` timestamp is in the past, the system publishes the version immediately.

The system may not publish scheduled versions at the exact scheduled time, but publishing should happen within minutes of the set time.

### Force publish a version

Set `force` to `true` in the request body to bypass validations such as approval workflows and required properties. This requires `Administer` access rights on the content.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions/1253:publish
Content-Type: application/json
```

```json
{
  "force": true
}
```

### Move a version back to draft

Transition a `ready` or `scheduled` version back to `draft` for further editing.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions/1253:draft
```

### Approve a content version in review

When a version is `inReview` (submitted for approval), approve the active step of the approval workflow. The authenticated client must be a reviewer for the active step.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions/1253:approve
```

You can include an optional request body with a `comment` (max 255 characters). If the approval definition requires a comment for approvals, the `comment` field is mandatory.

For multi-step approvals, approving advances one step. The version remains in `inReview` until all steps are approved. After the final step, the version transitions to `ready`.

To bypass reviewer validation and approve the entire flow, set `force` to `true`. This requires `Administer` access on the content.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions/1253:approve
```

```json
{
  "comment": "Reviewed and approved.",
  "force": false
}
```

### Reject a content version in review

When a version is `inReview`, reject the active step of the approval workflow. This transitions the version to `rejected` status regardless of remaining steps. The authenticated client must be a reviewer for the active step.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions/1253:reject
```

You can include an optional request body with a `comment` (max 255 characters). If the approval definition requires a comment for rejections, the `comment` field is mandatory.

To bypass reviewer validation and reject the entire flow, set `force` to `true`. This requires `Administer` access on the content.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions/1253:reject
```

```json
{
  "comment": "Content needs revision.",
  "force": false
}
```

## Delete content

Use the Content API to delete a content item.

```http
DELETE https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2
```

Deleting a content item does not immediately or permanently remove the resource. Instead, the content item remains read-only for a time decided by the CMS (SaaS) configuration.

Use the `cms-permanent-delete` header to permanently delete a content item.

```http
DELETE https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2
cms-permanent-delete: true
```

See [Delete content](docId:9pMqRMPvtyl9f7n2_7RUV) API reference.

## Get a deleted content item

If you deleted a content item but did not permanently remove it, the normal request for the content fails. You can use the `cms-accept-resource` header to retrieve a deleted content item before permanently deleting it.

Listing content never includes deleted content.

```http
GET https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2
cms-accept-resource: deleted
```

The content endpoint accepts the `cms-accept-resource` header with a `deleted` or `*` value.

## Delete a content version

You can remove a content version using the content key and version identifier. Using this method, you cannot delete the published content or the only version in a locale.

:::hint{type="warning"}
**Warning**
Deleting a content version is immediate and cannot be reversed.
:::

```http
DELETE https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/versions/1253
```

See [Delete version](docId\:GvA3Fd28DSzPF3dfvPbIh) API reference.

## Delete a content locale

To delete all versions of a content locale, provide the locale as a path parameter together with the content key.

:::hint{type="warning"}
**Warning**
Deleting a content locale is immediate and cannot be reversed.
:::

```http
DELETE https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2/locales/fr
```

See [Delete locale](docId\:UuCQO6eok3_cCwusCAvXv) API reference.

## Restore a deleted item

Use `undelete` to restore a deleted content item that was not permanently removed.

```http
POST https://api.cms.optimizely.com/v1/content/6946107a8ad6414f8f1786364dab1ec2:undelete
```

See [Restore content](docId\:oc3lw8tiN04RPv1yN6WfM) API reference.
