# YouTube API — search (with filters) videos, channels, playlists and shorts; get video details, comments (top/newest), related videos, channel info and About panel, playlist and channel-uploads listings, and video transcripts/captions

> search videos/channels/playlists/shorts with filters (upload date, duration, sort order, features)
> ReefAPI engine `youtube` · 11 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/youtube/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed or blocked calls are free.
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /youtube/v1/search — 1 credit
search videos/channels/playlists/shorts with filters (upload date, duration, sort order, features)

**Parameters:**
- `query` (string, optional) — Search keywords. Provide `query` for a new search, or `continuation` for the next page.
- `type` (enum, optional, default "all") — Restrict results to one result kind. [one of: all, video, channel, playlist, movie, shorts]
- `upload_date` (enum, optional) — Filter by how recently the video was uploaded. [one of: hour, today, week, month, year]
- `duration` (enum, optional) — Filter by video length. [one of: short, medium, long]
- `sort_by` (enum, optional, default "relevance") — Order the results. [one of: relevance, date, views, rating]
- `features` (string, optional) — Comma-separated feature filters: live, 4k, hd, subtitles/cc, creative_commons, 360, hdr, location, purchased, 3d.
- `limit` (integer, optional, default 20) — How many items to return (1-200). Paged internally; clamped to range.
- `continuation` (string, optional) — Next-page token from a previous response's `continuation` (provide this instead of the primary id to fetch the next page).

**Returns:** results[] (type-tagged: video/shorts/channel/playlist rows), count, estimated_results, continuation (next-page token), query, type

**Example request body:**
```json
{
  "query": "lofi hip hop",
  "type": "video",
  "limit": 20
}
```

### POST /youtube/v1/video_detail — 1 credit
video metadata: title/views/likes/date/channel/description (+ duration/keywords/thumbnails/caption-langs best-effort)

**Parameters:**
- `video_id` (string, required) — YouTube video id (11 chars) or any watch/youtu.be/shorts/embed URL.

**Returns:** video record: title, views, likes, published_date, channel{name,channel_id,subscribers}, description, +length_seconds/keywords/thumbnails/available_captions

**Example request body:**
```json
{
  "video_id": "dQw4w9WgXcQ"
}
```

