YouTube Channel Scraper avatar

YouTube Channel Scraper

Pricing

$0.50 / 1,000 videos

Go to Apify Store
YouTube Channel Scraper

YouTube Channel Scraper

Export a YouTube channel's long-form videos to JSON by URL, @handle, or channel ID. No YouTube Data API key or quota. One record per video with views, date, duration, and thumbnail. Pay-per-video: a channel that can't be resolved returns a success:false row and is not charged.

Pricing

$0.50 / 1,000 videos

Rating

0.0

(0)

Developer

apihq

apihq

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Export a public YouTube channel's long-form videos as clean JSON, from a channel URL, @handle, or channel ID. No YouTube Data API key, no quota, no browser.

The contract is simple: a bad channel never fails your run, and you only pay for videos delivered. Misspell a handle, paste a video URL by mistake, or hit a channel with no uploads, and it comes back as a success: false row while the rest of the batch keeps going. Pay-per-result at $0.50 per 1,000 videos. Failed channels cost $0.

See one run

Input:

{ "channelUrls": ["@MrBeast", "@totally-wrong-handle"], "maxResults": 5 }

What comes back:

  • 5 success: true video rows from @MrBeast, billed
  • 1 success: false row, code: CHANNEL_NOT_FOUND, for the bad handle, not billed
  • Run status: SUCCEEDED
  • Charged: 5 videos = $0.0025

That is the whole contract. Good input returns billed rows, bad input returns free error rows in the same dataset, and the run still succeeds so one typo never costs you a batch.

Why this Actor

  • A bad channel never breaks the batch. Every channel that cannot be resolved or listed returns a success: false record with a machine-readable code (CHANNEL_NOT_FOUND, NO_VIDEOS, VALIDATION_FAILED, RESOLVE_TIMEOUT, CHANNEL_VIDEOS_TIMEOUT, DEADLINE_EXCEEDED). Branch on code without parsing English.
  • You pay only for videos. Billing fires on an explicit per-video event, not on dataset writes, so failure rows sit in your dataset for free.
  • No YouTube Data API key, no quota. The official YouTube Data API needs a Google key and rations a daily quota per call. This reads public data directly, so there is no Google key to provision and no daily Data API quota to ration. (You still run it with your normal Apify account, like any Actor.)

Best for

Data and AI workflows that turn channels into video datasets: creator databases, competitor monitoring, content-enrichment pipelines, and collecting video IDs to feed transcript or comment jobs. The failure-free billing and machine-readable error rows matter most when the extraction runs unattended inside a larger pipeline, where one bad channel should never take down the batch. It works fine for one-off manual pulls too.

Input example

A single channel:

{
"channelUrl": "https://www.youtube.com/@MrBeast",
"maxResults": 50
}

A batch, mixing URL, @handle, and channel ID forms:

{
"channelUrls": [
"https://www.youtube.com/@MrBeast",
"@mkbhd",
"UCX6OQ3DkcsbYNE6H8uQQuVA"
],
"maxResults": 100
}

channelUrl and channelUrls are merged and de-duplicated. Up to 50 unique channels run per job. Each channel is walked newest-first up to maxResults videos (default 50).

Output example

One record per video. The channel's id and name are copied onto every row so each row stands alone:

{
"success": true,
"channel_id": "UCX6OQ3DkcsbYNE6H8uQQuVA",
"channel_title": "MrBeast",
"video_id": "iYlODtkyw_I",
"title": "Spend 30 Days Handcuffed To A Stranger",
"url": "https://www.youtube.com/watch?v=iYlODtkyw_I",
"published": "2 weeks ago",
"view_count": "55M views",
"duration": 2105,
"thumbnail_url": "https://i.ytimg.com/vi/iYlODtkyw_I/hqdefault.jpg",
"author": "MrBeast"
}

A channel that cannot be resolved lands in the same dataset and is not charged:

{
"success": false,
"channel_url": "@totally-wrong-handle",
"code": "CHANNEL_NOT_FOUND",
"error": "Could not resolve YouTube channel: @totally-wrong-handle",
"request_id": "req_911f37d2e55644ff9d9e4a3f",
"status_code": 404
}

Split hits from misses on the success field. Quote request_id in any support issue and we can trace the exact request.

What you get

Every video is one record with success: true:

