How it will work: 3 steps
- Follow us on ApifyThe tool is built and waits in the queue for the Apify Store. Apify is the cloud platform where our tools run.
- Paste your input and press StartNo code needed: you fill in a form (the input). It already has a working example. For example:
@apifyin Channels. Each start is one run. - Download the resultsWhen the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.
This tool is an Apify Actor: a small program that runs on Apify. You can also run it on a schedule, for example every Monday. New to it? Read how it works, step by step and the 8 words you need first.
What it does
YouTube Channel Videos Export gets all videos of one or more YouTube channels: title, publish date, duration, views, likes, comments, tags and a Shorts flag. You paste channel links, @handles or channel IDs and add your own free YouTube Data API v3 key. You get one clean table row per video, newest uploads first.
- Finds the channel with the YouTube Data API (
channels.list) and reads its name, @handle, subscribers and video count. - Reads the channel's public uploads list, 50 videos at a time, newest first (
playlistItems.list). - Reads the full data of those videos, 50 at a time (
videos.list), and saves one row per video. - Marks each video as a Short or not with the channel's own Shorts list.
- Accepts
https://www.youtube.com/@handle,/channel/UC…,/user/nameand/c/namelinks, plain@handlesandUC…channel IDs. Up to 100 channels per run. - The same channel given twice is exported once.
- A channel that does not exist gets a free
not_foundrow with your original line. A video link or a non-YouTube link also gets anot_foundrow that says why. nullmeans "no value from YouTube" (for example, hidden likes). It is never written as0.
Good for
- You need all videos of a channel, or its last N videos, in a table with real numbers.
- You compare several channels: what they post, how often, and which videos work.
- You want an official, stable data source with a clear quota, not a scraper that can break.
Not a good fit
- You have no API key and do not want one. This Actor does not work without a key.
- You need comments, transcripts or search results. See Related Actors.
- You need private, unlisted or members-only videos. The Actor sees only public uploads.
- You need view history from the past. YouTube only gives the current numbers.
Who uses it
Creators
Find which of your videos get the most views and likes.
Sponsors
Check a channel's upload habits and video stats before a deal.
Researchers
Build a table of a channel's videos for study.
Price
Prices will be shown after release.
Questions
Do I need a YouTube API key?
Yes. You make a free key in a Google project. The Actor does not log in to YouTube.
How many videos can I export?
Up to 100 channels and 20,000 videos per channel per run.
How does it find Shorts?
It reads the channel's own Shorts list. If it cannot, isShort is null.
What if my daily quota runs out?
The Actor keeps the saved rows and stops. Run the rest after the quota resets.
Do I need a YouTube or Google account?
You need a Google account to make the free API key. The Actor does not log in to YouTube and does not use cookies.
Does it cost Google money?
No. The YouTube Data API is free within the daily quota. You pay only the Apify price above.
How do you know which videos are Shorts?
YouTube keeps a list of Shorts for each channel. The Actor reads that list for the same time range. This list is not a documented Google feature; if it cannot be read, isShort is null, not false.
Can I export live streams?
Yes. liveStatus says live, upcoming or was_live. For a live or upcoming stream durationSec is null; a finished stream has its real length.
Is personal data included?
Only public channel and video data that YouTube shows on the channel page. No viewer data and no comments.
Details
Step by step on Apify
- Get a key (see above).
- Open the Input tab. Channels already has
@apify, and Max videos per channel is 10. - Paste your key into YouTube Data API key.
- Click Start. 10 videos take a few seconds.
- Open the Videos view of the dataset, or download it as CSV, Excel or JSON.
Use cases
| Task | Input | Key fields | Next step |
|---|---|---|---|
| Audit a competitor channel | the channel, maxVideos 1,000+ | publishedAt, views, durationSec, isShort | Find posting rhythm and top formats |
| Compare creators before a deal | several channels, publishedAfter 90 days | views, likes, comments, engagementRate | Rank creators by recent engagement |
| Weekly report on your own channel | your channel, publishedAfter 7 days | title, views, likes, fetchedAt | Send to a sheet or dashboard |
| Shorts vs long videos | channel, includeShorts on | isShort, views, durationSec | Compare average views by format |
| Tag and topic research | channels in a niche | tags, categoryId, defaultLanguage | Find common tags and languages |
Tips for better results
- Sort by views in a spreadsheet to find top videos.
- Use the Shorts flag to split Shorts from long videos.
- Raise the run timeout when you export several large channels.
Limits and good to know
Data comes from the YouTube Data API v3 under your own key and Google project. Please follow the YouTube API Services Terms of Service. This Actor is not affiliated with or endorsed by YouTube or Google.
- Up to 100 channels and up to 20,000 videos per channel per run. With the default 300-second timeout and 256 MB memory, 8,000 videos of one channel took about 1 minute. An earlier full test of 20,000 videos finished in about 3 minutes
- For several large channels in one run, raise the run timeout. The Actor stops 15 seconds before the timeout, keeps all saved rows and ends as
PARTIALwith reasonTIMEOUT. The run still SUCCEEDED - If your daily quota runs out during a run, the Actor keeps the rows it saved, adds a free
quota_exceededrow, ends asPARTIALwith reasonQUOTA_LIMIT, and the run SUCCEEDED. Run the rest after the quota resets - If Google fails for 3 channels in a row, the run keeps saved rows and stops with reason
SOURCE_ERROR - Rows come in the order of the channel's uploads list: newest uploads first. A video uploaded early but published later by schedule can appear a little out of date order
- Private, deleted and members-only videos in the uploads list are skipped and are not charged. The run summary counts them
- Numbers are live at
fetchedAtand change all the time. YouTube roundschannelSubscribers
For developers
Sample result
One result from a real test run, in JSON. Real values change from run to run. In Excel or CSV each field is a column.
{
"status": "ok",
"inputChannel": "@apify",
"channelId": "UCTgwcoeGGKmZ3zzCXN2qo_A",
"channelTitle": "Apify",
"channelHandle": "@apify",
"channelUrl": "https://www.youtube.com/channel/UCTgwcoeGGKmZ3zzCXN2qo_A",
"channelSubscribers": 35200,
"channelVideoCount": 300,
"videoId": "e6My6S_QFJk",
"url": "https://www.youtube.com/watch?v=e6My6S_QFJk",
"title": "I Built a LinkedIn Lead Scraper with Claude Code + Apify",
"description": "See how you can turn LinkedIn post engagement into a ranked …",
"publishedAt": "2026-10-21T17:00:26Z",
"durationSec": 302,
"isShort": false,
"liveStatus": "none",
"views": 176,
"likes": 3,
"comments": 0,
"engagementRate": 0.017045,
"tags": ["web scraping platform", "web automation", "Apify"],
"categoryId": "28",
"defaultLanguage": "en",
"defaultAudioLanguage": "en",
"definition": "hd",
"hasCaptions": false,
"madeForKids": false,
"thumbnailUrl": "https://i.ytimg.com/vi/e6My6S_QFJk/maxresdefault.jpg",
"message": null,
"source": "youtube-data-api-v3",
"fetchedAt": "2026-10-22T05:23:02.678Z"
}Data fields (31)
| Field | Type | Meaning |
|---|---|---|
status | string | ok = a video. Other values are free explaining rows: no_videos, not_found, error, api_key_required, api_key_rejected, quota_exceeded (see message). |
inputChannel | string | The channel value exactly as you entered it. |
channelId | string | YouTube channel ID (UC…). |
channelTitle | string | Channel name. |
channelHandle | string | Channel @handle, when the channel has one. |
channelUrl | string | https://www.youtube.com/channel/UC… link. |
channelSubscribers | integer | Subscriber count as YouTube shows it (rounded by YouTube); null when the channel hides it. |
channelVideoCount | integer | Public video count of the channel as reported by the API. |
videoId | string | YouTube video ID. |
url | string | Video link: /watch?v= for videos, /shorts/ for Shorts. |
title | string | Video title. |
description | string | Full video description. |
publishedAt | string | Publish time, ISO 8601 UTC. |
durationSec | integer | Duration in seconds; null for live and upcoming streams. |
isShort | boolean | true when the video is in the channel's Shorts list. |
liveStatus | string | none, live (streaming now), upcoming (scheduled) or was_live (a past live stream or premiere). |
views | integer | View count at fetch time. |
likes | integer | Like count; null when the owner hides likes. |
comments | integer | Comment count; null when comments are off. |
engagementRate | number | (likes + comments) / views, e.g. 0.0425 = 4.25%; null without views. |
tags | array | Creator tags of the video (empty list when none). |
categoryId | string | YouTube category ID, e.g. 28 = Science & Technology. |
defaultLanguage | string | Language of title and description, when set. |
defaultAudioLanguage | string | Audio language, when set. |
definition | string | hd or sd. |
hasCaptions | boolean | true when the video has creator-uploaded captions. |
madeForKids | boolean | Made for kids flag. |
thumbnailUrl | string | Largest available thumbnail. |
message | string | Explanation for rows that are not videos. |
source | string | youtube-data-api-v3 |
fetchedAt | string | When this row was fetched, ISO 8601 UTC. |
Input settings (5)
The main fields of the input form. With the API you send them as JSON.
| Setting | Name in the API | Type | Example value |
|---|---|---|---|
| Channels required | channels | array | ["@apify"] |
| YouTube Data API key | apiKey | string | |
| Max videos per channel | maxVideos | integer | 10 |
| Published after | publishedAfter | string | |
| Include Shorts | includeShorts | boolean | true |