YouTube Channel Scraper — Latest Videos via RSS (No API Key) avatar

YouTube Channel Scraper — Latest Videos via RSS (No API Key)

Pricing

from $0.70 / 1,000 result items

Go to Apify Store
YouTube Channel Scraper — Latest Videos via RSS (No API Key)

YouTube Channel Scraper — Latest Videos via RSS (No API Key)

Latest videos of any YouTube channel or playlist without API key or quota: official RSS (15 latest, exact dates/views) or the public Videos/Shorts tab (~30/48 latest). Keyword, date and view filters, channel stats (subscribers, total views), per-video details (duration, likes, category).

Pricing

from $0.70 / 1,000 result items

Rating

0.0

(0)

Developer

Samat Makatov

Samat Makatov

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

5 days ago

Last modified

Share

Monitor any YouTube channel or playlist without the Data API, quota, browser or proxy. Reads the official RSS feed (15 latest videos with exact timestamps, view counts and descriptions) or the public Videos / Shorts tab (~30 / ~48 latest), optionally enriched with channel stats (subscribers, total views, country, links) and per-video details (duration, likes, category, keywords — paused, see Limits). Give a @handle, any channel URL, a UC… id or a PL… playlist id.

Use cases

  • Competitor / creator monitoring — daily run with maxAgeDays: 1 over 50 channels; alert on new uploads that match includeKeywords.
  • Channel benchmarking — includeChannelStats: true to compare subscribers, total views and video counts of the channels you follow.
  • Content research — source: "videos", sort: "mostViewed" to see which recent topics perform for each channel.
  • Shorts trend tracking — source: "shorts" for the latest 48 Shorts with view counts.
  • Sponsorship due diligence — includeVideoDetails for exact duration, likes and category of the last N videos (paused since late 09/2026: YouTube shows its anti-bot check on video pages — see Limits).
  • Playlist sync — feed a course or podcast playlist (PL…) into your CMS / vector DB whenever a new episode appears.

Input

FieldTypeDefaultNotes
channelsstring[]—@handle, youtube.com/@x, /channel/UC…, /c/Name, /user/Name, UC… id, PL…/UU… playlist id or playlist URL. Links work with or without https://; a video link (watch?v=…, youtu.be/…, /shorts/…) is read as "the channel of that video".
sourceselectrssrss (15 latest, exact data), videos (~30 latest uploads, approx. dates & rounded views, durations), shorts (~48 latest Shorts). Playlists always use RSS.
limitPerChannelint15Max videos kept per entry (1–100; the source caps apply).
includeKeywordsstring[]—Keep videos whose title/description contains any (case-insensitive).
excludeKeywordsstring[]—Drop videos containing any.
sinceDatedate—Keep videos published on/after this date.
maxAgeDaysint—Keep videos newer than N days (good for scheduled runs).
minViewsint—Drop videos below this view count.
sortselectnewestnewest, mostViewed, feed. Applied before limitPerChannel.
includeChannelStatsboolfalseFetch the About page: subscribers, video count, total views, country, joined, description, links, avatar. Emits one type: "channel" row per channel + channel* columns on videos.
includeVideoDetailsboolfalsePaused (see Limits). Fetch each video page: durationSec, likeCount, category, keywords, exact views, isLive. A page YouTube does not serve leaves detailsFetched: false and the reason in detailsError.
maxDetailsPerChannelint5Budget for includeVideoDetails (0–50).
descriptionLengthint1000Truncate RSS descriptions (0 = drop).
maxItemsint1000Hard cap on dataset rows across all channels (channel-stats rows count too).
dedupebooltrueSkip a videoId already emitted by an earlier entry. An entry listed twice is read once.
fieldsstring[]— (all)Keep only these columns, in this order. type, channelId and videoId are always kept and come first unless you place them. Case and spaces do not matter (channel title = channelTitle); an unknown name is skipped and named in the status. A row that would keep none of your columns (e.g. a channel row when you list only video columns) is not written.

Reference

What each source gives you

Fieldrssvideos tabshorts tab+ includeVideoDetails (paused)
items≤ 15≈ 30≈ 48—
publishedAt (exact ISO)yesno (publishedAtApprox from "3 days ago" / "3d ago")noyes (publishDate)
viewsexactrounded ("572K")roundedexact
descriptionyes (truncated)nonono
durationSecnoyesnoyes
rating / ratingCountyesnonolikeCount
category, keywords, isLivenononoyes

Accepted channel references

