YouTube Channel and Video List Scraper
Pricing
from $1.02 / 1,000 video rows
YouTube Channel and Video List Scraper
Scrape YouTube channels, playlists, and search results as flat rows, with no login. Video rows carry title, views, date, and length. Channel rows carry subscribers, total views, joined date, and links. Each source reports whether its list was read to the end.
Pricing
from $1.02 / 1,000 video rows
Rating
0.0
(0)
Developer
Mamba Labs
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 hours ago
Last modified
Categories
Features
Share
Give YouTube channels, playlists, or search terms, and get one row per video with title, rounded views, relative date, and length, one row per channel with subscribers, total views, joined date, and links, and a free report per source that says whether its list was read to the end. You pay per row; no YouTube account or key is needed.
Features
- Reads channel, playlist, and search lists past the first page, up to 5,000 videos a source. Tested to 350 on a playlist, 300 on a channel, and 200 on a search.
- Takes
youtube.comandyoutu.beaddresses, @handles, and channel IDs. - A channel row per channel source: subscribers, total views, video count, joined date, country, description, and published links.
- Videos, Shorts, or streams tab per channel.
- A free
source_reportrow per source, withrows_returned,list_complete,reached_row_cap, and for playlists the count the page declares.
How the data is read
The actor reads public YouTube pages, plus the next page requests those pages make, as a logged out US visitor on the Apify proxy default pool. It uses no login, no browser, no residential proxy, no YouTube API key, and no other developer's actor. A refused page is final: the actor does not retry it on a new address or another route. It waits 5 seconds, returns a free row, and ends the run after 3 refused reads in a row. Only a network error, where no answer came back, is tried once more.
Input
| Field | Type | Default | What it does |
|---|---|---|---|
urls | array | Channel, @handle, playlist, or search result addresses, or a bare channel ID or @handle. Up to 200 sources a run, counted with search terms. A single video address returns one free row: this actor does not open video pages. Clay users: wrap a column in a one item list. | |
search_terms | array | Terms to search on YouTube. Each term returns videos in YouTube's order, for a logged out US visitor. Clay users: wrap a column in a one item list. | |
max_videos_per_source | string | 30 | Per channel, playlist, or search term. Default 30, maximum 5000. Set 0 on a channel to get only its channel row. |
include_channel_row | string | yes | yes (default) adds one row per channel source with subscribers, total views, video count, joined date, country, and links. no skips it. |
channel_tab | string | videos | Which channel list to read: videos (default), shorts, or streams. |
max_charge_usd | string | Optional. The run stops before a charge that would pass this amount. Reports are always delivered. |
Output
| Field | Type | What it holds |
|---|---|---|
row_type | string | One of: video, channel, source_report, run_summary. run_summary is the one free row written when the input is refused. |
source_input | string | The address or term that produced this row. |
source_type | string | video, channel, playlist, search, or invalid. |
video_id | string | video: the 11 character YouTube ID. |
video_url | string | video: the watch address. |
title | string | video: the title. |
channel_name | string | The channel's display name. |
channel_id | string | The UC channel ID, when the page shows it. |
channel_handle | string | The @handle when the page shows it. |
channel_url | string | channel: the channel address. |
view_count | integer | video: views, rounded the way YouTube shows them on a list page. |
published_text | string | video: YouTube's relative date. |
duration_seconds | integer | video: length. Empty on a live stream or a Short. |
duration_text | string | video: the length YouTube shows. |
description | string | channel: the description. |
keywords | array | channel: tags the owner set. An empty list if none. |
is_short | boolean | True on a row read from a channel's shorts tab; otherwise empty. |
is_family_safe | boolean | channel: YouTube's flag. |
thumbnail_url | string | The largest image the page lists. |
subscriber_count | integer | channel: rounded by YouTube. |
channel_video_count | integer | channel: total videos. |
channel_view_count | integer | channel: total views. |
joined_date | string | channel: YouTube's joined date text. |
country | string | channel: the country the owner set. Often empty. |
links | array | channel: links the owner published, each with title and url. |
rows_returned | integer | source_report: videos delivered for this source. |
list_complete | boolean | source_report: true when the list was read to its end. |
reached_row_cap | boolean | source_report: true when max_videos_per_source ended the list. |
declared_videos | integer | source_report: the count a playlist page declares. Hidden videos count here and never list, so it can exceed rows_returned on a complete list. |
row_status | string | ok, or why this row carries no data: no_results, no_change, partial, blocked, or error. |
error_reason | string | Why the row is not ok. A refused input reads input_invalid: followed by what to fix. |
billable_events_json | string | What this row was billed as, for example {"video-row":1}. {} means free. |
scraped_at | string | When the row was written, UTC. |
Pricing
Pay per event. Reports, refused pages, and a refused input are free. The run start is charged on every run through the apify-actor-start event, including a refused input.
| Event | Free plan | Bronze | Silver | Gold |
|---|---|---|---|---|
video-row, one video from a list: title, rounded views, relative date, and length | $0.0012 | $0.00114 | $0.00108 | $0.00102 |
channel-row, one channel | $0.001 | $0.00095 | $0.0009 | $0.00085 |
apify-actor-start, once per run (one per GB of memory; the default 256 MB is one) | $0.0025 | $0.0025 | $0.0025 | $0.0025 |
Per 1,000 rows of video-row: $1.20 on the free plan, $1.02 on Gold.
Free plan cap: 1.50 USD of evaluation a month, about 1250 rows. Any paid Apify plan removes the cap, and it resets on the 1st. The run stops before a charge that passes your maximum charge per run in Apify or your max_charge_usd input.
Mamba Labs pays the platform costs of your run, Apify proxy traffic included.
Usage examples
Last 50 videos of a channel. {"urls": ["@NASA"], "max_videos_per_source": "50"}
Channel rows only. {"urls": ["@NASA", "@veritasium"], "max_videos_per_source": "0"}
Search. {"search_terms": ["home espresso"], "max_videos_per_source": "40"}
Clay. Number and on or off inputs are text fields, which is what Clay sends. A list input takes a JSON list, so put the column inside a one item list.
MCP. The Mamba Labs MCP server @mambalabsdev/mcp-youtube-video-channel-scraper exposes this actor to Claude and other MCP clients.
Error handling
| Case | What you get |
|---|---|
| Missing or unreadable input | One free row, row_type run_summary, error_reason starting input_invalid: with what to fix. The run ends successfully and charges nothing but the run start |
| A single video address, or an address that is not YouTube | One free source_report row with row_status error |
| A channel that does not exist, or a search with no results | Free rows with row_status no_results |
| YouTube refuses a read | A free row with row_status blocked. After 3 refusals in a row the run stops and delivers what it has |
| The run is close to its timeout | The actor stops starting new work 90 seconds before the timeout and delivers what it has |
Limitations
- This actor does not open single video pages. In a test on 2026-11-06, YouTube answered 22 of 40 video page reads with "Sign in to confirm you're not a bot", and 8 of 20 videos changed answer between reads. So there are no likes, comment counts, exact views, full dates, video descriptions, tags, transcripts, or comments. A single video address returns a free row. If you need those fields, this actor is not the one.
- Views are rounded the way YouTube shows them on a list page, for example 1.2M, and dates are relative, for example 2 weeks ago.
- Shorts rows carry title, views, and thumbnail, with no date or length. The Shorts tab served one page in testing, so its report reads
list_completefalse. Shorts shelves in search results are left out. list_completetrue means YouTube offered no further page. On a search that is YouTube's own limit, not every matching video: one search ended at 53 rows. An empty next page reads false, with a note. A playlist's declared count includes hidden videos that never list.- Results are what a logged out US visitor sees, in English. They are not personalized, and search order can change between runs.
subscriber_countis rounded by YouTube.countryis empty when the owner set none. No email addresses are read.- List pages were not refused in testing (8 of 8 channel lists, 300 rows on one channel), but YouTube can change that at any time.
- YouTube's Terms of Service bar automated access without its written permission, and restrict collecting information that identifies a person, such as usernames. Its robots.txt disallows
/resultsand/youtubei/, which search and paging use. Check that your use fits them.
Changes
- 2026-11-08: renamed from YouTube Video and Channel Scraper to YouTube Channel and Video List Scraper, because it reads lists and channel pages, not single video pages. The slug is unchanged. A refused page is no longer retried on a new pool address.
Mamba Labs actor suite
Built by Mamba Labs.