> ## 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.

# Channels API

> Create, update, list, and delete delivery channels with placements.

<Note>
  **See also**: [Channels concept and configuration](/studio/channels) for what this API powers, when to call it, and how it is configured.
</Note>

Channels define how recommendations are delivered to customers. Each channel has a delivery mode, optional provider configuration, and can contain multiple placements (slots where creatives are rendered).

All channels support **soft-delete** (a `deletedAt` timestamp is set instead of permanent removal), **version tracking** (the `version` field auto-increments on every update), and **audit logging** (before/after snapshots are recorded for every CRUD operation).

<Info>
  See the [Channels feature page](/studio/channels) for UI guidance and conceptual overview.
</Info>

## Base path

```
/api/v1/channels
```

***

## List channels

```
GET /api/v1/channels
```

Returns a paginated list of channels for the current tenant, ordered by creation date (newest first). Each channel includes its placements and creatives. By default, soft-deleted channels are excluded.

### Query parameters

| Parameter        | Required | Type    | Description                                                              |
| ---------------- | -------- | ------- | ------------------------------------------------------------------------ |
| `limit`          | No       | integer | Maximum results per page. Default `50`, max `100`.                       |
| `cursor`         | No       | string  | Cursor for keyset pagination. Pass the last `id` from the previous page. |
| `includeDeleted` | No       | string  | Set to `"true"` to include soft-deleted channels in the results.         |

### Response `200`

```json theme={null}
{
  "data": [
    {
      "id": "ch_email",
      "tenantId": "t_001",
      "name": "Email",
      "channelType": "email",
      "status": "active",
      "description": "Transactional and marketing email channel.",
      "deliveryMode": "api",
      "impressionMode": "explicit",
      "couplingMode": "partial",
      "providerConfig": { "provider": "sendgrid" },
      "fileConfig": {},
      "version": 1,
      "deletedAt": null,
      "placements": [
        {
          "id": "pl_hero",
          "name": "Hero Banner",
          "slotType": "banner",
          "maxSlots": 1
        }
      ],
      "creatives": [],
      "createdAt": "2026-03-10T12:00:00.000Z",
      "updatedAt": "2026-03-12T09:30:00.000Z"
    }
  ],
  "pagination": {
    "limit": 50,
    "cursor": null,
    "hasMore": false,
    "total": 5
  }
}
```

### Error codes

| Code  | Reason                                |
| ----- | ------------------------------------- |
| `401` | Missing or invalid API key / session. |
| `403` | Insufficient role.                    |

***

## Create a channel

```
POST /api/v1/channels
```

Creates a new channel. You can inline placements in the create request to set them up atomically. Creating a channel also auto-creates flow routes to the default decision flow for each placement.

### Request body

