---
title: "Channel Content API"
description: "Fetch YouTube channel details, videos, shorts, playlists, and outlier analysis."
source: "https://dashboard.nexlev.io/docs/api/channel-content"
---

# Channel Content API

Fetch YouTube channel details, videos, shorts, playlists, and outlier analysis.

**Base URL**: `https://prod.dashboard.nexlev.io` — see [Authentication](/docs/api/authentication). All 5 operations cost 🥞 1 quota per request — see [Rate Limits & Quota](/docs/api/rate-limits).

## Operations Quick Reference

| Operation     | Method & Path                          |
| ------------- | -------------------------------------- |
| Get About     | `GET /api/external/channels/about`     |
| Get Videos    | `GET /api/external/channels/videos`    |
| Get Shorts    | `GET /api/external/channels/shorts`    |
| Get Playlists | `GET /api/external/channels/playlists` |
| Get Outliers  | `GET /api/external/channels/outliers`  |

## Available Operations

The Channel Content resource provides five different operations to retrieve various types of channel data:

### Get About

#### Get About

```http
GET /api/external/channels/about
```

**Description**: Retrieve comprehensive channel metadata including title, description, subscriber count, social links, and channel statistics.

> **Warning**
>
> **🥞 Quota Cost: 1 quota per request**
>
> Each call to this endpoint deducts **1 quota** from your account balance. Monitor your usage at [Manage API Key](https://dashboard.nexlev.io/nexlev-api/manage-api-key) to avoid interruptions.
>

**Query Parameters**: `forUsername` (optional) or `id` (optional) - YouTube username or channel ID

**Note**: Provide either `forUsername` or `id`, not both.

**Example URLs**:

```
https://prod.dashboard.nexlev.io/api/external/channels/about?forUsername=@DavidFraserYT
https://prod.dashboard.nexlev.io/api/external/channels/about?id=UCBJycsmduvYEL83R_U4JriQ
```

**cURL Example**:

```bash
curl "https://prod.dashboard.nexlev.io/api/external/channels/about?id=UCBJycsmduvYEL83R_U4JriQ" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Get detailed information about a YouTube channel including description, avatar, banner, channel handle, and subscriber information.

**When to use this operation:**

- Gathering channel profile information for research
- Building channel databases with metadata
- Extracting social media links and contact information
- Verifying channel authenticity and statistics

**Parameters**:

| Parameter     | Type   | Required                  | Description                            |
| ------------- | ------ | ------------------------- | -------------------------------------- |
| `id`          | string | One of `id`/`forUsername` | The unique YouTube channel identifier  |
| `forUsername` | string | One of `id`/`forUsername` | YouTube handle (e.g. `@DavidFraserYT`) |

**Status Code**: `200 OK`

**Response Body**:

```json
{
  "channelId": "UCBJycsmduvYEL83R_U4JriQ",
  "title": "Marques Brownlee",
  "description": "MKBHD: Quality Tech Videos | YouTuber | Geek | Consumer Electronics | Tech Head | Internet Personality!\n\nbusiness@MKBHD.com\n\nNYC",
  "avatar": [
    {
      "url": "https://yt3.googleusercontent.com/qu4TmIaYUlS41-dJ9gZ7DUR3nilvmB5_11i6OKSdvNnBNiyOusZP1bMN6ICnuxtjFBb6ioKgRQ=s160-c-k-c0x00ffffff-no-rj",
      "width": 160,
      "height": 160
    },
    {
      "url": "https://yt3.googleusercontent.com/qu4TmIaYUlS41-dJ9gZ7DUR3nilvmB5_11i6OKSdvNnBNiyOusZP1bMN6ICnuxtjFBb6ioKgRQ=s72-c-k-c0x00ffffff-no-rj",
      "width": 72,
      "height": 72
    }
  ],
  "metaD": "UCBJycsmduvYEL83R_U4JriQ",
  "banner": [],
  "channelHandle": "@mkbhd",
  "subscriberCountText": "20.6M subscribers",
  "subscriberCount": 20600000,
  "videosCountText": "1,785 videos",
  "videosCount": "1785",
  "keywords": ["MKBHD", "MarquesBrownlee", "Marques", "Brownlee"],
  "isFamilySafe": true,
  "isUnlisted": false,
  "availableCountries": ["SL", "TT", "EH", "NU", "SA", "AG", "GA", "..."],
  "tabs": ["Home", "Videos", "Shorts", "Live", "Playlists", "Posts", "Store"],
  "country": "United States",
  "viewCountText": "5,142,094,005 views",
  "viewCount": "5142094005",
  "joinedDateText": "Joined Mar 21, 2008",
  "joinedDate": "2008-03-21",
  "links": [
    {
      "title": "Twitter",
      "link": "twitter.com/MKBHD",
      "favicon": [
        {
          "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcQYbMNQ3a7LqKzqhkvBsowNn_ZiyMTETw8naXxDTLsn12SAxcLwxr9aVzQcAb7yfXeaFg-H0NjXyKBK7kTt_tVF4RfZ3OtAiFZvpqW0lZB4iQ",
          "width": 256,
          "height": 256
        },
        {
          "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcRfrgN-vDv2HHFDMwk8GargknaDuXUO2BuEQtUv7Ue0CI2uPorX5JDp48wjQ6JtyrF590nARXhnUVs-5R0o0dY3zKMtmGxJdNwtDiX23Gvv",
          "width": 32,
          "height": 32
        }
      ]
    },
    {
      "title": "Instagram",
      "link": "instagram.com/MKBHD",
      "favicon": [
        {
          "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcSMItu-kpj9mUqJlYFLBMsNp279lOFn_WdIAoqsMZYtJYhjg8xQh9qCgB3BvVFbtYpLemKWr-ZbwnTCA2jDa_i60wjmuwUIX-vxhbaBmAQONd2D",
          "width": 256,
          "height": 256
        },
        {
          "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcRHmEJzjUkw7J1XBesfOY377AVoQe5m75w7LUT44H77vERWBHa8BjlyEZEbPQRUubv0p5FMgFYb-91m2f7M-QMk18WOl3Tf_llyYuSI5P-DpHE",
          "width": 32,
          "height": 32
        }
      ]
    }
  ],
  "hasEmail": true,
  "msg": ""
}
```

**Response Fields**:

- `channelId` - Unique channel identifier
- `title` - Channel name
- `description` - Channel description/bio
- `avatar` - Array of avatar images in different sizes (160px, 72px)
- `metaD` - Channel metadata identifier
- `banner` - Array of banner images (may be empty)
- `channelHandle` - Channel handle (e.g., @mkbhd)
- `subscriberCountText` - Formatted subscriber count (e.g., "20.6M subscribers")
- `subscriberCount` - Raw subscriber count number
- `videosCountText` - Formatted video count
- `videosCount` - Raw video count
- `keywords` - Array of channel keywords/tags
- `isFamilySafe` - Boolean indicating if channel is family-safe
- `isUnlisted` - Boolean indicating if channel is unlisted
- `availableCountries` - Array of country codes where content is available
- `tabs` - Array of available tabs on the channel
- `country` - Channel's country of origin
- `viewCountText` - Formatted total view count
- `viewCount` - Raw total view count
- `joinedDateText` - Human-readable join date
- `joinedDate` - ISO date of channel creation
- `links` - Array of external links with favicons
- `hasEmail` - Boolean indicating if channel has email available
- `msg` - Status message (empty on success)

### Get Videos

#### Get Videos

```http
GET /api/external/channels/videos
```

**Description**: Retrieve all long-form videos from a channel with sorting and pagination options.

> **Warning**
>
> **🥞 Quota Cost: 1 quota per request**
>
> Each call to this endpoint deducts **1 quota** from your account balance. Monitor your usage at [Manage API Key](https://dashboard.nexlev.io/nexlev-api/manage-api-key) to avoid interruptions.
>

**Query Parameters**: `id` (required), `sort_by` (optional), `token` (optional)

**Example URL**:

```
https://prod.dashboard.nexlev.io/api/external/channels/videos?id=UCX6OQ3DkcsbYNE6H8uQQuVA&sort_by=oldest
```

**cURL Example**:

```bash
curl "https://prod.dashboard.nexlev.io/api/external/channels/videos?id=UCX6OQ3DkcsbYNE6H8uQQuVA&sort_by=oldest" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Get all videos from a YouTube channel with detailed metadata including view count, publish date, thumbnails, and more. Supports pagination via continuation tokens to retrieve additional videos beyond the initial response.

**When to use this operation:**

- Analyzing video performance and publishing patterns
- Building comprehensive video databases
- Tracking content output over time
- Identifying content trends and topics

**Parameters**:

| Parameter          | Type   | Required | Description                                                                                   | Options                 |
| ------------------ | ------ | -------- | --------------------------------------------------------------------------------------------- | ----------------------- |
| Channel ID         | string | Yes      | The unique YouTube channel identifier                                                         | -                       |
| Sort By            | string | No       | Sort order for videos (default: Latest)                                                       | Latest, Popular, Oldest |
| Continuation Token | string | No       | Token from previous response to fetch the next page of results (see Pagination section below) | -                       |

**Status Code**: `200 OK`

**Response Body**:

```json
{
  "meta": {
    "channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
    "title": "MrBeast",
    "description": "SUBSCRIBE FOR A COOKIE! New MrBeast or MrBeast Gaming video every single Saturday at noon eastern time! Accomplishments: - Raised $20,000,000 To Plant 20,000...",
    "channelHandle": "@MrBeast",
    "banner": [],
    "tvBanner": [],
    "mobileBanner": [],
    "avatar": [
      {
        "url": "https://yt3.googleusercontent.com/nxYrc_1_2f77DoBadyxMTmv7ZpRZapHR5jbuYe7PlPd5cIRJxtNNEYyOC0ZsxaDyJJzXrnJiuDE=s160-c-k-c0x00ffffff-no-rj",
        "width": 160,
        "height": 160
      },
      {
        "url": "https://yt3.googleusercontent.com/nxYrc_1_2f77DoBadyxMTmv7ZpRZapHR5jbuYe7PlPd5cIRJxtNNEYyOC0ZsxaDyJJzXrnJiuDE=s72-c-k-c0x00ffffff-no-rj",
        "width": 72,
        "height": 72
      }
    ],
    "subscriberCountText": "454M subscribers",
    "subscriberCount": 454000000,
    "videosCountText": "0",
    "videosCount": "0",
    "keywords": ["mrbeast6000", "beast", "mrbeast", "Mr.Beast", "mr"],
    "isFamilySafe": true,
    "availableCountries": [
      "TW",
      "IO",
      "UZ",
      "BR",
      "AZ",
      "DO",
      "AU",
      "ES",
      "..."
    ],
    "tabs": ["Home", "Videos", "Shorts", "Playlists", "Posts"]
  },
  "continuation": "4qmFsgL1EBIYVUNYNk9RM0RrY3NiW......",
  "data": [
    {
      "type": "video",
      "videoId": "2XVcLrB7B3Y",
      "title": "Worst Minecraft Saw Trap Ever???",
      "description": "This is the worst saw trap ever done in minecraft",
      "viewCount": "32,819,569 views",
      "publishedTimeText": "13 years ago",
      "publishDate": "2012-12-11",
      "publishedAt": "2012-12-11T00:00:00Z",
      "lengthText": "2:37",
      "thumbnail": [
        {
          "url": "https://i.ytimg.com/vi/2XVcLrB7B3Y/hqdefault.jpg",
          "width": 336,
          "height": 188
        },
        {
          "url": "https://i.ytimg.com/vi/2XVcLrB7B3Y/hqdefault.jpg",
          "width": 246,
          "height": 138
        },
        {
          "url": "https://i.ytimg.com/vi/2XVcLrB7B3Y/hqdefault.jpg",
          "width": 168,
          "height": 94
        }
      ],
      "richThumbnail": [
        {
          "url": "https://i.ytimg.com/an_webp/2XVcLrB7B3Y/mqdefault_6s.webp?du=3000&sqp=CJa86ckG&rs=AOn4CLDsOBNNLXamcwvhu4ySeBoC2BOXYw",
          "width": 320,
          "height": 180
        }
      ]
    },
    {
      "type": "video",
      "videoId": "jP82d277Cc8",
      "title": "Harry Potter Mod In Minecraft! EPIC MUST SEE MOD!!!",
      "description": "One of the coolest mods i have ever seen",
      "viewCount": "6,362,258 views",
      "publishedTimeText": "13 years ago",
      "publishDate": "2012-12-11",
      "publishedAt": "2012-12-11T00:00:00Z",
      "lengthText": "3:59",
      "thumbnail": [
        {
          "url": "https://i.ytimg.com/vi/jP82d277Cc8/hqdefault.jpg",
          "width": 336,
          "height": 188
        },
        {
          "url": "https://i.ytimg.com/vi/jP82d277Cc8/hqdefault.jpg",
          "width": 246,
          "height": 138
        },
        {
          "url": "https://i.ytimg.com/vi/jP82d277Cc8/hqdefault.jpg",
          "width": 168,
          "height": 94
        }
      ],
      "richThumbnail": [
        {
          "url": "https://i.ytimg.com/an_webp/jP82d277Cc8/mqdefault_6s.webp?du=3000&sqp=CKqX6ckG&rs=AOn4CLB9zbLyF9gUXdzhMSfa6ni9nLPZzg",
          "width": 320,
          "height": 180
        }
      ]
    }
  ],
  "msg": ""
}
```

**Response Fields**:

- `meta` - Channel metadata including:
  - `channelId` - Unique channel identifier
  - `title` - Channel name
  - `description` - Channel description
  - `channelHandle` - Channel handle (e.g., @MrBeast)
  - `banner`, `tvBanner`, `mobileBanner` - Banner images (may be empty)
  - `avatar` - Array of avatar images in different sizes
  - `subscriberCountText` - Formatted subscriber count
  - `subscriberCount` - Raw subscriber count number
  - `videosCountText` - Formatted video count
  - `videosCount` - Raw video count
  - `keywords` - Array of channel keywords/tags
  - `isFamilySafe` - Boolean indicating if channel is family-safe
  - `availableCountries` - Array of country codes where content is available
  - `tabs` - Array of available tabs on the channel
- `continuation` - Token for pagination (empty string if no more results)
- `data` - Array of video objects containing:
  - `type` - Resource type (always "video")
  - `videoId` - Unique video identifier
  - `title` - Video title
  - `description` - Video description
  - `viewCount` - Formatted view count
  - `publishedTimeText` - Human-readable publish time (e.g., "13 years ago")
  - `publishDate` - ISO date of publication
  - `publishedAt` - ISO 8601 timestamp
  - `lengthText` - Video duration
  - `thumbnail` - Array of thumbnail objects with URL, width, and height
  - `richThumbnail` - Array of animated thumbnail objects (if available)
- `msg` - Status message (empty on success)

**Sort By Options:**

- **Latest**: Returns videos sorted by upload date, newest first (default)
- **Popular**: Returns videos sorted by view count, most popular first
- **Oldest**: Returns videos sorted by upload date, oldest first

##### Pagination

When a channel has more videos than can be returned in a single response, the API returns a `continuation` token in the response. Use this token to fetch the next page of results.

**How to use continuation tokens:**

1. Make an initial request without a continuation token to get the first page of videos
2. Check the `continuation` field in the response:
   - If it contains a token (non-empty string), more videos are available
   - If it's an empty string (`""`), you've reached the last page
3. To fetch the next page, make another request using the token from the previous response:
   - Set the **Continuation Token** parameter to the value from the `continuation` field
   - Keep all other parameters the same (Channel ID, Sort By)
4. Repeat until the `continuation` field returns an empty string

**Example pagination workflow:**

```
// First request (no token)
GET /api/external/channels/videos?id=UCX6OQ3DkcsbYNE6H8uQQuVA&sort_by=latest
```

```json
Response: {
  "continuation": "4qmFsgL1EBIYVUNYNk9RM0RrY3NiW......",
  "data": [
    /* Array of 30 video objects */
  ],
  "msg": ""
}
```

```
// Second request (with the token from the previous response)
GET /api/external/channels/videos?id=UCX6OQ3DkcsbYNE6H8uQQuVA&sort_by=latest&token=4qmFsgL1EBIYVUNYNk9RM0RrY3NiWU5
```

```json
Response: {
  "continuation": "",  // Empty string means no more results
  "data": [
    /* Array of remaining video objects */
  ],
  "msg": ""
}
```

**Implementation Tips:**

- Store the continuation token from each response to fetch subsequent pages
- Use a loop node in n8n to automatically paginate through all results
- The continuation token is specific to the channel and sort order - changing either requires starting over
- Continuation tokens may expire after some time, so fetch all pages in a single workflow execution

### Get Shorts

#### Get Shorts

```http
GET /api/external/channels/shorts
```

**Description**: Retrieve all short-form videos (YouTube Shorts) from a channel with sorting and pagination options.

> **Warning**
>
> **🥞 Quota Cost: 1 quota per request**
>
> Each call to this endpoint deducts **1 quota** from your account balance. Monitor your usage at [Manage API Key](https://dashboard.nexlev.io/nexlev-api/manage-api-key) to avoid interruptions.
>

**Query Parameters**: `id` (required), `sort_by` (optional), `token` (optional)

**Example URL**:

```
https://prod.dashboard.nexlev.io/api/external/channels/shorts?id=UCBJycsmduvYEL83R_U4JriQ&sort_by=oldest
```

**cURL Example**:

```bash
curl "https://prod.dashboard.nexlev.io/api/external/channels/shorts?id=UCBJycsmduvYEL83R_U4JriQ&sort_by=oldest" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Get all short-form videos (YouTube Shorts) from a YouTube channel with metadata. Supports pagination via continuation tokens to retrieve additional shorts beyond the initial response.

**When to use this operation:**

- Tracking short-form content performance separately
- Analyzing shorts strategy and engagement
- Comparing shorts vs long-form video performance
- Building shorts-specific databases

**Parameters**:

| Parameter          | Type   | Required | Description                                                                                   | Options                 |
| ------------------ | ------ | -------- | --------------------------------------------------------------------------------------------- | ----------------------- |
| Channel ID         | string | Yes      | The unique YouTube channel identifier                                                         | -                       |
| Sort By            | string | No       | Sort order for shorts (default: Latest)                                                       | Latest, Popular, Oldest |
| Continuation Token | string | No       | Token from previous response to fetch the next page of results (see Pagination section below) | -                       |

**Status Code**: `200 OK`

**Response Body**:

```json
{
  "meta": {
    "channelId": "UCBJycsmduvYEL83R_U4JriQ",
    "title": "Marques Brownlee",
    "description": "MKBHD: Quality Tech Videos | YouTuber | Geek | Consumer Electronics | Tech Head | Internet Personality! business@MKBHD.com NYC",
    "channelHandle": "@mkbhd",
    "banner": [],
    "tvBanner": [],
    "mobileBanner": [],
    "avatar": [
      {
        "url": "https://yt3.googleusercontent.com/qu4TmIaYUlS41-dJ9gZ7DUR3nilvmB5_11i6OKSdvNnBNiyOusZP1bMN6ICnuxtjFBb6ioKgRQ=s160-c-k-c0x00ffffff-no-rj",
        "width": 160,
        "height": 160
      },
      {
        "url": "https://yt3.googleusercontent.com/qu4TmIaYUlS41-dJ9gZ7DUR3nilvmB5_11i6OKSdvNnBNiyOusZP1bMN6ICnuxtjFBb6ioKgRQ=s72-c-k-c0x00ffffff-no-rj",
        "width": 72,
        "height": 72
      }
    ],
    "subscriberCountText": "20.6M subscribers",
    "subscriberCount": 20600000,
    "videosCountText": "0",
    "videosCount": "0",
    "keywords": ["MKBHD", "MarquesBrownlee", "Marques", "Brownlee"],
    "isFamilySafe": true,
    "availableCountries": ["OM", "RS", "RU", "AU", "BI", "CR", "PY", "..."],
    "tabs": ["Home", "Videos", "Shorts", "Live", "Playlists", "Posts", "Store"]
  },
  "continuation": "4qmFsgKzFhIYVUNCSnljc21kdXZZRUw4M1JfVTRKcmlRGpYW...",
  "data": [
    {
      "type": "shorts",
      "videoId": "Y5iif7YskU4",
      "title": "The Green iPhone 13 in 59 seconds!",
      "viewCountText": "5.3M views",
      "thumbnail": [],
      "isOriginalAspectRatio": true,
      "params": "CDMwAroBGFVDQkp5Y3NtZHV2WUVMODNSX1U0SnJpUQ%3D%3D",
      "playerParams": "8AEByAMkuAQ0ogYVAV9WnuM7NLX6lQsReMA0DMMRWxcBkAcC"
    },
    {
      "type": "shorts",
      "videoId": "xnPl9RPFLkE",
      "title": "AirPods Pro 2 vs Magnet Paper 👀",
      "viewCountText": "1.9M views",
      "thumbnail": [],
      "isOriginalAspectRatio": true,
      "params": "CDMwAroBGFVDQkp5Y3NtZHV2WUVMODNSX1U0SnJpUQ%3D%3D",
      "playerParams": "8AEByAMkuAQ0ogYVAV9WnuOEvgJ7lVH44zQpDT67RNB0kAcC"
    }
  ],
  "msg": ""
}
```

**Response Fields**:

- `meta` - Channel metadata including:
  - `channelId` - Unique channel identifier
  - `title` - Channel name
  - `description` - Channel description
  - `channelHandle` - Channel handle (e.g., @mkbhd)
  - `banner`, `tvBanner`, `mobileBanner` - Banner images (may be empty)
  - `avatar` - Array of avatar images in different sizes
  - `subscriberCountText` - Formatted subscriber count
  - `subscriberCount` - Raw subscriber count number
  - `videosCountText` - Formatted video count
  - `videosCount` - Raw video count
  - `keywords` - Array of channel keywords/tags
  - `isFamilySafe` - Boolean indicating if channel is family-safe
  - `availableCountries` - Array of country codes where content is available
  - `tabs` - Array of available tabs on the channel
- `continuation` - Token for pagination (empty string if no more results)
- `data` - Array of shorts objects containing:
  - `type` - Resource type (always "shorts")
  - `videoId` - Unique video identifier
  - `title` - Shorts title
  - `viewCountText` - Formatted view count
  - `thumbnail` - Array of thumbnail objects (may be empty)
  - `isOriginalAspectRatio` - Boolean indicating original aspect ratio
  - `params` - Encoded parameters for playback
  - `playerParams` - Player-specific parameters
- `msg` - Status message (empty on success)

**Sort By Options:**

- **Latest**: Returns shorts sorted by upload date, newest first (default)
- **Popular**: Returns shorts sorted by view count, most popular first
- **Oldest**: Returns shorts sorted by upload date, oldest first

##### Pagination

When a channel has more shorts than can be returned in a single response, the API returns a `continuation` token in the response. Use this token to fetch the next page of results.

**How to use continuation tokens:**

1. Make an initial request without a continuation token to get the first page of shorts
2. Check the `continuation` field in the response:
   - If it contains a token (non-empty string), more shorts are available
   - If it's an empty string (`""`), you've reached the last page
3. To fetch the next page, make another request using the token from the previous response:
   - Set the **Continuation Token** parameter to the value from the `continuation` field
   - Keep all other parameters the same (Channel ID, Sort By)
4. Repeat until the `continuation` field returns an empty string

**Example pagination workflow:**

```
// First request (no token)
GET /api/external/channels/shorts?id=UCBJycsmduvYEL83R_U4JriQ&sort_by=latest
```

```json
Response: {
  "meta": ,
  "continuation": "4qmFsgKzFhIYVUNCSnljc21kdXZZRUw4M1JfVTRKcmlRGpYW...",
  "data": [ /* Array of 30 shorts objects */ ],
  "msg": ""
}
```

```
// Second request (with the token from the previous response)
GET /api/external/channels/shorts?id=UCBJycsmduvYEL83R_U4JriQ&sort_by=latest&token=4qmFsgKzFhIYVUNCSnljc21kdXZZRUw4M1JfVTRKcmlR
```

```json
Response: {
  "meta": ,
  "continuation": "",  // Empty string means no more results
  "data": [ /* Array of remaining shorts objects */ ],
  "msg": ""
}
```

**Implementation Tips:**

- Store the continuation token from each response to fetch subsequent pages
- Use a loop node in n8n to automatically paginate through all results
- The continuation token is specific to the channel and sort order - changing either requires starting over
- Continuation tokens may expire after some time, so fetch all pages in a single workflow execution

### Get Playlists

#### Get Playlists

```http
GET /api/external/channels/playlists
```

**Description**: Retrieve all playlists from a channel with pagination support.

> **Warning**
>
> **🥞 Quota Cost: 1 quota per request**
>
> Each call to this endpoint deducts **1 quota** from your account balance. Monitor your usage at [Manage API Key](https://dashboard.nexlev.io/nexlev-api/manage-api-key) to avoid interruptions.
>

**Query Parameters**: `id` (required), `sort_by` (optional), `token` (optional)

**Example URL**:

```
https://prod.dashboard.nexlev.io/api/external/channels/playlists?id=UCBJycsmduvYEL83R_U4JriQ
```

**cURL Example**:

```bash
curl "https://prod.dashboard.nexlev.io/api/external/channels/playlists?id=UCBJycsmduvYEL83R_U4JriQ" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Get all playlists from a YouTube channel with detailed metadata including video count and thumbnails. Supports pagination via continuation tokens to retrieve additional playlists beyond the initial response.

**When to use this operation:**

- Analyzing how channels organize their content
- Discovering content series and collections
- Tracking playlist updates and additions
- Building playlist databases for content curation

**Parameters**:

| Parameter          | Type   | Required | Description                                                                                   | Options                      |
| ------------------ | ------ | -------- | --------------------------------------------------------------------------------------------- | ---------------------------- |
| Channel ID         | string | Yes      | The unique YouTube channel identifier                                                         | -                            |
| Sort By            | string | No       | Sort order for playlists (default: Date Added)                                                | Date Added, Last Video Added |
| Continuation Token | string | No       | Token from previous response to fetch the next page of results (see Pagination section below) | -                            |

**Status Code**: `200 OK`

**Response Body**:

```json
{
  "meta": {
    "channelId": "UCBJycsmduvYEL83R_U4JriQ",
    "title": "Marques Brownlee",
    "description": "MKBHD: Quality Tech Videos | YouTuber | Geek | Consumer Electronics | Tech Head | Internet Personality! business@MKBHD.com NYC",
    "channelHandle": "@mkbhd",
    "banner": [],
    "tvBanner": [],
    "mobileBanner": [],
    "avatar": [
      {
        "url": "https://yt3.googleusercontent.com/qu4TmIaYUlS41-dJ9gZ7DUR3nilvmB5_11i6OKSdvNnBNiyOusZP1bMN6ICnuxtjFBb6ioKgRQ=s160-c-k-c0x00ffffff-no-rj",
        "width": 160,
        "height": 160
      },
      {
        "url": "https://yt3.googleusercontent.com/qu4TmIaYUlS41-dJ9gZ7DUR3nilvmB5_11i6OKSdvNnBNiyOusZP1bMN6ICnuxtjFBb6ioKgRQ=s120-c-k-c0x00ffffff-no-rj",
        "width": 120,
        "height": 120
      },
      {
        "url": "https://yt3.googleusercontent.com/qu4TmIaYUlS41-dJ9gZ7DUR3nilvmB5_11i6OKSdvNnBNiyOusZP1bMN6ICnuxtjFBb6ioKgRQ=s72-c-k-c0x00ffffff-no-rj",
        "width": 72,
        "height": 72
      }
    ],
    "subscriberCountText": "20.6M subscribers",
    "subscriberCount": 20600000,
    "videosCountText": "1",
    "videosCount": "1",
    "keywords": ["MKBHD", "MarquesBrownlee", "Marques", "Brownlee"],
    "isFamilySafe": true,
    "availableCountries": ["US", "GB", "CA", "AU", "..."],
    "tabs": ["Home", "Videos", "Shorts", "Live", "Playlists", "Posts", "Store"]
  },
  "continuation": "",
  "data": [
    {
      "type": "playlist",
      "playlistId": "PLBsP89CPrMeNIuvr9j3_EQaMwaNJ6rhuQ",
      "title": "Retro Tech S2",
      "videoCount": "5 episodes",
      "videoId": "ifI_fwg55k8",
      "publishedTimeText": null,
      "thumbnail": [
        {
          "url": "https://i.ytimg.com/vi/ifI_fwg55k8/hqdefault.jpg",
          "width": 480,
          "height": 270
        }
      ]
    },
    {
      "type": "playlist",
      "playlistId": "PLBsP89CPrMePNK7yIxcyRdiIFentQVHra",
      "title": "MKBHD Interviews!",
      "videoCount": "13 episodes",
      "videoId": "7jaMJGtAV9M",
      "publishedTimeText": null,
      "thumbnail": [
        {
          "url": "https://i.ytimg.com/vi/7jaMJGtAV9M/hqdefault.jpg",
          "width": 480,
          "height": 270
        }
      ]
    },
    {
      "type": "playlist",
      "playlistId": "PLBsP89CPrMeOpKhXiKyXg8AjiConuTXvI",
      "title": "Auto Focus",
      "videoCount": "15 episodes",
      "videoId": "9O5PhuW927w",
      "publishedTimeText": null,
      "thumbnail": [
        {
          "url": "https://i.ytimg.com/vi/9O5PhuW927w/hqdefault.jpg",
          "width": 480,
          "height": 270
        }
      ]
    },
    {
      "type": "playlist",
      "playlistId": "PLBsP89CPrMeNm71T5gYC6jebm9vPbLBiP",
      "title": "Reviews!",
      "videoCount": "315 episodes",
      "videoId": "6d0lEMp8Vtk",
      "publishedTimeText": null,
      "thumbnail": [
        {
          "url": "https://i.ytimg.com/vi/6d0lEMp8Vtk/hqdefault.jpg",
          "width": 480,
          "height": 270
        }
      ]
    },
    {
      "type": "playlist",
      "playlistId": "PLBsP89CPrMeM2MmF4suOeT0vsic9nEC2Y",
      "title": "First Impressions!",
      "videoCount": "149 episodes",
      "videoId": "269OsrzG3Ew",
      "publishedTimeText": null,
      "thumbnail": [
        {
          "url": "https://i.ytimg.com/vi/269OsrzG3Ew/hqdefault.jpg",
          "width": 480,
          "height": 270
        }
      ]
    }
  ],
  "msg": ""
}
```

**Response Fields**:

- `meta` - Channel metadata including:
  - `channelId` - Unique channel identifier
  - `title` - Channel name
  - `description` - Channel description
  - `channelHandle` - Channel handle (e.g., @mkbhd)
  - `banner` - Array of banner images (may be empty)
  - `tvBanner` - Array of TV banner images (may be empty)
  - `mobileBanner` - Array of mobile banner images (may be empty)
  - `avatar` - Array of avatar images in different sizes
  - `subscriberCountText` - Formatted subscriber count
  - `subscriberCount` - Raw subscriber count number
  - `videosCountText` - Formatted video count text
  - `videosCount` - Raw video count
  - `keywords` - Array of channel keywords/tags
  - `isFamilySafe` - Boolean indicating if channel is family-safe
  - `availableCountries` - Array of country codes where content is available
  - `tabs` - Array of available tabs on the channel (e.g., Home, Videos, Shorts, etc.)
- `continuation` - Token for pagination to fetch more playlists (empty string if no more results)
- `data` - Array of playlist objects containing:
  - `type` - Resource type (always "playlist")
  - `playlistId` - Unique playlist identifier
  - `title` - Playlist title
  - `videoCount` - Number of videos/episodes in the playlist
  - `videoId` - First video ID in the playlist (may be empty string for some playlists)
  - `publishedTimeText` - Published time text (usually null for playlists)
  - `thumbnail` - Array of thumbnail objects with URL, width, and height
- `msg` - Message field (empty string on success)

**Sort By Options:**

- **Date Added**: Returns playlists sorted by creation date, newest first (default)
- **Last Video Added**: Returns playlists sorted by when the last video was added, most recently updated first

##### Pagination

When a channel has more playlists than can be returned in a single response, the API returns a `continuation` token in the response. Use this token to fetch the next page of results.

**How to use continuation tokens:**

1. Make an initial request without a continuation token to get the first page of playlists
2. Check the `continuation` field in the response:
   - If it contains a token (non-empty string), more playlists are available
   - If it's an empty string (`""`), you've reached the last page
3. To fetch the next page, make another request using the token from the previous response:
   - Set the **Continuation Token** parameter to the value from the `continuation` field
   - Keep all other parameters the same (Channel ID, Sort By)
4. Repeat until the `continuation` field returns an empty string

**Example pagination workflow:**

```
// First request (no token)
GET /api/external/channels/playlists?id=UCBJycsmduvYEL83R_U4JriQ&sort_by=date_added
```

```json
Response: {
  "continuation": "4qmFsgI2EiRWTFBMQnNQODlDUHJNZU5tNzFUNWdZQzZqZWJtOXZQYkxCaVAaGENBRjZCbEJVT2tOSFZRJTNEJTNEmgIiUExCc1A4OUNQck1lTm03MVQ1Z1lDNmplYm05dlBiTEJpUA",
  "data": [ /* 30 playlists */ ]
}
```

```
// Second request (with the token from the previous response)
GET /api/external/channels/playlists?id=UCBJycsmduvYEL83R_U4JriQ&sort_by=date_added&token=4qmFsgI2EiRWTFBMQnNQODlDUHJNZU5tNzFUNWdZQzZqZWJtOXZQYkxCaVAaGENBRjZCbEJVT2tOSFZRJTNEJTNEmgIiUExCc1A4OUNQck1lTm03MVQ1Z1lDNmplYm05dlBiTEJpUA
```

```json
Response: {
  "continuation": "",  // Empty string means no more results
  "data": [ /* remaining playlists */ ]
}
```

**Implementation Tips:**

- Store the continuation token from each response to fetch subsequent pages
- Use a loop node in n8n to automatically paginate through all results
- The continuation token is specific to the channel and sort order - changing either requires starting over
- Continuation tokens may expire after some time, so fetch all pages in a single workflow execution

### Get Outliers

#### Get Outliers

```http
GET /api/external/channels/outliers
```

**Description**: Identify high-performing videos (outliers) that significantly exceed the channel's average performance.

> **Warning**
>
> **🥞 Quota Cost: 1 quota per request**
>
> Each call to this endpoint deducts **1 quota** from your account balance. Monitor your usage at [Manage API Key](https://dashboard.nexlev.io/nexlev-api/manage-api-key) to avoid interruptions.
>

**Query Parameters**: `id` (required), `maxVideos` (optional), `minOutlierThreshold` (optional)

**Example URL**:

```
https://prod.dashboard.nexlev.io/api/external/channels/outliers?id=UCBJycsmduvYEL83R_U4JriQ&maxVideos=30&minOutlierThreshold=2.0
```

**cURL Example**:

```bash
curl "https://prod.dashboard.nexlev.io/api/external/channels/outliers?id=UCBJycsmduvYEL83R_U4JriQ&maxVideos=30&minOutlierThreshold=2.0" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Get videos from a YouTube channel that have significantly higher views than the channel's average video performance. This operation analyzes recent videos to identify outlier content that performed exceptionally well, helping you discover what content resonates most with the audience.

**When to use this operation:**

- Identifying viral or exceptionally successful content
- Understanding what content types resonate with audiences
- Analyzing patterns in high-performing videos
- Making data-driven content strategy decisions
- Finding inspiration for future content topics

**Parameters**:

| Parameter                 | Type    | Required | Description                                                                                                                        | Default |
| ------------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------- |
| Channel ID                | string  | Yes      | The unique YouTube channel identifier                                                                                              | -       |
| Maximum Videos            | integer | No       | Number of recent videos to analyze (higher values may affect performance and API usage)                                            | 30      |
| Minimum Outlier Threshold | number  | No       | Minimum multiplier for a video to be considered an outlier (e.g., 2.0 means videos with 2x or more views than the channel average) | 2.0     |

**Status Code**: `200 OK`

**Response Body**:

```json
{
  "channelId": "UCBJycsmduvYEL83R_U4JriQ",
  "channelInfo": {
    "channelId": "UCBJycsmduvYEL83R_U4JriQ",
    "title": "Marques Brownlee",
    "description": "MKBHD: Quality Tech Videos | YouTuber | Geek | Consumer Electronics | Tech Head | Internet Personality!\n\nbusiness@MKBHD.com\n\nNYC",
    "avatar": [
      {
        "url": "https://yt3.googleusercontent.com/qu4TmIaYUlS41-dJ9gZ7DUR3nilvmB5_11i6OKSdvNnBNiyOusZP1bMN6ICnuxtjFBb6ioKgRQ=s160-c-k-c0x00ffffff-no-rj",
        "width": 160,
        "height": 160
      }
    ],
    "channelHandle": "@mkbhd",
    "subscriberCountText": "20.6M subscribers",
    "subscriberCount": 20600000,
    "videosCountText": "1,786 videos",
    "videosCount": "1786",
    "keywords": ["MKBHD", "MarquesBrownlee", "Marques", "Brownlee"],
    "viewCountText": "5,148,915,987 views",
    "viewCount": "5148915987",
    "avgViews": 2882932
  },
  "outliers": [
    {
      "type": "video",
      "videoId": "idEAABFzpfg",
      "title": "iPhone 17/Pro/Air Impressions: Spot the Red Flags!",
      "description": "Everything new from Apple's 2025 September event...",
      "viewCount": "13,941,263 views",
      "publishedTimeText": "3 months ago",
      "publishDate": "2025-09-18",
      "publishedAt": "2025-09-18T00:00:00Z",
      "lengthText": "14:50",
      "thumbnail": [
        {
          "url": "https://i.ytimg.com/vi/idEAABFzpfg/hqdefault.jpg",
          "width": 336,
          "height": 188
        }
      ],
      "richThumbnail": [
        {
          "url": "https://i.ytimg.com/an_webp/idEAABFzpfg/mqdefault_6s.webp?du=3000&sqp=CMiGjsoG&rs=AOn4CLDkCLe56UR5otHAm0Jl6CTDkIGe6A",
          "width": 320,
          "height": 180
        }
      ],
      "outlierScore": "4.8x"
    },
    {
      "type": "video",
      "videoId": "Mb6H7trzMfI",
      "title": "Driving Xiaomi's Electric Car: Are we Cooked?",
      "description": "Xiaomi (yes, that Xiaomi) made a ridiculously good car for the price...",
      "viewCount": "7,890,197 views",
      "publishedTimeText": "12 days ago",
      "publishDate": "2025-12-06",
      "publishedAt": "2025-12-06T00:00:00Z",
      "lengthText": "17:25",
      "thumbnail": [
        {
          "url": "https://i.ytimg.com/vi/Mb6H7trzMfI/hqdefault.jpg",
          "width": 336,
          "height": 188
        }
      ],
      "richThumbnail": [
        {
          "url": "https://i.ytimg.com/an_webp/Mb6H7trzMfI/mqdefault_6s.webp?du=3000&sqp=CIb8jcoG&rs=AOn4CLDxwnT80aMAcDFHJZmb2k7e0tx11g",
          "width": 320,
          "height": 180
        }
      ],
      "outlierScore": "2.7x"
    }
  ],
  "totalOutliers": 8,
  "msg": "Success"
}
```

**Response Fields**:

- `channelId` - The channel identifier
- `channelInfo` - Detailed channel information including:
  - Basic metadata (title, description, handle)
  - Avatar images in multiple sizes
  - Subscriber and video counts
  - Channel keywords
  - View statistics
  - **`avgViews`** - Average views per video for this channel (used to calculate outliers)
- `outliers` - Array of video objects that exceeded the outlier threshold:
  - `type` - Resource type (always "video")
  - `videoId` - Unique video identifier
  - `title` - Video title
  - `description` - Video description (truncated)
  - `viewCount` - Formatted view count
  - `publishedTimeText` - Human-readable publish time (e.g., "3 months ago")
  - `publishDate` - ISO date of publication
  - `publishedAt` - ISO 8601 timestamp
  - `lengthText` - Video duration
  - `thumbnail` - Array of thumbnail objects with URL, width, and height
  - `richThumbnail` - Array of animated thumbnail objects (if available)
  - **`outlierScore`** - How many times above average this video performed (e.g., "4.8x" means 4.8 times the average views)
- `totalOutliers` - Total number of outlier videos found
- `msg` - Status message

**Understanding Outlier Scores**:

The `outlierScore` field shows how much a video outperformed the channel average:

- **2.0x** - Video has twice the average views (minimum with default threshold)
- **4.8x** - Video has 4.8 times the average views (exceptional performance)
- Videos are sorted by outlier score in descending order (highest performers first)

**What If No Outliers Are Found?**

If the API returns an empty `outliers` array, it means no videos exceeded your outlier threshold. To find outliers, try:

1. **Increase Maximum Videos**: Analyze more recent videos (e.g., 50 or 100 instead of 30)
2. **Decrease Minimum Outlier Threshold**: Lower the threshold (e.g., 1.5x instead of 2x)
3. **Check Channel Consistency**: Some channels have very consistent view counts, making outliers rare

**Example**: If a channel's average video gets 1M views, with a threshold of 2, only videos with 2M+ views will be considered outliers.

**Performance Considerations**:

- ⚠️ Analyzing more videos (higher Maximum Videos) increases processing time and API usage
- ⚠️ Channels with consistent view counts may have few or no outliers
- ✅ Default settings (30 videos, 2x threshold) work well for most channels
- ✅ For large channels, consider analyzing 50-100 recent videos for better insights

## Error Responses

### Bad Request

**Status Code**: `400 Bad Request`

**Description**: The request was invalid or malformed.

```json
{
  "error": {
    "code": 400,
    "message": "Invalid channel ID format",
    "details": "Channel ID must be a valid YouTube channel identifier"
  }
}
```

### Unauthorized

**Status Code**: `401 Unauthorized`

**Description**: Authentication credentials are missing or invalid.

```json
{
  "error": {
    "code": 401,
    "message": "Unauthorized",
    "details": "Invalid API key or credentials not provided. Create your API key at https://dashboard.nexlev.io/nexlev-api/create-api-key"
  }
}
```

### Not Found

**Status Code**: `404 Not Found`

**Description**: The specified channel could not be found.

```json
{
  "error": {
    "code": 404,
    "message": "Channel not found",
    "details": "No channel exists with the provided channel ID"
  }
}
```

### Rate Limit

**Status Code**: `429 Too Many Requests`

**Description**: You have exceeded your API rate limit.

```json
{
  "error": {
    "code": 429,
    "message": "Rate limit exceeded",
    "details": "You have exceeded your API quota. Please try again later.",
    "retryAfter": 3600
  }
}
```
