CMP REST API Reference
Overview
Section titled “Overview”The CMP REST API provides programmatic access to content, assets, campaigns, workflows, and publishing operations. All endpoints use JSON request and response bodies, require OAuth 2.0 authentication, and follow REST conventions.
Base URL: https://api.optimizely.com/v1/cmp
Authentication
Section titled “Authentication”All requests require a Bearer token obtained via OAuth 2.0 client credentials flow.
Token endpoint: POST https://api.optimizely.com/oauth/token
| Parameter | Type | Required | Description |
|---|---|---|---|
grant_type | string | Yes | Must be client_credentials |
client_id | string | Yes | Your API client ID |
client_secret | string | Yes | Your API client secret |
scope | string | Yes | Space-separated scopes: cmp:read, cmp:write, cmp:publish |
Response:
| Field | Type | Description |
|---|---|---|
access_token | string | Bearer token for API requests |
token_type | string | Always Bearer |
expires_in | integer | Token lifetime in seconds (default: 3600) |
Rate limits
Section titled “Rate limits”| Tier | Rate | Burst |
|---|---|---|
| Standard | 100 requests/minute | 20 requests/second |
| Enterprise | 500 requests/minute | 50 requests/second |
Rate-limited responses return 429 with a Retry-After header (seconds).
Content endpoints
Section titled “Content endpoints”List content items
Section titled “List content items”GET /content
Returns a paginated list of content items with optional filters.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
per_page | integer | 25 | Items per page (max 100) |
status | string | — | Filter by workflow status: draft, in_review, approved, published, archived |
content_type | string | — | Filter by content type slug |
campaign_id | string | — | Filter by campaign ID |
assignee_id | string | — | Filter by current assignee |
created_after | ISO 8601 | — | Items created after this timestamp |
created_before | ISO 8601 | — | Items created before this timestamp |
sort | string | created_at | Sort field: created_at, updated_at, title |
order | string | desc | Sort order: asc, desc |
Response: 200 OK
| Field | Type | Description |
|---|---|---|
items | array | Array of content item objects |
pagination.page | integer | Current page number |
pagination.per_page | integer | Items per page |
pagination.total | integer | Total items matching the filter |
pagination.has_next | boolean | Whether more pages exist |
Get content item
Section titled “Get content item”GET /content/{id}
Returns a single content item with all fields, metadata, and workflow state.
Path parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Content item ID |
Response: 200 OK
| Field | Type | Description |
|---|---|---|
id | string | Unique content identifier |
title | string | Content title |
content_type | string | Content type slug |
status | string | Current workflow status |
fields | object | Content fields as key-value pairs |
campaign_id | string | Associated campaign ID (nullable) |
assignee | object | Current assignee user object |
created_at | ISO 8601 | Creation timestamp |
updated_at | ISO 8601 | Last modification timestamp |
published_at | ISO 8601 | Publication timestamp (nullable) |
version | integer | Version number |
Create content item
Section titled “Create content item”POST /content
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Content title |
content_type | string | Yes | Content type slug |
campaign_id | string | No | Campaign to associate with |
fields | object | No | Field values matching the content type schema |
template_id | string | No | Template ID to pre-populate fields |
Response: 201 Created — Returns the created content item object.
Update content item
Section titled “Update content item”PATCH /content/{id}
Updates specified fields on a content item. Only include fields you want to change.
Request body: Same fields as create, all optional.
Response: 200 OK — Returns the updated content item object.
Delete content item
Section titled “Delete content item”DELETE /content/{id}
Moves a content item to trash. Items in trash are permanently deleted after 30 days.
Response: 204 No Content
Asset endpoints
Section titled “Asset endpoints”List assets
Section titled “List assets”GET /assets
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
per_page | integer | 25 | Items per page (max 100) |
folder_id | string | — | Filter by folder |
tags | string | — | Comma-separated tag names |
type | string | — | Filter by asset type: image, video, document, design |
search | string | — | Full-text search across name, description, and tags |
Upload asset
Section titled “Upload asset”POST /assets
Content-Type: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
file | binary | Yes | The file to upload |
title | string | Yes | Asset title |
description | string | No | Asset description |
alt_text | string | No | Alt text for images |
folder_id | string | No | Target folder ID |
tags | JSON array | No | Tag names as JSON string |
Response: 201 Created for small files, 202 Accepted for files over 10 MB (async processing).
Get asset
Section titled “Get asset”GET /assets/{id}
Response: 200 OK
| Field | Type | Description |
|---|---|---|
id | string | Asset identifier |
title | string | Asset title |
file_name | string | Original file name |
mime_type | string | MIME type |
file_size | integer | Size in bytes |
dimensions | object | Width and height for images/video |
url | string | CDN URL for the asset |
thumbnail_url | string | Thumbnail URL |
tags | array | Associated tags |
folder_id | string | Parent folder ID |
created_at | ISO 8601 | Upload timestamp |
Delete asset
Section titled “Delete asset”DELETE /assets/{id}
Response: 204 No Content
Campaign endpoints
Section titled “Campaign endpoints”List campaigns
Section titled “List campaigns”GET /campaigns
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
per_page | integer | 25 | Items per page |
status | string | — | Filter: planning, active, completed, archived |
Get campaign
Section titled “Get campaign”GET /campaigns/{id}
Returns campaign details including associated content items and progress metrics.
Create campaign
Section titled “Create campaign”POST /campaigns
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Campaign name |
description | string | No | Campaign description |
start_date | ISO 8601 | No | Campaign start date |
end_date | ISO 8601 | No | Campaign end date |
Response: 201 Created
Publishing endpoints
Section titled “Publishing endpoints”Publish content
Section titled “Publish content”POST /content/{id}/publish
Triggers publishing to a configured channel. Content must be in approved status.
| Field | Type | Required | Description |
|---|---|---|---|
channel_id | string | Yes | Target publishing channel |
schedule_at | ISO 8601 | No | Schedule publish for a future time |
target_location | string | No | CMS content tree location (CMS channels only) |
Response: 200 OK for immediate publish, 202 Accepted for scheduled.
Get publish status
Section titled “Get publish status”GET /content/{id}/publish-status
Returns the publishing status for a content item across all channels.
| Field | Type | Description |
|---|---|---|
channels | array | Status per channel |
channels[].channel_id | string | Channel identifier |
channels[].status | string | pending, published, failed, scheduled |
channels[].published_at | ISO 8601 | When content was published (nullable) |
channels[].external_url | string | URL on the target platform (nullable) |
Workflow endpoints
Section titled “Workflow endpoints”Get workflow status
Section titled “Get workflow status”GET /content/{id}/workflow
Returns the current workflow state and history for a content item.
Transition workflow
Section titled “Transition workflow”POST /content/{id}/workflow/transition
Advances content to the next workflow stage.
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | approve, reject, request_changes |
comment | string | No | Reviewer comment |
Response: 200 OK — Returns updated workflow state.
Webhook configuration
Section titled “Webhook configuration”List webhooks
Section titled “List webhooks”GET /webhooks
Create webhook
Section titled “Create webhook”POST /webhooks
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Endpoint URL to receive events |
events | array | Yes | Event types to subscribe to |
secret | string | No | Signing secret for payload verification |
active | boolean | No | Whether the webhook is enabled (default: true) |
Response: 201 Created
Error response format
Section titled “Error response format”All error responses follow a consistent structure:
| Field | Type | Description |
|---|---|---|
error.code | string | Machine-readable error code |
error.message | string | Human-readable description |
error.details | array | Field-level validation errors (when applicable) |
Related
Section titled “Related”- CMP REST API Integration Guide — Step-by-step integration walkthrough
- CMP-CMS Integration Architecture — How CMP connects to CMS
- Webhook Events Reference — Event types and payload schemas