What it does
Most YouTube scrapers load youtube.com pages through proxies and break whenever the page layout or bot checks change. This actor takes a different route: it calls the official YouTube Data API v3 with an API key you create yourself in a free Google Cloud project. Nothing is scraped from youtube.com, and there are no proxies, cookies or logins involved.
The default videos mode accepts watch URLs, youtu.be links, Shorts, embed and live links or bare 11-character IDs, and returns one row per video: title, description, channel, published date, duration in seconds, view, like and comment counts, tags, category, default language, thumbnails, live status, made-for-kids flag and topic categories. IDs are batched 50 per API call, so one quota unit covers 50 videos. The same actor also switches to search, channel or comments mode through the mode field.
It suits analysts building YouTube dashboards, marketers doing competitor and trend research, and developers who want a stable feed into Sheets, Make, n8n or Zapier. Pricing is $0.40 per 1,000 video rows, and the free quota on one key covers about 500,000 video lookups a day. ActorForge is not affiliated with or endorsed by YouTube or Google.
How it works
- You paste your own YouTube Data API v3 key into the secret
apiKeyfield; Apify stores it encrypted and the actor never logs it or writes it to the output. - Video URLs and IDs are normalised, duplicates are removed, and the IDs are sent to
videos.listin batches of 50. - Each video comes back as a schema-validated row with stats, duration in seconds and an
isShortheuristic (3 minutes or less and not live). - Invalid, private, deleted or missing videos become free error rows instead of failing the run.
- If your key hits a
403 quotaExceedederror, the run stops cleanly, keeps the rows already delivered and does not charge for the failed call.
Input example
A typical run input (JSON). Every field is also available as a form in the Apify console.
{
"apiKey": "AIzaSy...your-own-key",
"mode": "videos",
"videoUrls": [
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"https://youtu.be/jNQXAC9IVRw",
"9bZkp7q19f0"
]
}All input fields
| Field | Type | Required | Default | What it does |
|---|---|---|---|---|
apiKey | string | no | Required. Your own free YouTube Data API v3 key (starts with AIza). Get one in about a minute: console.cloud.google.com → create a project → APIs & Services → Library → enable "YouTube Data API v3" → Credentials →… | |
mode | string | no | "videos" | videos: details and stats for video URLs/IDs (1 quota unit per 50 videos). search: YouTube search results, enriched with full video details (100 units per page of 50). channel: channel stats plus every upload (about 2… |
videoUrls | array | no | Videos for the videos and comments modes: watch URLs, youtu.be links, Shorts, embed or live URLs, or bare 11-character IDs. Duplicates are removed. videos.list takes 50 IDs per call. | |
searchQueries | array | no | [] | One or more search terms (search mode). Each page of up to 50 results costs 100 of your 10,000 daily quota units, so a full key's day is about 100 pages (5,000 results). |
maxResultsPerQuery | integer | no | 50 | Search results per query (search mode). YouTube returns at most about 500 per query. Each 50 = one search page (100 quota units). |
order | string | no | "relevance" | search.list order (search mode). |
searchType | string | no | "video" | video: video rows with full details. channel: channel rows with subscriber, video and view counts (search mode). |
publishedAfter | string | no | "" | Optional date (YYYY-MM-DD). In search mode, filters results; in channel mode, only uploads on or after it (and paging stops at older videos, saving quota). |
publishedBefore | string | no | "" | Optional date (YYYY-MM-DD) for search mode. |
regionCode | string | no | "" | Optional 2-letter country code (US, GB, DE …): search results available in that country (search mode). |
relevanceLanguage | string | no | "" | Optional ISO 639-1 language code (en, es, de …): results most relevant to that language (search mode). |
videoDuration | string | no | "any" | Filter search results by duration (search mode, videos only). short < 4 min, medium 4–20 min, long > 20 min. |
channels | array | no | [] | Channel URLs (youtube.com/@handle, /channel/UC…, /user/name), @handles or channel IDs (UC…), for channel mode. Each gives one channel row plus its uploads. |
maxVideosPerChannel | integer | no | 100 | Newest uploads per channel (channel mode). 0 = channel row only. Every 50 videos cost about 2 quota units. |
includeShorts | boolean | no | true | Channel mode. The API does not flag Shorts, so this uses a heuristic (3 minutes or less, not live): turning it off also drops regular videos that short. |
maxCommentsPerVideo | integer | no | 100 | Top-level comments per video (comments mode). Replies are not counted here; they are capped separately by Max replies per comment. 100 top-level comments per quota unit. |
includeReplies | boolean | no | false | Also return replies (comments mode), up to Max replies per comment per thread. Each reply is its own comment-result row, linked by parentId. |
maxRepliesPerComment | integer | no | 20 | With Include replies on: at most this many replies per top-level comment (comments mode), so one huge thread cannot eat the run. 0 = no replies. Up to 5 replies come free with the thread call; more cost 1 quota unit… |
commentOrder | string | no | "time" | time: newest first. relevance: YouTube's top comments. |
searchTerms | string | no | "" | Optional keyword filter applied by YouTube to the comments (comments mode). |
Output example
Each video URL or ID becomes one row with its title, channel, publish date, duration and engagement counts, as in these real examples:
| title | channelTitle | publishedAt | durationSec | viewCount | likeCount | commentCount | categoryId | isShort | searchQuery |
|---|---|---|---|---|---|---|---|---|---|
| Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster) | Rick Astley | 2009-10-25T06:57:33Z | 214 | 1828596530 | 19490833 | 2460128 | 10 | false | |
| Me at the zoo | jawed | 2005-04-24T03:31:52Z | 19 | 445426986 | 20095698 | 10642771 | 1 | true | |
| PSY - GANGNAM STYLE(강남스타일) M/V | officialpsy | 2012-07-15T07:46:32Z | 253 | 6098344051 | 32321298 | 5465487 | 10 | false | |
| Web Scraping with Python - Beautiful Soup Crash Course | freeCodeCamp.org | 2020-11-18T16:05:43Z | 4103 | 1827575 | 39425 | 1102 | 27 | false | web scraping tutorial |
Pricing
Pay per event: you are charged only for the results you receive, with no subscription. Set a maximum total charge on any run and it stops cleanly at the cap.
| Charged for | When | Price | Per 1,000 | Worked example |
|---|---|---|---|---|
| Video result | Charged per video row delivered (full details and stats) | $0.0004 | $0.40 | 1,000 videos = $0.40 (streamers/youtube-scraper: $4.00 per 1,000) |
| Channel result | Charged per channel row delivered (stats, country, uploads playlist) | $0.0005 | $0.50 | 100 channels = $0.05; their videos are video-result rows |
| Comment result | Charged per comment or reply row delivered (author fields stripped) | $0.0005 | $0.50 | 10,000 comments = $5.00 (streamers/youtube-comments-scraper: $20) |
| Search page | Charged per search page of up to 50 results that returned rows (search mode; it costs 100 of your quota units) | $0.002 | $2 | 50 search results = $0.002 + 50 × $0.0004 = $0.022 |
| Actor Start (platform start fee) | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). | $0.00005 | — | One run at 256 MB = $0.0000125 |
Prices are read from the live Apify Store listing when this page is built. The listing is always authoritative.
Try YouTube Scraper (Official API) on Apify. Pay only for the results you get.
Run on Apify →Use cases
Refresh stats for a video list
Keep a sheet of video IDs, from your own campaigns or a competitor's, and re-run on a schedule to pull current view, like and comment counts. At 50 IDs per quota unit, even large lists use very little of the daily free quota.
Enrich links collected elsewhere
If another tool or a CRM gives you a pile of YouTube links, pass them in as-is. Watch, youtu.be, Shorts, embed and live formats are all accepted, and each comes back with duration, tags, category and topic categories.
One client for every YouTube job
Switch mode to search, channel or comments when the task changes, using the same key and the same output conventions. Video rows are always $0.40 per 1,000 whichever mode produced them.
Analytics feeds without page scraping
Because the data comes from the official API, the run does not depend on youtube.com's HTML. That makes it a steadier source for dashboards and automations in Make, n8n or Zapier.
How it compares
| ActorForge YouTube Scraper | Typical no-key YouTube scrapers | Calling the YouTube API yourself | |
|---|---|---|---|
| Data source | Official YouTube Data API v3 | youtube.com pages via proxies | Official YouTube Data API v3 |
| Needs your own API key | Yes (free, no billing account) | No | Yes |
| Blocks and layout breakage | No page scraping | Possible | No page scraping |
| Batching, paging, quota-stop handling | Built in | Not applicable | You write it |
| Price per 1,000 video rows | $0.40 | Varies | Free (your quota only) |
| Dislikes, watch time, revenue | No | Varies | No (not in the public API) |
| Setup time | Paste key and links | Paste links | Write and maintain code |
If you already maintain your own API client, calling the YouTube Data API directly costs nothing beyond your quota and is the better choice. If you cannot or will not create a Google Cloud API key, a no-key scraper is the only option, at the cost of depending on youtube.com's pages.
Limits and honest notes
- You need your own free YouTube Data API v3 key (see the 4-step guide above). Without one the run stops at once with instructions, and nothing is charged.
- Quota is per Google Cloud project: 10,000 units/day for free. Unit costs: videos.list, channels.list, playlistItems.list, commentThreads.list and comments.list cost 1 unit each, and search.list costs 100. A
quotaExceedederror stops the run cleanly; rows already delivered are kept, and the failed call is free. - Only public data the API returns for an API key: no private or unlisted-by-ID-only details, no dislike counts (removed by YouTube), no revenue, no watch time, and no subscriber lists. Channels that hide their subscriber count give
subscriberCount: null. - Like counts that the creator hides come back as null. Counts are YouTube's own; subscriber counts are rounded by YouTube to 3 significant figures.
- Free rows (type error) cover invalid inputs, videos and channels that are not found, private or deleted, and videos with comments disabled.
- You must refresh or delete stored API data within 30 days (YouTube Developer Policies III.E.4). We keep nothing after the run.
- The run's spend limit is respected: each page of rows is charged before it is delivered, and the run stops cleanly at the cap.
- Search returns at most about 500 results per query (a YouTube limit), and results can differ from what youtube.com shows in a browser.
isShortis a heuristic (3 minutes or less and not live), because the API does not flag Shorts.
FAQ
Do I need my own YouTube API key to use this scraper?
Yes. There is no built-in or shared key. You create a free YouTube Data API v3 key in the Google Cloud Console in about a minute, with no billing account, and paste it into the apiKey field. Without a key the run stops immediately with instructions and nothing is charged.
How many YouTube videos can I look up per day on the free quota?
Each Google Cloud project gets 10,000 free quota units per day, reset at midnight Pacific Time. Video lookups cost 1 unit per 50 videos, which works out to about 500,000 video rows a day on one key.
Can it get YouTube dislike counts or watch time?
No. The public API does not return dislike counts (YouTube removed them), watch time, revenue or subscriber lists. Like counts that a creator hides come back as null.
How does it know if a video is a YouTube Short?
The API does not flag Shorts, so isShort is a heuristic: 3 minutes or less and not live. Treat it as a good guess rather than YouTube's own label.
What happens when my YouTube API quota runs out mid-run?
The actor stops cleanly on a 403 quotaExceeded error, keeps every row already delivered and does not charge for the failed call. It never retries against an exhausted quota, so you can simply run again after the daily reset.
Do I have to delete the YouTube data after some time?
YouTube's Developer Policies require stored API data to be refreshed or deleted at least every 30 days. ActorForge keeps no copy after the run, so set a retention period on your datasets or re-run to refresh them.
Use it from code
Run the actor through the Apify API with the input above.
cURL
curl -X POST "https://api.apify.com/v2/acts/actor-forge~youtube-api-scraper/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"apiKey": "AIzaSy...your-own-key", "mode": "videos", "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ", "https://youtu.be/jNQXAC9IVRw", "9bZkp7q19f0"]}'JavaScript (Node.js)
// Node.js 18+ (built-in fetch). Set APIFY_TOKEN in your environment.
const input = {
"apiKey": "AIzaSy...your-own-key",
"mode": "videos",
"videoUrls": [
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"https://youtu.be/jNQXAC9IVRw",
"9bZkp7q19f0"
]
};
const res = await fetch(
"https://api.apify.com/v2/acts/actor-forge~youtube-api-scraper/run-sync-get-dataset-items",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.APIFY_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify(input),
}
);
const items = await res.json();
console.log(items.length, items[0]);Python
# pip install apify-client (set APIFY_TOKEN in your environment)
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run_input = {
"apiKey": "AIzaSy...your-own-key",
"mode": "videos",
"videoUrls": [
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"https://youtu.be/jNQXAC9IVRw",
"9bZkp7q19f0"
]
}
run = client.actor("actor-forge/youtube-api-scraper").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)The run-sync-get-dataset-items endpoint waits for the run (up to 5 minutes) and returns the dataset rows directly. For longer runs, start the run asynchronously and read the dataset when it finishes, as the Python example does. Replace APIFY_TOKEN with your own token from the Apify console.
Step-by-step guides
How to Get YouTube Data With the Official API (Free Key, No Code)
Create a free YouTube Data API v3 key in Google Cloud (no billing account), paste it into an ActorForge YouTube actor, and get video, channel…
Related actors
YouTube Channel Scraper (Official API) — All Videos & Stats
Bring your own free YouTube API key. Get any channel's stats (subscribers, total views, video count, country) and every upload with views, likes…
$0.40 per 1,000 · video resultYouTube Search Scraper (Official API) — Videos by Keyword
Bring your own free YouTube API key. YouTube search by keyword with sort, date, region, language and length filters — every result enriched with…
$0.30 per 1,000 · video resultYouTube Comments Scraper (Official API) — No Usernames
Bring your own free YouTube API key. Export YouTube comments and replies (text, likes, reply count, dates) for any video via the official YouTube…
$0.50 per 1,000 · comment resultGoogle Trends Scraper — Trending Now & Interest Over Time
Google Trends scraper and API: Trending Now searches for 125 countries from the official feed (traffic, start time, picture, news articles), plus…
$0.50 per 1,000 · trend resultTry YouTube Scraper (Official API) on Apify. Pay only for the results you get.
Run on Apify →