# Create channel

Create a new channel with specified videos and/or projects.

```http
POST /v1/channels
```

## Authentication

This endpoint requires authentication using a Bearer token.

```http
Authorization: Bearer YOUR_API_KEY
```

## Request Headers

| Header          | Value                 | Required |
| --------------- | --------------------- | -------- |
| `Authorization` | `Bearer YOUR_API_KEY` | Yes      |
| `Content-Type`  | `application/json`    | Yes      |

## Request Body

| Field                | Type    | Required | Description                                  |
| -------------------- | ------- | -------- | -------------------------------------------- |
| `name`               | string  | **Yes**  | Channel name (max 100 characters)            |
| `description`        | string  | No       | Channel description (max 250 characters)     |
| `templateKey`        | string  | No       | Template key to apply styling                |
| `videoKeys`          | array   | No\*     | Array of video keys to include               |
| `projectKeys`        | array   | No\*     | Array of project keys to include             |
| `privateLinkEnabled` | boolean | No       | Enable private link access (default: `true`) |

{% hint style="warning" %}
**Important:** At least one `videoKey` or `projectKey` must be provided.
{% endhint %}

### Request Example

```json
{
  "name": "Getting Started Series",
  "description": "Beginner tutorials for new users",
  "templateKey": "tmpl_dark",
  "videoKeys": [
    "vid_abc123",
    "vid_def456",
    "vid_ghi789"
  ],
  "projectKeys": [
    "proj_xyz"
  ],
  "privateLinkEnabled": true
}
```

## Response

### Success Response

**Status Code:** `201 Created`

The response includes a `Location` header with the URL of the created channel.

```json
{
  "id": "new_channel_id",
  "key": "ch_newkey123",
  "name": "Getting Started Series",
  "description": "Beginner tutorials for new users",
  "accountId": "acc_789",
  "version": 1,
  "planType": 2,
  "templateKey": "tmpl_dark",
  "status": 1,
  "created": "2024-01-25T09:00:00Z",
  "updated": "2024-01-25T09:00:00Z"
}
```

### Response Fields

| Field         | Type     | Description                            |
| ------------- | -------- | -------------------------------------- |
| `id`          | string   | Internal channel identifier            |
| `key`         | string   | Public channel key (use for embedding) |
| `name`        | string   | Channel display name                   |
| `description` | string   | Channel description                    |
| `accountId`   | string   | Owner account identifier               |
| `version`     | integer  | Channel version (starts at 1)          |
| `planType`    | integer  | Associated plan type                   |
| `templateKey` | string   | Applied template key                   |
| `status`      | integer  | Channel status (1 = Published)         |
| `created`     | datetime | Creation timestamp (ISO 8601)          |
| `updated`     | datetime | Last update timestamp (ISO 8601)       |

## Error Responses

| Status Code | Description                               |
| ----------- | ----------------------------------------- |
| `400`       | Bad Request - Validation error            |
| `401`       | Unauthorized - Invalid or missing API key |
| `500`       | Internal Server Error                     |

<details>

<summary>Validation error examples</summary>

```json
{
  "message": "Name is required."
}
```

```json
{
  "message": "Provide at least one videoKey or projectKey."
}
```

```json
{
  "message": "Invalid videoKeys provided.",
  "invalidVideoKeys": ["vid_invalid1", "vid_invalid2"]
}
```

```json
{
  "message": "Invalid projectKeys provided.",
  "invalidProjectKeys": ["proj_invalid"]
}
```

```json
{
  "message": "Template not found for this account."
}
```

</details>

## Code Examples

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST "https://api.dyntube.com/v1/channels" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Getting Started Series",
    "description": "Beginner tutorials for new users",
    "videoKeys": ["vid_abc123", "vid_def456"],
    "privateLinkEnabled": true
  }'
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const newChannel = {
  name: 'Getting Started Series',
  description: 'Beginner tutorials for new users',
  videoKeys: ['vid_abc123', 'vid_def456', 'vid_ghi789'],
  privateLinkEnabled: true
};

const response = await fetch('https://api.dyntube.com/v1/channels', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(newChannel)
});

if (response.status === 201) {
  const channel = await response.json();
  console.log(`Created channel: ${channel.name}`);
  console.log(`Channel key for embedding: ${channel.key}`);
} else {
  const error = await response.json();
  console.error(`Error: ${error.message}`);
}
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

new_channel = {
    'name': 'Getting Started Series',
    'description': 'Beginner tutorials for new users',
    'videoKeys': ['vid_abc123', 'vid_def456', 'vid_ghi789'],
    'privateLinkEnabled': True
}

response = requests.post(
    'https://api.dyntube.com/v1/channels',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json=new_channel
)

if response.status_code == 201:
    channel = response.json()
    print(f"Created channel: {channel['name']}")
    print(f"Channel key for embedding: {channel['key']}")
else:
    error = response.json()
    print(f"Error: {error['message']}")
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$newChannel = [
    'name' => 'Getting Started Series',
    'description' => 'Beginner tutorials for new users',
    'videoKeys' => ['vid_abc123', 'vid_def456', 'vid_ghi789'],
    'privateLinkEnabled' => true
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.dyntube.com/v1/channels');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($newChannel));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer YOUR_API_KEY',
    'Content-Type: application/json'
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode === 201) {
    $channel = json_decode($response, true);
    echo "Created channel: " . $channel['name'] . "\n";
    echo "Channel key for embedding: " . $channel['key'] . "\n";
} else {
    $error = json_decode($response, true);
    echo "Error: " . $error['message'] . "\n";
}
```

{% endtab %}
{% endtabs %}

## Use Cases

### Create Channel with Videos

```javascript
// Create a channel containing specific videos
const channel = await createChannel({
  name: 'Product Demo Videos',
  description: 'Demonstrations of our product features',
  videoKeys: [
    'vid_intro',
    'vid_feature1',
    'vid_feature2',
    'vid_advanced'
  ]
});
```

### Create Channel from Project

```javascript
// Create a channel that includes all videos from a project
const channel = await createChannel({
  name: 'Marketing Campaign Q1',
  description: 'All marketing videos for Q1 2024',
  projectKeys: ['proj_marketing_q1']
});
```

### Create Channel with Template

```javascript
// First, get available templates
const templatesResponse = await fetch(
  'https://api.dyntube.com/v1/channels/templates',
  { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
);
const templates = await templatesResponse.json();

// Create channel with a specific template
const channel = await createChannel({
  name: 'Branded Channel',
  videoKeys: ['vid_abc123'],
  templateKey: templates[0].key  // Use first available template
});
```

## Video Key Order

The order of video keys in the `videoKeys` array determines the display order in the channel. Videos are shown in the same order they appear in the request.

```json
{
  "name": "Ordered Playlist",
  "videoKeys": [
    "vid_episode1",  // Displayed first
    "vid_episode2",  // Displayed second
    "vid_episode3"   // Displayed third
  ]
}
```

## See Also

* [List Templates](https://dev.dyntube.com/reference/channels/broken-reference) - Get available templates
* [Update Channel](https://dev.dyntube.com/reference/channels/broken-reference) - Modify a channel
* [Get Channel](https://dev.dyntube.com/reference/channels/broken-reference) - Retrieve channel details
* [Channels API Overview](https://dev.dyntube.com/reference/channels/broken-reference) - API overview and authentication
