---
title: Introduction to the CMS (SaaS) REST API
slug: cms-saas/api
docTags: 
createdAt: 2026-07-30T20:20:18.789Z
---

Optimizely Content Management System (CMS) (SaaS) has a REST API to manage resources. See the developer guide for available [Resource types](docId\:JQOziYP0_i0KL_nuUlsPW).

## OpenAPI schema

You can download the [OpenAPI schema](https://www.openapis.org/what-is-openapi) from `https://api.cms.optimizely.com/<version>/docs/content-openapi.json` as follows:

:::CodeblockTabs
HTTP

```http
  GET https://api.cms.optimizely.com/VERSION/docs/content-openapi.json
  Authorization: Bearer <your_access_token>
  
```
:::

## Management and delivery

The REST APIs are intended for managing resources only. For high-performance delivery, use your CMS (SaaS) instance's [Optimizely Graph](docId\:aM0WpNsNXe_n26IhkX5sG) instance.

## Authentication

See [authentication and authorization](docId:2uVhCnJr4BdL9e5UNkN4L).

## API requests

Requests and responses use `Content-Type: application/json` unless otherwise specified. Unknown or unsupported fields in request bodies result in a `400 Bad Request` error. Read-only properties are an exception and are silently ignored to simplify JSON roundtripping. Refer to the OpenAPI spec for details on which fields are read-only.

Responses may include additional fields not defined in the specification. The client should be able to handle this. In the future, operations that normally return a `200 OK` response may return `202 Accepted` if the service believes the operation will take too long to process. Such a response includes information about where you can retrieve the operation processing status.

Standard values for a field are documented as examples rather than a fixed `enum`, so the API accepts values beyond those listed. If you generate an API client, generate it from the current specification and regenerate it after each update. A client built from an earlier specification can reject valid values.

## GET requests

Use `GET` requests to retrieve existing resources. Generally, when a request is without a resource key, a list of resources matching the request is returned.

### Conditional requests

Use the `If-None-Match` header with an ETag value to avoid fetching unchanged resources. If the resource's ETag matches the provided value, the API returns a `304 Not Modified` response. Alternatively, use the `If-Modified-Since` header with a date value; if the resource has not been modified since that date, a `304 Not Modified` response is returned. Note that `If-None-Match` takes precedence if both headers are provided. Refer to the OpenAPI spec for which operations support these headers.

### Paging

Most list endpoints use the query parameters `pageIndex` and `pageSize`.

- `pageIndex` – Zero-based index deciding which resource page to return. If omitted, the first page is returned.
- `pageSize` – Defines how many items are returned. If omitted, each page includes up to 100 resources unless defined otherwise.

The response returns a resource list in the following format, where the resources are included under the `items` field.

```json
{
  "items": [],
  "pageIndex": 2,
  "pageSize": 10,
  "totalCount": 421
}
```

If all existing resources are returned, the service will omit the `pageSize` and `pageIndex` fields. The `totalCount` field provides an approximate indication of the total number of items available. It is not returned if the total number of resources is unknown.

## POST requests

You can mostly use `POST` requests to create resources, but you can sometimes use them for custom actions. In such cases, the resource path ends with a suffix representing the action. For example, the `:copy` suffix is used for the endpoint that creates a copy of an existing content item.

To ensure that no one has updated an existing resource because you last checked, pass in the `ETag` returned in the response header from a `GET` request for the same resource in the `If-Match` request header.

All `POST` requests return a `201 Created` or `204 No Content` response without a body by default. If you want the API to return the created or updated resource, you can pass in a `Prefer` header with the value `return=representation` as per the [RFC 7240 ](https://www.rfc-editor.org/rfc/rfc7240)standard.

## PATCH requests

Use a `PATCH` request to update existing resources. CMS (SaaS) API follows the [JSON Merge Patch](https://www.rfc-editor.org/rfc/rfc7386) standard and expects a `Content-Type: application/merge-patch+json` header with requests.

To ensure that no one has updated an existing resource because you last checked, pass in the `ETag` returned in the response header from a `GET` request for the same resource in the `If-Match` request header.

All `PATCH` requests return a `204 No Content` response by default. If you want the API to return the updated resource, you can pass in a `Prefer` header with the value `return=representation` as per the [RFC 7240](https://www.rfc-editor.org/rfc/rfc7240) standard.

## DELETE requests

Use a `DELETE` request to delete existing resources.

To ensure that no one has updated an existing resource because you last checked, pass in the `ETag` returned in the response header from a `GET` request for the same resource in the `If-Match` request header.

All `DELETE` requests return a `204 No Content` response by default. If you want the API to return the resource that was deleted, you can pass in a `Prefer` header with the value `return=representation` as per the [RFC 7240](https://www.rfc-editor.org/rfc/rfc7240) standard.

Attempts to delete a resource that does not exist or that has already been deleted will result in a `404 Not Found` response.

## Error responses

The following list shows CMS (SaaS) API error responses. They follow [RFC 7807](https://www.rfc-editor.org/rfc/rfc7807) standards.

- The `type`, `title`, `status`, and `instance` fields are used only for generic error information.
- The `details` field provides a human-readable description of the error
- The `code` field provides a machine-readable description of the error.
- If an `errors` array field is included, it indicates an issue with the provided model. Each object on the `errors` array contains the following two fields:
  - `field` – Represents a field on the provided model.
  - `detail` – Provides error information about the problem with that field.

## Rate limits for CMS Rest API

CMS (SaaS) Rest API limits the number of REST API requests that you can make within a specific amount of time. This limit helps prevent abuse and denial-of-service attacks, and ensures that the API remains available for users.

:::hint{type="info"}
**Note**
The rate limit for the CMS Rest API is 100 requests per 10 seconds per IP address. If you exceed the rate limit, you will receive a `429 Too Many Requests` response.
:::
