> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Content

> Manage content items through a full lifecycle: draft, submit for review, approve, publish, reject, and revert to previous versions.

<Frame caption="The Content page.">
  <img src="https://mintcdn.com/kaireonai/l-jsUQlUEuA3B6hG/images/screenshots/content-list.png?fit=max&auto=format&n=l-jsUQlUEuA3B6hG&q=85&s=8a680be2ef2064be2e3a78fa88f22de7" alt="Content list view in the Studio module" width="1440" height="900" data-path="images/screenshots/content-list.png" />
</Frame>

## GET /api/v1/content

List all content items for the tenant. Supports cursor-based pagination and filtering.

### Query Parameters

| Parameter     | Type    | Default | Description                                       |
| ------------- | ------- | ------- | ------------------------------------------------- |
| `limit`       | integer | `20`    | Max results per page                              |
| `cursor`      | string  | --      | Cursor for pagination                             |
| `status`      | string  | --      | Filter by status (e.g., `"draft"`, `"published"`) |
| `channelType` | string  | --      | Filter by channel type                            |
| `isTemplate`  | string  | --      | Filter templates (`"true"` or `"false"`)          |
| `sourceType`  | string  | --      | Filter by source type                             |

### Response

```json theme={null}
{
  "data": [
    {
      "id": "content_001",
      "name": "Spring Promotion Email",
      "tenantId": "tenant_001",
      "channelType": "email",
      "status": "published",
      "version": 4,
      "content": { "subject": "Spring deals just for you", "body": "<html>...</html>" },
      "blocks": [],
      "personalization": { "customer_name": "{{customer.name}}" },
      "isTemplate": false,
      "sourceType": "internal",
      "parentTemplate": { "id": "tmpl_001", "name": "Seasonal Template" },
      "source": null,
      "createdAt": "2026-03-01T10:00:00.000Z",
      "updatedAt": "2026-03-10T12:00:00.000Z"
    }
  ],
  "pagination": {
    "total": 15,
    "hasMore": false,
    "limit": 20,
    "cursor": null
  }
}
```

***

## POST /api/v1/content

Create a new content item. The item starts in `"draft"` status at version 1. An initial version snapshot is created automatically.

### Request Body

| Field              | Type    | Required | Description                                                |
| ------------------ | ------- | -------- | ---------------------------------------------------------- |
| `name`             | string  | Yes      | Content item name (must be unique per tenant)              |
| `channelType`      | string  | Yes      | Channel type (e.g., `"email"`, `"sms"`, `"push"`)          |
| `description`      | string  | No       | Description                                                |
| `content`          | object  | No       | Content payload (e.g., subject, body, etc.)                |
| `blocks`           | array   | No       | Content blocks for block-based editing                     |
| `personalization`  | object  | No       | Personalization configuration                              |
| `parentTemplateId` | string  | No       | ID of a template to inherit from                           |
| `isTemplate`       | boolean | No       | Whether this item is a reusable template. Default: `false` |

### Example

```bash theme={null}
curl -X POST https://playground.kaireonai.com/api/v1/content \
  -H "Content-Type: application/json" \
  -H "X-Tenant-Id: my-tenant" \
  -d '{
    "name": "Welcome Email",
    "channelType": "email",
    "content": {
      "subject": "Welcome to Kaireon!",
      "body": "<html>...</html>"
    },
    "personalization": {
      "customer_name": "{{customer.name}}"
    }
  }'
```

### Error Codes

| Code  | Reason                                       |
| ----- | -------------------------------------------- |
| `201` | Content item created successfully            |
| `409` | A content item with that name already exists |

**Response:** `201 Created` with the content item object.

***

## GET /api/v1/content/{id}

Get a content item with its parent template, source, and recent version history (up to 20 versions).

### Response

