# YouTube channel videos

`POST https://api.endless.app/social/youtube_channel_videos`

Source: https://endless.app/docs/api/social/youtube-channel-videos

Get a channel's long-form uploads with view counts, length, and publish dates. Use when asked what a channel has posted or for its top/most-viewed videos (`sort_by:'popular'`). For a date range pass `since`: the listing cards are sparse, so each video is then fetched individually to get its date and counts — accurate, but one call per video, so keep the window tight. Pair `since` with `until` and the tool returns a `totals` block computed over exactly that window — quote it, never add up the rows yourself. Read `coverage` before reporting totals. For Shorts use `youtube_channel_shorts`.

## Authentication

- `bearerAuth`: HTTP bearer (JWT)

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Endless-Api-Version` | header | string | no | Pin the caller to an API major (`1`). Omit to accept the current version. A major this deployment cannot serve is refused with 400 `unsupported_api_version`. |

## Request body

Required.

Content type: `application/json` — object

- `organization_id` (string, required)
- `max_credits` (integer): Refuse the call when its quoted ceiling exceeds this many credits.
- `tool_call_id` (string | null): The tool call behind this read, for the ledger. Every read that runs is billed, a repeated id too.
- `conversation_id` (string (uuid) | null): The chat this call belongs to, for cost attribution.
- `message_id` (string (uuid) | null): The chat turn this call belongs to, for cost attribution.
- `input` (object, required)
  - `channel` (string, required): Channel handle (e.g. '@MrBeast' or 'MrBeast'), full channel URL, or channel id (UC…).
  - `sort_by` ("newest" | "popular" | "oldest"): 'newest' first, 'popular' for most-viewed, or 'oldest'.
  - `max_items` (integer): How many items to return (max 300; fetched ~48 per upstream page, so large values are slower).
  - `lang` (string): Original content language as an ISO-639 code (e.g. 'es', 'pt', 'fr'). Pass this when the channel/content is not in English so titles and descriptions come back in the original language instead of YouTube's English auto-translation. Omit for English content.
  - `since` (string): Page back until posts from this date (YYYY-MM-DD) are reached. Use this when the requested source content is bounded by publication date, instead of raising the item cap. For creative references or account voice, omit date filters unless the user limits the source period; a planning deadline does not limit when references were published. Never pass a far-past date to mean 'everything', and omit it when the user asks for no date filter: every page walked back costs credits.
  - `until` (string): End of the window (YYYY-MM-DD, inclusive). Pair with `since` to get exact `totals` for a date range instead of summing rows yourself.
  - `tz` (string): IANA timezone the date window is cut in (e.g. 'America/Argentina/Buenos_Aires'). Pass the user's timezone from the system prompt whenever you pass `since`/`until` — days cut in the wrong zone shift every piece published late in the evening into the next day. Defaults to UTC.
  - `with_comments` (boolean): Fetch each video's exact comment count. Off by default because it DOUBLES the requests (one extra call per video) — turn it on only when the answer needs comment totals or engagement including comments. Left off, comment counts come back absent, and totals report them as not measured rather than as zero.

## Responses

### 200 OK

Content type: `application/json` — object

- `operation` ("instagram_profile" | "instagram_user_posts" | "instagram_user_reels" | "instagram_user_stories" | "instagram_user_highlights" | "instagram_highlight_stories" | "instagram_post" | "instagram_post_comments" | "tiktok_profile" | "tiktok_user_posts" | "tiktok_post" | "tiktok_post_comments" | "tiktok_search" | "tiktok_hashtag_posts" | "tiktok_music_posts" | "tiktok_trending" | "tiktok_trend_scan" | "linkedin_profile" | "linkedin_company" | "linkedin_user_posts" | "linkedin_company_posts" | "linkedin_post" | "linkedin_search_people" | "linkedin_search_posts" | "youtube_channel" | "youtube_channel_videos" | "youtube_channel_playlists" | "youtube_channel_shorts" | "youtube_video" | "youtube_search" | "youtube_trending" | "facebook_page" | "facebook_page_posts" | "facebook_page_reels" | "facebook_post" | "facebook_post_comments" | "facebook_group" | "facebook_group_posts" | "facebook_search" | "reddit_search" | "reddit_subreddit_posts" | "reddit_post" | "reddit_post_comments" | "x_search" | "x_profile" | "x_user_posts" | "x_post" | "x_post_comments" | "x_user_connections" | "x_tweet_engagers" | "x_trends" | "resolve_mention", required): Operation name — see the operations catalog.
- `result` (object, required)
  - `summary` (string, required): One-line result, for the reader.
  - `channel` (string, required)
  - `count` (integer, required)
  - `totals` (object)
    - `window` (object, required)
    - `posts` (integer, required)
    - `views` (number, required)
    - `likes` (number, required)
    - `comments` (number, required)
    - `engagement_rate` (number | null, required)
    - `rows_without_views` (integer)
    - `rows_without_likes` (integer)
    - `rows_without_comments` (integer)
    - `views_metric` (string)
    - `measured_at` (string, required)
    - `partial` (true)
    - `overlaps` (string)
    - `oldest` (string)
    - `newest` (string)
  - `receipt` (string)
  - `coverage` (string)
  - `videos` (array<object>, required)
    - `id` (string)
    - `url` (string)
    - `title` (string)
    - `description` (string)
    - `channel` (object, required)
    - `published_at` (string)
    - `published_text` (string)
    - `length` (string)
    - `view_count` (number)
    - `view_count_text` (string)
    - `like_count` (number)
    - `comment_count` (number)
    - `thumbnail` (string)
- `requests` (integer, required)
- `credits_charged` (integer, required)

### Errors

- `400` (Error): The request is malformed, or failed input validation. `message` names the field and the rule it broke; `data.issues` carries them individually.
- `401` (Error): No bearer token, or a token that failed verification.
- `402` (Error): The workspace has no credits left, or the caller is over a spending limit.
- `403` (Error): Authenticated, but the caller's role in this workspace does not carry the permission this operation needs.
- `409` (Error): The request is well-formed, but the resource's current state forbids it — a taken name, a last admin, a limit already reached.
- `429` (Error): The caller has spent its rate-limit window. `Retry-After` says when to come back.
- `500` (Error): The request failed on our side. Safe to retry an idempotent operation with backoff.