### POST /youtube/v1/video_details — 1 credit
BATCH engagement enrichment — pass up to 50 video_ids in ONE call, get likes + description (+ optional comment_count) per video. Built to enrich channel_videos/channel_shorts lists (which don't carry likes) without one call per video.

**Parameters:**
- `video_ids` (array, optional) — Up to 50 video ids or watch URLs to enrich in one batch.
- `include_comment_count` (boolean, optional, default false) — Also fetch total comment_count per video (1 extra call/video → higher cost+latency). Default off (likes + description only).

**Returns:** videos[]{video_id, title, views, likes, published_date, description, channel_id, channel_name, comment_count?} + count + requested + failed[]

### POST /youtube/v1/comments — 1 credit
video comments (text/author/likes/replies), paginated, sortable by top or newest

**Parameters:**
- `video_id` (string, optional) — YouTube video id (11 chars) or any watch/youtu.be/shorts/embed URL.
- `limit` (integer, optional, default 20) — How many items to return (1-200). Paged internally; clamped to range.
- `sort` (enum, optional, default "top") — Comment ordering (ignored when paging an existing `continuation`). [one of: top, newest]
- `continuation` (string, optional) — Next-page token from a previous response's `continuation` (provide this instead of the primary id to fetch the next page).

**Returns:** comments[]{text, author, likes, reply_count, published, is_reply}, count, continuation, sort, top_level_count

**Example request body:**
```json
{
  "video_id": "dQw4w9WgXcQ",
  "limit": 20
}
```

### POST /youtube/v1/channel — 1 credit
channel detail: subs/videoCount/description/links

**Parameters:**
- `channel_id` (string, required) — Channel id (UC…), an @handle, or a channel URL — any one resolves the channel.

**Returns:** channel record: title, channel_id, handle, subscribers, video_count, description, external_links[], avatar

**Example request body:**
```json
{
  "channel_id": "UCX6OQ3DkcsbYNE6H8uQQuVA"
}
```

### POST /youtube/v1/transcript — 1 credit
video transcript/captions (timed segments + full text) select any language the video has via 'lang'; format=text|segments

**Parameters:**
- `video_id` (string, required) — YouTube video id (11 chars) or any watch/youtu.be/shorts/embed URL.
- `lang` (string, optional, default "en") — Preferred caption language code (e.g. en, es, de). Falls back to an available track; see available_languages in the response.
- `format` (enum, optional, default "segments") — Output shape. 'text' omits the per-cue segments[] array. [one of: segments, text]

**Returns:** transcript: language, language_code, is_generated, segment_count, duration_ms, text, segments[]{start_ms,dur_ms,text}, available_languages[]

**Example request body:**
```json
{
  "video_id": "dQw4w9WgXcQ",
  "lang": "en"
}
```

### POST /youtube/v1/playlist — 1 credit
list a playlist's videos (id/title/channel/duration/position), paginated

**Parameters:**
- `playlist_id` (string, optional) — Playlist id (PL…/UU…/OLAK…), a full playlist URL (…?list=…), or a VL… browseId.
- `limit` (integer, optional, default 100) — How many items to return (1-200). Paged internally; clamped to range.
- `continuation` (string, optional) — Next-page token from a previous response's `continuation` (provide this instead of the primary id to fetch the next page).

**Returns:** items[]{video_id, title, channel, channel_id, duration, views, position, thumbnails, url}, count, continuation, playlist_id, playlist_title

**Example request body:**
```json
{
  "playlist_id": "PL15B1E77BB5708555",
  "limit": 20
}
```

### POST /youtube/v1/channel_videos — 2 credits
a channel's uploads (Videos tab): video_id/title/views/duration, paginated

**Parameters:**
- `channel_id` (string, required) — Channel id (UC…), an @handle, or a channel URL — any one resolves the channel.
- `limit` (integer, optional, default 30) — How many items to return (1-200). Paged internally; clamped to range.
- `continuation` (string, optional) — Next-page token from a previous response's `continuation` (provide this instead of the primary id to fetch the next page).

**Returns:** videos[]{video_id, title, channel, views, published, duration, thumbnails, url}, count, continuation, channel_id

**Example request body:**
```json
{
  "channel_id": "UCX6OQ3DkcsbYNE6H8uQQuVA",
  "limit": 20
}
```

### POST /youtube/v1/channel_shorts — 1 credit
a channel's Shorts tab (video_id/title/views/views_int/thumbnails), paginated — the Shorts that the Videos tab (channel_videos) omits; works for shorts-only channels

**Parameters:**
- `channel_id` (string, required) — Channel id (UC…), an @handle, or a channel URL — any one resolves the channel.
- `limit` (integer, optional, default 30) — How many items to return (1-200). Paged internally; clamped to range.
- `continuation` (string, optional) — Next-page token from a previous response's `continuation` (provide this instead of the primary id to fetch the next page).

**Returns:** shorts[]{video_id, title, views, views_int, thumbnails, url}, count, continuation, channel_id

**Example request body:**
```json
{
  "channel_id": "UCX6OQ3DkcsbYNE6H8uQQuVA",
  "limit": 20
}
```

### POST /youtube/v1/related — 1 credit
recommended/related videos for a video_id (from the watch page)

**Parameters:**
- `video_id` (string, required) — YouTube video id (11 chars) or any watch/youtu.be/shorts/embed URL.
- `limit` (integer, optional, default 20) — How many items to return (1-200). Paged internally; clamped to range.

**Returns:** related[]{video_id, title, channel, channel_id, views, published, duration, thumbnails, url}, count, video_id

**Example request body:**
```json
{
  "video_id": "dQw4w9WgXcQ",
  "limit": 15
}
```

### POST /youtube/v1/channel_about — 2 credits
full channel About panel: total views, joined date, country, links, description

**Parameters:**
- `channel_id` (string, required) — Channel id (UC…), an @handle, or a channel URL — any one resolves the channel.

**Returns:** channel_id, description, country, joined_date, view_count, video_count, subscribers, canonical_url, links[]{title, link}

**Example request body:**
```json
{
  "channel_id": "UCX6OQ3DkcsbYNE6H8uQQuVA"
}
```

## More
- Try it live, no code: https://reefapi.com/playground?engine=youtube
- Human docs page: https://reefapi.com/docs/youtube
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