InputExample
Handle@Fireship, Fireship
Channel URLhttps://www.youtube.com/@Fireship/videos, youtube.com/@Fireship (no scheme), m.youtube.com/@Fireship, /channel/UCsBjURrPoezykLs9EqgamOA, /c/Fireship, /user/GoogleDevelopers
Channel idUCsBjURrPoezykLs9EqgamOA
PlaylistPLrAXtmErZgOeiKm4sgNOknGvNjby9efdf, https://www.youtube.com/playlist?list=PL…, uploads playlist UU…
Video linkhttps://www.youtube.com/watch?v=…, youtu.be/…, /shorts/…, /live/… → the channel that published the video (the run log and SUMMARY.notes say which one).

Examples

Daily "what's new" across a watchlist

{ "channels": ["@Fireship", "@aiDotEngineer", "@lexfridman"], "maxAgeDays": 1 }

Channel stats next to the latest uploads

{ "channels": ["@Fireship", "@ThePrimeagen", "@t3dotgg"], "includeChannelStats": true, "limitPerChannel": 3 }

Only the columns you need

{ "channels": ["@Fireship"], "fields": ["title", "views", "publishedAt", "url"] }

Top-performing recent videos per channel

{ "channels": ["@Fireship"], "source": "videos", "sort": "mostViewed", "limitPerChannel": 10 }

Keyword watch: reviews mentioning a product

{ "channels": ["@mkbhd", "@UnboxTherapy"], "includeKeywords": ["iPhone", "Pixel"], "excludeKeywords": ["#shorts"], "maxAgeDays": 30 }

Latest Shorts

{ "channels": ["@Fireship"], "source": "shorts", "limitPerChannel": 20 }

Output

Video row (RSS + details, when YouTube serves the video page):

{
"type": "video",
"input": "https://www.youtube.com/@Fireship",
"kind": "channel",
"source": "rss",
"playlistId": null,
"channelId": "UCsBjURrPoezykLs9EqgamOA",
"channelTitle": "Fireship",
"channelUrl": "https://www.youtube.com/channel/UCsBjURrPoezykLs9EqgamOA",
"channelHandle": "@Fireship",
"channelSubscribers": 4270000,
"channelVideoCount": 841,
"channelTotalViews": 744056340,
"channelCountry": null,
"videoId": "FluKUJyeYD8",
"title": "Did OpenAI actually build AGI? GPT-6 Astra first look",
"url": "https://www.youtube.com/watch?v=FluKUJyeYD8",
"publishedAt": "2026-09-04T20:14:12.000Z",
"publishedAtApprox": null,
"publishedText": null,
"updatedAt": "2026-09-11T22:17:40.000Z",
"description": "CodeRabbit Security protects your code…",
"thumbnail": "https://i3.ytimg.com/vi/FluKUJyeYD8/hqdefault.jpg",
"views": 3999521,
"viewsText": null,
"rating": 5,
"ratingCount": 45194,
"likeCount": 45194,
"durationSec": 446,
"durationText": null,
"isShort": false,
"isLive": false,
"category": "Science & Technology",
"keywords": ["webdev", "app development"],
"detailsFetched": true,
"detailsError": null,
"fetchedAt": "2026-09-12T23:41:12.086Z"
}
FieldDescription
typevideo or channel (stats row, only with includeChannelStats).
input, kind, sourceWhat you passed, channel/playlist, and which source produced the row.
channelId, channelTitle, channelUrl, channelHandleResolved channel identity.
channelSubscribers, channelVideoCount, channelTotalViews, channelCountryFrom About page (includeChannelStats), else null. channelCountry is null when the channel does not publish a country (common).
videoId, title, url, thumbnailVideo identity.
publishedAt / publishedAtApprox / publishedTextExact UTC ISO-8601 …Z (RSS/details) or approximate from relative text (tabs). updatedAt (RSS) is UTC too.
views, viewsText, rating, ratingCount, likeCountEngagement.
durationSec, durationText, isShort, isLive, category, keywordsFrom tab / details.
descriptionRSS description, truncated to descriptionLength.
detailsFetched, detailsErrortrue when the watch page was read (includeVideoDetails). false with a reason when YouTube did not serve the video's data (age restriction, members-only, its anti-bot check) or the run skipped it (after an anti-bot check, near the timeout); false with null beyond maxDetailsPerChannel or without includeVideoDetails.

Every video row has all these columns (null where the source has no value).