```json theme={null}
{
  "id": "content_001",
  "name": "Spring Promotion Email",
  "status": "published",
  "version": 4,
  "content": { "subject": "Spring deals just for you", "body": "<html>...</html>" },
  "blocks": [],
  "personalization": { "customer_name": "{{customer.name}}" },
  "parentTemplate": { "id": "tmpl_001", "name": "Seasonal Template" },
  "source": null,
  "publishedAt": "2026-03-10T12:00:00.000Z",
  "versions": [
    { "id": "cv_004", "version": 4, "createdAt": "2026-03-10T12:00:00.000Z" }
  ]
}
```

***

## PUT /api/v1/content/{id}

Update a content item. Increments the version number and creates a version snapshot automatically.

### Request Body

| Field             | Type   | Required | Description                    |
| ----------------- | ------ | -------- | ------------------------------ |
| `name`            | string | No       | Updated name                   |
| `content`         | object | No       | Updated content payload        |
| `blocks`          | array  | No       | Updated content blocks         |
| `personalization` | object | No       | Updated personalization config |

**Response:** `200 OK`

***

## DELETE /api/v1/content/{id}

Archive a content item (soft delete -- sets status to `"archived"`).

**Response:** `204 No Content`

***

## POST /api/v1/content/{id}/submit

Submit a draft content item for review. Changes status from `"draft"` to `"in_review"`.

**Prerequisite:** Content must be in `"draft"` status.

**Response:** `200 OK`

***

## POST /api/v1/content/{id}/approve

Approve a content item that is in review. Changes status from `"in_review"` to `"approved"`.

**Prerequisite:** Content must be in `"in_review"` status. The approver cannot be the same user who submitted the content (self-approval prevention).

**Response:** `200 OK`

***

## POST /api/v1/content/{id}/publish

Publish an approved content item. Sets status to `"published"` and records `publishedAt`. Creates a version snapshot.

**Prerequisite:** Content must be in `"approved"` status.

**Response:** `200 OK`

***

## POST /api/v1/content/{id}/reject

Reject a content item in review. Returns it to `"draft"` status.

**Prerequisite:** Content must be in `"in_review"` status.

### Request Body

| Field    | Type   | Required | Description      |
| -------- | ------ | -------- | ---------------- |
| `reason` | string | No       | Rejection reason |

**Response:** `200 OK`

***

## GET /api/v1/content/{id}/versions

List all version snapshots for a content item (up to 100, newest first).

### Response

```json theme={null}
[
  {
    "id": "cv_004",
    "contentItemId": "content_001",
    "version": 4,
    "content": { "subject": "Spring deals just for you" },
    "changeNote": "Published",
    "changedBy": "user_001",
    "createdAt": "2026-03-10T12:00:00.000Z"
  }
]
```

***

## POST /api/v1/content/{id}/revert/{version}

Revert a content item to a previous version. Creates a new version with the snapshot's content and resets status to `"draft"`.

**Prerequisite:** Target version must be less than the current version.

### Example

```bash theme={null}
curl -X POST https://playground.kaireonai.com/api/v1/content/content_001/revert/2 \
  -H "X-Tenant-Id: my-tenant"
```

**Response:** `200 OK` with the updated content item at the new version number.

***

## Content Lifecycle

```
draft --> in_review --> approved --> published
  ^          |
  |          v
  +------ rejected (returns to draft)
  ^
  |
  +------ reverted (returns to draft)
```

***

## Roles

| Endpoint                              | Allowed Roles         |
| ------------------------------------- | --------------------- |
| `GET /content`                        | admin, editor, viewer |
| `POST /content`                       | admin, editor         |
| `GET /content/{id}`                   | admin, editor, viewer |
| `PUT /content/{id}`                   | admin, editor         |
| `DELETE /content/{id}`                | admin, editor         |
| `POST /content/{id}/submit`           | admin, editor         |
| `POST /content/{id}/approve`          | admin, editor         |
| `POST /content/{id}/publish`          | admin, editor         |
| `POST /content/{id}/reject`           | admin, editor         |
| `GET /content/{id}/versions`          | admin, editor, viewer |
| `POST /content/{id}/revert/{version}` | admin, editor         |

See also: [Content Management](/studio/content-management)