| Field            | Required | Type           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ---------------- | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`           | **Yes**  | string (1-255) | Unique channel name.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `channelType`    | No       | string         | Channel type identifier. Default `"email"`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `status`         | No       | enum           | `draft` (default), `active`, `paused`, `archived`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `description`    | No       | string         | Channel description.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `deliveryMode`   | No       | enum           | `api` (default), `file`, `integration`, `manual`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `impressionMode` | No       | enum           | `explicit` (default), `implicit`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `couplingMode`   | No       | enum           | `partial` (default) or `atomic`. Controls within-channel placement coupling — when `atomic`, an empty placement on this channel causes ALL placements on the channel to come back empty in the Recommend response. Used for composite surfaces (email body, push notification) where a partial response renders broken. Cross-channel coupling is intentionally not supported. See [Placement Coupling in the composable pipeline docs](/data/transforms/composable-pipeline#channel-coupling-within-channel-atomicity). |
| `providerConfig` | No       | object         | Provider-specific configuration.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `fileConfig`     | No       | object         | **Deprecated** — batch file output now lives on the campaign (`Run.fileConfig`; see [File Output Configuration](/operations-reporting/runs#file-output-configuration)). Still accepted/stored for backward compatibility and validated when non-empty, but the batch executor no longer reads it.                                                                                                                                                                                                                        |
| `placements`     | No       | array          | Inline placement definitions (see below).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

#### Placement object (inline)

| Field         | Required | Type           | Description                                                       |
| ------------- | -------- | -------------- | ----------------------------------------------------------------- |
| `name`        | **Yes**  | string         | Placement name.                                                   |
| `description` | No       | string         | Placement description.                                            |
| `slotType`    | No       | string         | Slot type (e.g., `banner`, `card`, `inline`). Default `"banner"`. |
| `maxSlots`    | No       | integer (>= 1) | Maximum concurrent slots. Default `1`.                            |
| `schema`      | No       | object         | Content schema for the slot.                                      |
| `targeting`   | No       | object         | Targeting rules for the placement.                                |

### Example request

```json theme={null}
{
  "name": "Mobile Push",
  "channelType": "push",
  "deliveryMode": "api",
  "impressionMode": "implicit",
  "providerConfig": { "provider": "firebase" },
  "placements": [
    {
      "name": "Notification Tray",
      "slotType": "notification",
      "maxSlots": 3
    }
  ]
}
```

### Response `201`

Returns the created channel with placements, creatives relations, `version: 1`, and `deletedAt: null`. An audit log entry is created with a `create` action.

### Error codes

| Code  | Reason                                            |
| ----- | ------------------------------------------------- |
| `400` | Validation error.                                 |
| `401` | Missing or invalid API key / session.             |
| `403` | Insufficient role (requires `editor` or `admin`). |
| `409` | A channel with that name already exists.          |
| `413` | Request body exceeds the 2 MB limit.              |
| `415` | `Content-Type` is not `application/json`.         |

***

## Update a channel

```
PUT /api/v1/channels
```

Updates an existing channel. Only provided fields are changed. Placements are managed separately via the Placements API. The `version` field is auto-incremented and a before/after audit snapshot is recorded.

### Request body

| Field            | Required | Type           | Description                                                                                                                                            |
| ---------------- | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`             | **Yes**  | string         | Channel ID to update.                                                                                                                                  |
| `name`           | No       | string (1-255) | Updated name.                                                                                                                                          |
| `channelType`    | No       | string         | Updated type.                                                                                                                                          |
| `status`         | No       | enum           | `draft`, `active`, `paused`, `archived`.                                                                                                               |
| `description`    | No       | string         | Updated description.                                                                                                                                   |
| `deliveryMode`   | No       | enum           | `api`, `file`, `integration`, `manual`.                                                                                                                |
| `impressionMode` | No       | enum           | `explicit`, `implicit`.                                                                                                                                |
| `couplingMode`   | No       | enum           | `partial` or `atomic`. See create section above for behavior.                                                                                          |
| `providerConfig` | No       | object         | Updated provider config.                                                                                                                               |
| `fileConfig`     | No       | object         | **Deprecated** — file output is configured on the campaign (`Run.fileConfig`); accepted for backward compatibility but not read by the batch executor. |

### Example request

```json theme={null}
{
  "id": "ch_push",
  "status": "active",
  "providerConfig": { "provider": "firebase", "apiKey": "***" }
}
```

### Response `200`

Returns the updated channel object with the incremented `version`.

### Error codes

| Code  | Reason                                              |
| ----- | --------------------------------------------------- |
| `400` | Validation error.                                   |
| `401` | Missing or invalid API key / session.               |
| `403` | Insufficient role.                                  |
| `404` | No channel with that `id` (or name) in your tenant. |
| `409` | A channel with that name already exists.            |
| `413` | Request body exceeds the 2 MB limit.                |
| `415` | `Content-Type` is not `application/json`.           |

***

## Delete a channel (soft-delete)

```
DELETE /api/v1/channels?id={channelId}
```

Soft-deletes a channel by setting its `deletedAt` timestamp. **Cascade behavior:** all associated placements and creatives are also soft-deleted. The `version` is incremented on the channel and each cascaded child. An audit log entry is recorded for every affected entity.

### Query parameters

| Parameter | Required | Type   | Description           |
| --------- | -------- | ------ | --------------------- |
| `id`      | **Yes**  | string | Channel ID to delete. |

### Response `200`

```json theme={null}
{
  "success": true,
  "cascaded": 4
}
```

The `cascaded` field indicates how many child entities (placements + creatives) were also soft-deleted.

### Error codes

| Code  | Reason                                                           |
| ----- | ---------------------------------------------------------------- |
| `400` | Missing `id` query parameter, or the channel is already deleted. |
| `401` | Missing or invalid API key / session.                            |
| `403` | Insufficient role.                                               |
| `404` | No channel with that `id` (or name) in your tenant.              |

<Note>
  To restore a soft-deleted channel, use `POST /api/v1/restore?entityType=channel&id={channelId}` (admin only). Restoring a channel does not automatically restore cascaded placements or creatives -- you must restore them individually.
</Note>

***

## Role requirements

| Method | Minimum role |
| ------ | ------------ |
| GET    | `viewer`     |
| POST   | `editor`     |
| PUT    | `editor`     |
| DELETE | `editor`     |

<Card title="Channels" icon="tower-broadcast" href="/studio/channels">
  Learn more about creating and managing channels in the platform UI.
</Card>