Channel row (type: "channel") adds channelDescription, channelJoined, channelAvatar, channelKeywords, channelLinks[], channelIsFamilySafe and the raw subscribersText / videoCountText / totalViewsText. Key-value record SUMMARY: { rows, videos, channelRows, channels, entriesRead, entriesNotRead, source, details, statsErrors[], blockedBy, requests, notes[], errors[], delivered, stoppedBy, status } — rows = videos + channel rows (what is billed), details = { requested, fetched, failed, skipped, errors[] }, notes records inputs we interpreted (a video link resolved to its channel, a corrected fields name, a repeated entry).

Use it from code / agents

curl -X POST "https://api.apify.com/v2/acts/yadroo~youtube-channel-feed/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H 'Content-Type: application/json' -d '{"channels":["@Fireship"],"maxAgeDays":7}'
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('yadroo/youtube-channel-feed').call({ channels: ['@aiDotEngineer'], includeChannelStats: true });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("yadroo/youtube-channel-feed").call(run_input={"channels": ["@Fireship"], "source": "videos", "sort": "mostViewed"})
items = client.dataset(run["defaultDatasetId"]).list_items().items

MCP: connect https://mcp.apify.com and call the yadroo/youtube-channel-feed tool with the same JSON.

Pricing

Pay per event: $0.001 per run start + $0.001 per row (a video or a channel-stats row). Bronze −10 %, Silver −20 %, Gold and above −30 % on the row price; the start event is the same on every plan; platform usage is included. Typical: 10 channels × 15 videos = 150 rows ≈ $0.15; a daily maxAgeDays: 1 watchlist usually yields a handful of rows, under $0.01.

Your maximum cost per run is respected: the run stops at the last row it pays for, ends with "Stopped at your spending limit: N rows delivered", and fetches no video details for rows it cannot deliver.

Limits & FAQ

  • Only 15 videos? That is YouTube's RSS cap. Use source: "videos" (~30) or "shorts" (~48); for full back-catalogues use a full YouTube scraper.
  • Approximate dates and rounded views on tabs. The Videos/Shorts tabs only show relative dates ("3 days ago", in YouTube's compact layout "3d ago") and rounded counts ("572K", "2.5M"); publishedAtApprox and views are computed from those and both tab layouts are read. source: "rss" gives exact dates and view counts for the 15 latest videos; includeVideoDetails would give them per video but is paused (below).
  • Per-video details are paused. Since at least 27.09.2026 YouTube answers video pages requested from Apify's cloud with its "Sign in to confirm you're not a bot" check (every test run of 02.10.2026). The actor does not try to get around it: after the first check it requests no more video pages, the rows still come from RSS / the tabs with detailsFetched: false and the reason in detailsError, and the status says so. Feeds, tabs and channel About pages are not affected.
  • How much fits in one run. One request at a time, every request at least 0.6 s after the previous one — the channel-page lookup, the About page and the feed of one entry included: up to 4 s per @handle channel from RSS (less for UC… ids, which need no page lookup), up to 6 s with includeChannelStats (About page), plus about 2 s per video page when YouTube serves them. The default run timeout (900 s) fits roughly 190 RSS channels or 120 channels with stats (measured 07.10.2026: 50 channels, 144 rows, under 4 minutes). Near the timeout the run stops starting new channels, saves what it has read and ends with "Stopped before the run timeout: N rows saved" — raise the timeout or split the channel list.
  • Rate limits / blocks. Up to 5 polite retries on 429/5xx, waiting as long as YouTube's Retry-After asks and otherwise 5 s, 10 s, 20 s, 40 s — a short burst of "too many requests" from Apify's shared cloud IPs is waited out instead of ending the run. If YouTube still keeps answering 429, refuses with 403, redirects to its "unusual traffic" page, or shows its "confirm you're not a bot" check, the run does not try to get around it (no proxies, no other clients): it stops sending that kind of request, keeps the rows it has, and says what it met plus "start the run again in 15–30 minutes, or with fewer channels per run" in the status (SUMMARY.blockedBy). A check on video pages only stops the details (rows get detailsError); on feeds, channel pages or About pages the run stops reading channels.
  • Private / deleted / renamed. 404 → clear error for that entry in SUMMARY.errors; the run continues with the others and fails only if every entry it read failed. A feed or About page that answers with something else than the expected data is an error too (never an empty or null-filled success); a failed About page is listed in SUMMARY.statsErrors and gives no channel row.
  • Anything that is not a YouTube address (another site, a typo'd handle) is reported per entry with what to pass instead — it never falls back to a different channel.
  • Members-only / age-restricted videos get detailsFetched: false with YouTube's reason in detailsError.
  • Roadmap. Comments count, transcript availability flag, uploads-playlist paging for older videos.

Made by Yadroo · Sibling actors: google-news-search · rss-to-json · hackernews-search · crypto-news