> For the complete documentation index, see [llms.txt](https://docs.pullbay.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pullbay.com/api-reference/endpoints/youtube.md).

# Youtube

YouTube: channels, videos, shorts, live streams, comments, search, trending, and hashtags. All endpoints are read-only `GET` requests and return public YouTube data — no channel or video of your own is required.

**Base URL:** `https://api.pullbay.com/`

## Endpoints

| Endpoint                                 | Description                                       | Pagination        |
| ---------------------------------------- | ------------------------------------------------- | ----------------- |
| `GET /youtube/channel`                   | Get a single channel by ID, handle, or URL        | —                 |
| `GET /youtube/channel/{id}/videos`       | Get videos uploaded by a channel                  | Cursor / maxItems |
| `GET /youtube/channel/{id}/shorts`       | Get shorts uploaded by a channel                  | Cursor / maxItems |
| `GET /youtube/channel/{id}/live-streams` | Get live streams (current and past) for a channel | Cursor / maxItems |
| `GET /youtube/video`                     | Get a single video's full metadata                | —                 |
| `GET /youtube/shorts/{id}`               | Get a single short's full metadata                | —                 |
| `GET /youtube/comments`                  | Get top-level comments on a video                 | Cursor / maxItems |
| `GET /youtube/search`                    | Search videos, channels, or playlists             | Cursor / maxItems |
| `GET /youtube/hashtag`                   | Get videos tagged with a hashtag                  | Cursor / maxItems |
| `GET /youtube/trending`                  | Get currently trending videos                     | —                 |

***

### Get Channel

Returns channel details. Provide exactly one of `id`, `handle`, or `channelUrl`.

**Request**

```bash
GET /youtube/channel
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter    | Type   | Required                          | Description                                                    |
| ------------ | ------ | --------------------------------- | -------------------------------------------------------------- |
| `id`         | string | One of `id`/`handle`/`channelUrl` | Channel ID, 1–100 characters (e.g. `UCX6OQ3DkcsbYNE6H8uQQuVA`) |
| `handle`     | string | One of `id`/`handle`/`channelUrl` | Channel handle, 1–100 characters (e.g. `@MrBeast`)             |
| `channelUrl` | string | One of `id`/`handle`/`channelUrl` | Full URL to the channel, 10–1000 characters                    |

**Example**

```bash
curl -G "https://api.pullbay.com/youtube/channel" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d handle=@MrBeast
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "channel",
      "id": "UCX6OQ3DkcsbYNE6H8uQQuVA",
      "name": "MrBeast",
      "handle": "@MrBeast",
      "url": "http://www.youtube.com/@MrBeast",
      "description": "SUBSCRIBE FOR A COOKIE!",
      "thumbnails": "https://yt3.googleusercontent.com/nxYrc_1_2f77DoBadyxMTmv7ZpRZapHR5jbuYe7PlPd5cIRJxtNNEYyOC0ZsxaDyJJzXrnJiuDE",
      "isFamilySafe": true,
      "subscriberCount": "421M subscribers",
      "availableCountries": ["US", "GB", "CA"],
      "tags": ["mrbeast", "beast"],
      "joinedAt": "Joined Feb 20, 2012",
      "viewCount": "87,234,567,890 views",
      "videoCount": 837
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`.

***

### Get Channel Videos

Returns videos uploaded by the channel. Use `cursor` to paginate or `maxItems` for a one-shot bulk pull (mutually exclusive).

**Request**

```bash
GET /youtube/channel/{id}/videos
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter  | Type    | Required | Description                                                                           |
| ---------- | ------- | -------- | ------------------------------------------------------------------------------------- |
| `id`       | string  | Yes      | Channel ID, 1–100 characters — passed in the URL path                                 |
| `cursor`   | string  | No       | Opaque pagination cursor from a previous response. Mutually exclusive with `maxItems` |
| `maxItems` | integer | No       | One-shot bulk pull, 1–200 results. Mutually exclusive with `cursor`                   |

**Example**

```bash
curl -G "https://api.pullbay.com/youtube/channel/UCX6OQ3DkcsbYNE6H8uQQuVA/videos" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d maxItems=25
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "video",
      "id": "EerdGm-ehJQ",
      "url": "https://www.youtube.com/watch?v=EerdGm-ehJQ",
      "title": "JavaScript Tutorial Full Course - Beginner to Pro",
      "description": "Get a certificate for this course",
      "thumbnails": [
        { "url": "https://i.ytimg.com/vi/EerdGm-ehJQ/hqdefault.jpg", "width": 480, "height": 360 }
      ],
      "richThumbnail": [],
      "channel": {
        "id": "UCX6OQ3DkcsbYNE6H8uQQuVA",
        "name": "MrBeast",
        "handle": "@MrBeast",
        "url": "https://www.youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA",
        "subscriberCount": "421M subscribers",
        "badges": [],
        "thumbnails": []
      },
      "publishDate": "1 year ago",
      "views": "8531468",
      "duration": "22:15:57"
    }
  ],
  "pagination": { "page": null, "hasNextPage": true, "cursor": "CAUQAA", "offset": null },
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. Cost scales with the number of videos returned, not the number of requests.

***

### Get Channel Shorts

Returns shorts uploaded by the channel. Use `cursor` to paginate or `maxItems` for a one-shot bulk pull (mutually exclusive).

**Request**

```bash
GET /youtube/channel/{id}/shorts
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter  | Type    | Required | Description                                                                           |
| ---------- | ------- | -------- | ------------------------------------------------------------------------------------- |
| `id`       | string  | Yes      | Channel ID, 1–100 characters — passed in the URL path                                 |
| `cursor`   | string  | No       | Opaque pagination cursor from a previous response. Mutually exclusive with `maxItems` |
| `maxItems` | integer | No       | One-shot bulk pull, 1–200 results. Mutually exclusive with `cursor`                   |

**Example**

```bash
curl -G "https://api.pullbay.com/youtube/channel/UCX6OQ3DkcsbYNE6H8uQQuVA/shorts" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d maxItems=25
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "video",
      "id": "kJQP7kiw5Fk",
      "url": "https://www.youtube.com/watch?v=kJQP7kiw5Fk",
      "title": "I Gave My 1,000th Subscriber A Island",
      "description": "Shorts edit of the full video",
      "thumbnails": [
        { "url": "https://i.ytimg.com/vi/kJQP7kiw5Fk/hqdefault.jpg", "width": 480, "height": 360 }
      ],
      "richThumbnail": [],
      "channel": {
        "id": "UCX6OQ3DkcsbYNE6H8uQQuVA",
        "name": "MrBeast",
        "handle": "@MrBeast",
        "url": "https://www.youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA",
        "subscriberCount": "421M subscribers",
        "badges": [],
        "thumbnails": []
      },
      "publishDate": "3 weeks ago",
      "views": "42531468",
      "duration": "0:58"
    }
  ],
  "pagination": { "page": null, "hasNextPage": true, "cursor": "CAUQAA", "offset": null },
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. Cost scales with the number of shorts returned, not the number of requests.

***

### Get Channel Live Streams

Returns live streams (current and past) for the channel. Use `cursor` to paginate or `maxItems` for a one-shot bulk pull (mutually exclusive).

**Request**

```bash
GET /youtube/channel/{id}/live-streams
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter  | Type    | Required | Description                                                                           |
| ---------- | ------- | -------- | ------------------------------------------------------------------------------------- |
| `id`       | string  | Yes      | Channel ID, 1–100 characters — passed in the URL path                                 |
| `cursor`   | string  | No       | Opaque pagination cursor from a previous response. Mutually exclusive with `maxItems` |
| `maxItems` | integer | No       | One-shot bulk pull, 1–200 results. Mutually exclusive with `cursor`                   |

**Example**

```bash
curl -G "https://api.pullbay.com/youtube/channel/UCX6OQ3DkcsbYNE6H8uQQuVA/live-streams" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d maxItems=25
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "video",
      "id": "5qap5aO4i9A",
      "url": "https://www.youtube.com/watch?v=5qap5aO4i9A",
      "title": "lofi hip hop radio - beats to relax/study to",
      "description": "24/7 livestream",
      "thumbnails": [
        { "url": "https://i.ytimg.com/vi/5qap5aO4i9A/hqdefault.jpg", "width": 480, "height": 360 }
      ],
      "richThumbnail": [],
      "channel": {
        "id": "UCX6OQ3DkcsbYNE6H8uQQuVA",
        "name": "MrBeast",
        "handle": "@MrBeast",
        "url": "https://www.youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA",
        "subscriberCount": "421M subscribers",
        "badges": [],
        "thumbnails": []
      },
      "publishDate": "Streamed live",
      "views": "9823145",
      "duration": "LIVE"
    }
  ],
  "pagination": { "page": null, "hasNextPage": true, "cursor": "CAUQAA", "offset": null },
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. Cost scales with the number of streams returned, not the number of requests.

***

### Get Video

Returns full metadata for a single video by its 11-character video `id`.

**Request**

```bash
GET /youtube/video
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter | Type   | Required | Description                                                 |
| --------- | ------ | -------- | ----------------------------------------------------------- |
| `id`      | string | Yes      | 11-character video ID, 5–20 characters (e.g. `dQw4w9WgXcQ`) |
| `type`    | string | No       | `video` or `shorts` — hints the lookup at the content type  |

**Example**

```bash
curl -G "https://api.pullbay.com/youtube/video" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d id=dQw4w9WgXcQ \
  -d type=video
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "video",
      "id": "dQw4w9WgXcQ",
      "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
      "status": "OK",
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
      "description": "The official video for \"Never Gonna Give You Up\" by Rick Astley.",
      "duration": 213,
      "views": 1766758607,
      "likes": 18978439,
      "comments": 2400000,
      "channel": {
        "id": "UCuAXFkgsw1L7xaCfnd5JJOw",
        "name": "Rick Astley",
        "handle": "@RickAstleyYT",
        "url": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw",
        "subscriberCount": "4.49M subscribers",
        "badges": ["Official Artist Channel"],
        "thumbnails": []
      },
      "keywords": ["rick astley", "Never Gonna Give You Up"],
      "superTitle": "#RickAstley #NeverGonnaGiveYouUp #OfficialMusicVideo",
      "category": "Music",
      "isRatingsAllowed": true,
      "isLive": false,
      "isFamilySafe": true,
      "isPrivate": false,
      "isExclusive": false,
      "thumbnails": [
        { "url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg", "width": 480, "height": 360 }
      ]
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`.

***

### Get Short

Returns full metadata for a single short by its video `id`.

**Request**

```bash
GET /youtube/shorts/{id}
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter | Type   | Required | Description                                                     |
| --------- | ------ | -------- | --------------------------------------------------------------- |
| `id`      | string | Yes      | 11-character video ID, 5–20 characters — passed in the URL path |

**Example**

```bash
curl -G "https://api.pullbay.com/youtube/shorts/kJQP7kiw5Fk" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "video",
      "id": "kJQP7kiw5Fk",
      "title": "I Gave My 1,000th Subscriber A Island",
      "status": "OK",
      "url": "https://www.youtube.com/watch?v=kJQP7kiw5Fk",
      "description": "Shorts edit of the full video",
      "duration": 58,
      "views": 42531468,
      "likes": 3198452,
      "comments": 18230,
      "channel": {
        "id": "UCX6OQ3DkcsbYNE6H8uQQuVA",
        "name": "MrBeast",
        "handle": "@MrBeast",
        "url": "https://www.youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA",
        "subscriberCount": "421M subscribers",
        "badges": [],
        "thumbnails": []
      },
      "keywords": ["mrbeast", "shorts", "giveaway"],
      "superTitle": "#MrBeast #Shorts",
      "category": "Entertainment",
      "isRatingsAllowed": true,
      "isLive": false,
      "isFamilySafe": true,
      "isPrivate": false,
      "isExclusive": false,
      "thumbnails": [
        { "url": "https://i.ytimg.com/vi/kJQP7kiw5Fk/hqdefault.jpg", "width": 480, "height": 360 }
      ]
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`.

***

### Get Comments

Returns top-level comments for a video. `sort` is `top` (default) or `latest`. Use `cursor` to paginate or `maxItems` for a one-shot bulk pull (mutually exclusive).

**Request**

```bash
GET /youtube/comments
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter  | Type    | Required | Description                                                                           |
| ---------- | ------- | -------- | ------------------------------------------------------------------------------------- |
| `id`       | string  | Yes      | 11-character video ID, 5–20 characters                                                |
| `sort`     | string  | No       | `top` (default) or `latest`                                                           |
| `cursor`   | string  | No       | Opaque pagination cursor from a previous response. Mutually exclusive with `maxItems` |
| `maxItems` | integer | No       | One-shot bulk pull, 1–500 results. Mutually exclusive with `cursor`                   |

**Example**

```bash
curl -G "https://api.pullbay.com/youtube/comments" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d id=dQw4w9WgXcQ \
  -d sort=top \
  -d maxItems=50
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "comment",
      "id": "UgwJsXlCbEu8-5nIK3h4AaABAg",
      "text": "Check out the latest Space Souvenirs Drop on the kurzgesagt shop",
      "likeCount": "1.8K",
      "replyCount": "59",
      "publishedTime": "1 month ago",
      "author": {
        "id": "UCsXVk37bltHxD1rDPwtNM8Q",
        "name": "@kurzgesagt",
        "thumbnails": "https://yt3.ggpht.com/ytc/AIdro_n1Ribd7LwdP_qKtqWL3ZDfIgv9M1d6g78VwpHGXVR2Ir4=s88-c-k-c0x00ffffff-no-rj"
      }
    }
  ],
  "pagination": { "page": null, "hasNextPage": true, "cursor": "Eg0SC2RRdzR3OVdnWGNRGAYyJSIRIgtkUXc0dzlXZ1hjURABGAA", "offset": null },
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. Cost scales with the number of comments returned, not the number of requests.

***

### Search YouTube

Search YouTube. `mode` selects what to search for (`video`, `channel`, or `playlist`). When `mode=video`, results match the `YoutubeVideo` shape; other modes return shape variants. Use `cursor` to paginate or `maxItems` for a one-shot bulk pull (mutually exclusive).

**Request**

```bash
GET /youtube/search
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter    | Type    | Required | Description                                                                                                                       |
| ------------ | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `query`      | string  | Yes      | Search query, 1–100 characters                                                                                                    |
| `mode`       | string  | Yes      | `video`, `channel`, or `playlist`                                                                                                 |
| `sortBy`     | string  | No       | `relevance`, `rating`, `upload_date`, or `view_count`                                                                             |
| `lang`       | string  | No       | Language code, 2–5 characters                                                                                                     |
| `geo`        | string  | No       | Region code, 2–5 characters                                                                                                       |
| `duration`   | string  | No       | `short`, `medium`, or `long`                                                                                                      |
| `features`   | string  | No       | One feature filter — `360`, `hd`, `subtitles`, `creative_commons`, `3d`, `live`, `purchased`, `4k`, `location`, `hdr`, or `vr180` |
| `uploadDate` | string  | No       | `hour`, `today`, `week`, `month`, or `year`                                                                                       |
| `cursor`     | string  | No       | Opaque pagination cursor from a previous response. Mutually exclusive with `maxItems`                                             |
| `maxItems`   | integer | No       | One-shot bulk pull, 1–200 results. Mutually exclusive with `cursor`                                                               |

**Example**

```bash
curl -G "https://api.pullbay.com/youtube/search" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d query="javascript tutorial" \
  -d mode=video \
  -d sortBy=relevance \
  -d duration=long
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "video",
      "id": "EerdGm-ehJQ",
      "url": "https://www.youtube.com/watch?v=EerdGm-ehJQ",
      "title": "JavaScript Tutorial Full Course - Beginner to Pro",
      "description": "Get a certificate for this course",
      "thumbnails": [
        { "url": "https://i.ytimg.com/vi/EerdGm-ehJQ/hqdefault.jpg", "width": 480, "height": 360 }
      ],
      "richThumbnail": [],
      "channel": {
        "id": "UCW5YeuERMmlnqo4oq8vwUpg",
        "name": "freeCodeCamp.org",
        "handle": "@freecodecamp",
        "url": "https://www.youtube.com/channel/UCW5YeuERMmlnqo4oq8vwUpg",
        "subscriberCount": "10.4M subscribers",
        "badges": [],
        "thumbnails": []
      },
      "publishDate": "1 year ago",
      "views": "8531468",
      "duration": "22:15:57"
    }
  ],
  "pagination": { "page": null, "hasNextPage": true, "cursor": "CAUQAA", "offset": null },
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. Using `maxItems` to pull more results in one call costs proportionally more than a single page.

***

### Get Hashtag

Returns videos tagged with `tag`. Use `cursor` to paginate or `maxItems` for a one-shot bulk pull (mutually exclusive).

**Request**

```bash
GET /youtube/hashtag
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter  | Type    | Required | Description                                                                           |
| ---------- | ------- | -------- | ------------------------------------------------------------------------------------- |
| `tag`      | string  | Yes      | Hashtag to look up, 1–100 characters, without the `#` (e.g. `shorts`)                 |
| `cursor`   | string  | No       | Opaque pagination cursor from a previous response. Mutually exclusive with `maxItems` |
| `maxItems` | integer | No       | One-shot bulk pull, 1–200 results. Mutually exclusive with `cursor`                   |

**Example**

```bash
curl -G "https://api.pullbay.com/youtube/hashtag" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d tag=shorts \
  -d maxItems=25
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "video",
      "id": "kJQP7kiw5Fk",
      "url": "https://www.youtube.com/watch?v=kJQP7kiw5Fk",
      "title": "I Gave My 1,000th Subscriber A Island #shorts",
      "description": "Shorts edit of the full video",
      "thumbnails": [
        { "url": "https://i.ytimg.com/vi/kJQP7kiw5Fk/hqdefault.jpg", "width": 480, "height": 360 }
      ],
      "richThumbnail": [],
      "channel": {
        "id": "UCX6OQ3DkcsbYNE6H8uQQuVA",
        "name": "MrBeast",
        "handle": "@MrBeast",
        "url": "https://www.youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA",
        "subscriberCount": "421M subscribers",
        "badges": [],
        "thumbnails": []
      },
      "publishDate": "3 weeks ago",
      "views": "42531468",
      "duration": "0:58"
    }
  ],
  "pagination": { "page": null, "hasNextPage": true, "cursor": "CAUQAA", "offset": null },
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. Cost scales with the number of videos returned, not the number of requests.

***

### Get Trending

Returns currently trending videos. Use `geo` to target a country (e.g. `US`, `GB`).

**Request**

```bash
GET /youtube/trending
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter | Type   | Required | Description                                   |
| --------- | ------ | -------- | --------------------------------------------- |
| `geo`     | string | No       | Region code, 2–5 characters (e.g. `US`, `GB`) |

**Example**

```bash
curl -G "https://api.pullbay.com/youtube/trending" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d geo=US
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "video",
      "id": "5qap5aO4i9A",
      "url": "https://www.youtube.com/watch?v=5qap5aO4i9A",
      "title": "lofi hip hop radio - beats to relax/study to",
      "description": "24/7 livestream",
      "thumbnails": [
        { "url": "https://i.ytimg.com/vi/5qap5aO4i9A/hqdefault.jpg", "width": 480, "height": 360 }
      ],
      "richThumbnail": [],
      "channel": {
        "id": "UCSJ4gkVC6NrvII8umztf0Ow",
        "name": "Lofi Girl",
        "handle": "@LofiGirl",
        "url": "https://www.youtube.com/channel/UCSJ4gkVC6NrvII8umztf0Ow",
        "subscriberCount": "13.7M subscribers",
        "badges": [],
        "thumbnails": []
      },
      "publishDate": "Streamed live",
      "views": "9823145",
      "duration": "LIVE"
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`.

***

## Object schemas

### Channel object

| Field                | Type    | Description                                                   |
| -------------------- | ------- | ------------------------------------------------------------- |
| `type`               | string  | Always `channel`                                              |
| `id`                 | string  | Channel ID                                                    |
| `name`               | string  | Channel display name                                          |
| `handle`             | string  | Channel handle (e.g. `@MrBeast`)                              |
| `url`                | string  | Channel URL                                                   |
| `description`        | string  | Channel "About" description                                   |
| `thumbnails`         | string  | Channel avatar image URL                                      |
| `isFamilySafe`       | boolean | Whether the channel is marked family-safe                     |
| `subscriberCount`    | string  | Subscriber count, formatted (e.g. `421M subscribers`)         |
| `availableCountries` | array   | Country codes where the channel is available                  |
| `tags`               | array   | Channel keyword tags                                          |
| `joinedAt`           | string  | Channel creation date, formatted (e.g. `Joined Feb 20, 2012`) |
| `viewCount`          | string  | All-time view count, formatted                                |
| `videoCount`         | integer | Total number of uploaded videos                               |

### Channel reference object

Lightweight channel reference embedded in video and comment results.

| Field             | Type                                    | Description                                     |
| ----------------- | --------------------------------------- | ----------------------------------------------- |
| `id`              | string                                  | Channel ID                                      |
| `name`            | string                                  | Channel display name                            |
| `handle`          | string                                  | Channel handle                                  |
| `url`             | string                                  | Channel URL                                     |
| `subscriberCount` | string                                  | Subscriber count, formatted                     |
| `badges`          | array                                   | Channel badges (e.g. `Official Artist Channel`) |
| `thumbnails`      | array of [Thumbnail](#thumbnail-object) | Channel avatar thumbnails at different sizes    |

### Video object

Video result returned by the channel videos/shorts/live-streams, search, hashtag, and trending endpoints.

| Field           | Type                                           | Description                                                            |
| --------------- | ---------------------------------------------- | ---------------------------------------------------------------------- |
| `type`          | string                                         | Always `video`                                                         |
| `id`            | string                                         | 11-character video ID                                                  |
| `url`           | string                                         | Video watch URL                                                        |
| `title`         | string                                         | Video title                                                            |
| `description`   | string                                         | Video description snippet                                              |
| `thumbnails`    | array of [Thumbnail](#thumbnail-object)        | Thumbnail images at different sizes                                    |
| `richThumbnail` | array of [Thumbnail](#thumbnail-object)        | Animated/rich preview thumbnails, if available                         |
| `channel`       | [Channel reference](#channel-reference-object) | Uploading channel                                                      |
| `publishDate`   | string                                         | Relative publish date (e.g. `1 year ago`)                              |
| `views`         | string                                         | View count as a string                                                 |
| `duration`      | string                                         | Video duration, formatted (e.g. `22:15:57`); `LIVE` for active streams |

### Video detail object

Full video metadata returned by the get video and get short endpoints.

| Field              | Type                                           | Description                                    |
| ------------------ | ---------------------------------------------- | ---------------------------------------------- |
| `type`             | string                                         | Always `video`                                 |
| `id`               | string                                         | 11-character video ID                          |
| `title`            | string                                         | Video title                                    |
| `status`           | string                                         | Lookup status (e.g. `OK`)                      |
| `url`              | string                                         | Video watch URL                                |
| `description`      | string                                         | Full video description                         |
| `duration`         | integer                                        | Length in seconds                              |
| `views`            | integer                                        | View count                                     |
| `likes`            | integer                                        | Like count                                     |
| `comments`         | integer                                        | Total comment count                            |
| `channel`          | [Channel reference](#channel-reference-object) | Uploading channel                              |
| `keywords`         | array                                          | Video tags/keywords                            |
| `superTitle`       | string                                         | Hashtag/super-title line shown above the title |
| `category`         | string                                         | YouTube content category (e.g. `Music`)        |
| `isRatingsAllowed` | boolean                                        | Whether likes/dislikes are enabled             |
| `isLive`           | boolean                                        | Whether the video is a live broadcast          |
| `isFamilySafe`     | boolean                                        | Whether the video is marked family-safe        |
| `isPrivate`        | boolean                                        | Whether the video is private                   |
| `isExclusive`      | boolean                                        | Whether the video is exclusive/members-only    |
| `thumbnails`       | array of [Thumbnail](#thumbnail-object)        | Thumbnail images at different sizes            |

### Comment object

| Field           | Type                                     | Description                                |
| --------------- | ---------------------------------------- | ------------------------------------------ |
| `type`          | string                                   | Always `comment`                           |
| `id`            | string                                   | Comment ID                                 |
| `text`          | string                                   | Comment body text                          |
| `likeCount`     | string                                   | Like count, formatted (e.g. `1.8K`)        |
| `replyCount`    | string                                   | Reply count, formatted                     |
| `publishedTime` | string                                   | Relative publish time (e.g. `1 month ago`) |
| `author`        | [Comment author](#comment-author-object) | Commenter                                  |

### Comment author object

| Field        | Type   | Description                  |
| ------------ | ------ | ---------------------------- |
| `id`         | string | Author's channel ID          |
| `name`       | string | Author's display name/handle |
| `thumbnails` | string | Author's avatar image URL    |

### Thumbnail object

| Field    | Type    | Description            |
| -------- | ------- | ---------------------- |
| `url`    | string  | Thumbnail image URL    |
| `width`  | integer | Image width in pixels  |
| `height` | integer | Image height in pixels |

***

## Errors

All non-2xx responses share the same envelope:

```json
{
  "status": 400,
  "message": "Bad request",
  "success": false,
  "error": { "code": "BAD_REQUEST" }
}
```

| Status | Meaning                                                                                                          |
| ------ | ---------------------------------------------------------------------------------------------------------------- |
| `400`  | Bad request — missing/invalid parameters, or more than one of `id`/`handle`/`channelUrl` supplied to Get Channel |
| `402`  | Insufficient credits                                                                                             |
| `404`  | Channel, video, short, or comment thread not found                                                               |

## Channel, Video, and Short IDs

* **Channel ID**: the `UC...` string in a channel URL, e.g. `https://www.youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA` → `UCX6OQ3DkcsbYNE6H8uQQuVA`. Pass it as the `id` path/query parameter depending on the endpoint.
* **Handle**: the `@name` shown on a channel's page, e.g. `https://www.youtube.com/@MrBeast` → `@MrBeast`.
* **Video/Short ID**: the 11-character `v=` value in a watch URL or the trailing path segment of a shorts URL, e.g. `https://www.youtube.com/watch?v=dQw4w9WgXcQ` → `dQw4w9WgXcQ`. The same ID format is used for both regular videos and shorts — use `/youtube/video` or `/youtube/shorts/{id}` depending on which you're looking up.

## Pagination Notes

* `GET /youtube/channel`, `GET /youtube/video`, `GET /youtube/shorts/{id}`, and `GET /youtube/trending` are single-object or fixed-size lookups and have no pagination parameters.
* All list endpoints (channel videos, channel shorts, channel live streams, comments, search, hashtag) use cursor-based pagination: pass the `cursor` value from `pagination.cursor` in a response to fetch the next page, or use `maxItems` instead to pull a bulk batch in one call. The two are mutually exclusive.