FieldTypeWhat it is
successbooleantrue for a video (billed), false for a channel that could not be listed (not billed).
channel_idstringThe UC... channel ID the video belongs to.
channel_titlestringThe channel's display name.
video_idstringThe 11-character YouTube video ID.
titlestringVideo title.
urlstringCanonical watch URL.
publishedstringRelative publish string YouTube shows (for example 2 weeks ago).
view_countstringView count as a display string.
durationintegerVideo length in seconds. Absent for live streams and unparseable lengths.
thumbnail_urlstringURL of the largest available thumbnail.
authorstringChannel author name.

Channels that could not be listed carry success: false, channel_url, a machine-readable code, a human-readable error, the service request_id, and the HTTP status_code. They are not charged.

Pricing

Pay-per-result. One charge per video delivered: $0.0005 each, which is $0.50 per 1,000 videos. The charge fires only after a video row lands in your dataset.

  • 1,000 delivered videos cost $0.50.
  • A run that hits ten dead handles and returns zero videos costs $0.

Apify subscriber discounts apply automatically: roughly $0.40 per 1,000 on the Scale plan and $0.30 per 1,000 on Business. Platform compute is included in the per-video price. Cap the maximum spend of a single run from Apify's Run Limits panel; the Actor honors the cap and stops cleanly mid-walk when the budget runs out.

What this Actor does not do

Honest scope, so you know before you run it:

  • It reads the channel's Videos tab (long-form uploads), not Shorts. That keeps output focused on regular videos and avoids mixing formats. For Shorts, use a Shorts-specific Actor.
  • It returns videos newest first. There is no sort by popularity or oldest.
  • It returns channel identity (id and name), not channel statistics. Subscriber totals, lifetime views, and channel-level counts are out of scope.

How to use this Actor

  1. Open the Actor in the Apify Console.
  2. Set channelUrl (single), channelUrls (a list), or both. Each accepts a full channel URL, an @handle, or a UC... channel ID. Up to 50 unique channels run per job.
  3. Set maxResults to cap how many videos to return per channel, newest first. Default is 50.
  4. Click Start. Each video is one success: true record. Channels that cannot be listed produce one success: false record and do not stop the run. Only videos are charged.

The Actor is also callable from the Apify API and every official integration (Make, Zapier, n8n, Slack, webhooks). The API tab in the Console has ready-to-paste JavaScript, Python, and curl snippets.

Reliability

A bad channel never fails the batch. A misspelled handle, a video URL pasted by mistake, or a channel with no uploads becomes a success: false record with a specific code. The run keeps going and finishes successfully.

You never pay for a failure. Billing fires on an explicit per-video charge event, not on dataset writes, so success: false records are free.

Hard 30-second deadline per page request. Each page of a channel is fetched under a 30-second deadline. If YouTube or the proxy network stalls, that channel returns a 504 with code: DEADLINE_EXCEEDED as a success: false record instead of hanging your run.

FAQ

Do I need a YouTube Data API key?

No. The Actor reads YouTube's public data directly and does not consume Google API quota.

What channel formats are accepted?

A full channel URL (https://www.youtube.com/@MrBeast or .../channel/UC...), an @handle, or a bare UC... channel ID. A video URL or unrecognizable input comes back as a success: false record with code: VALIDATION_FAILED, not a rejected run.

How many videos do I get per channel?

Up to maxResults, newest first. The Actor walks the channel's Videos tab page by page until it reaches maxResults or the channel runs out. Set maxResults higher to go deeper.

Does this include Shorts?

No. This Actor lists a channel's long-form videos. For Shorts, use a Shorts-specific Actor.

Can I get transcripts too?

Not from this Actor. Use it to collect a channel's video IDs, then run the YouTube Transcript Scraper on those IDs to pull captions.

Can I use this Actor from my own code?

Yes. Use the Apify API or one of the official SDKs (Node.js: apify-client, Python: apify-client). The Console shows ready-to-paste code samples on the API tab.

How does billing know a channel failed?

Billing fires on an explicit per-video charge event, not on dataset writes. The Actor only fires it when a video is delivered, so success: false records sit in your dataset for free. You get every result in one place and still branch on success and code, with a request_id for support correlation.

Found a bug or want a feature?

Open an issue on this Actor's Issues tab and include the request_id from any error record you saw. We respond within one business day.