YouTube Video Scraper — Views, Likes, Tags & Captions
Pricing
from $4.00 / 1,000 video scrapeds
YouTube Video Scraper — Views, Likes, Tags & Captions
Scrape YouTube video data from video URLs: title, channel, duration, upload date, view, like and comment counts, tags, thumbnail and description, plus caption text in your languages. Export JSON, CSV or Excel. No login and no video download. $0.005 per video or less, captions included.
Pricing
from $4.00 / 1,000 video scrapeds
Rating
0.0
(0)
Developer
Sergey Andronik
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
13 hours ago
Last modified
Categories
Share
Scrape YouTube video data from video URLs into clean JSON. For each public YouTube video, YouTube Video Scraper returns the title, channel, duration, upload date, view, like and comment counts, tags, categories, thumbnail and description, plus the caption text and timed caption lines in the languages you choose. The video itself is never downloaded and no AI is run, so a video costs $0.005 or less, captions included. Use the output for spreadsheets, dashboards, search indexes, research or LLM prompts. No YouTube login, cookies or API key are needed.
What YouTube data you get
| Field | Content |
|---|---|
url, video_id | The URL you submitted and YouTube's video ID. |
title, description | The video title and description. |
author_username, author_name, author_id, author_url | The channel. |
author_follower_count, author_is_verified | The channel's subscriber count (as YouTube rounds it) and verified badge. |
published_at, upload_date | Publish time and date. |
released_at | Start time of a live stream or premiere. Only for those. |
duration_s, is_live | Length in seconds, and whether the video is a live stream. |
live_status, was_live, media_type | not_live, is_live, is_upcoming, was_live or post_live; whether it was ever live; video, short or livestream. |
availability, age_limit, playable_in_embed, license | Public or unlisted, minimum viewer age, whether it can be embedded, and its license when it has one (for example Creative Commons). |
webpage_url | The canonical watch URL, whichever form you submitted. |
width, height, fps, resolution | Of the best video stream. |
hashtags | The #hashtags written in the description. |
video_chapters | The creator's chapters, [{ "title", "start_s", "end_s" }]. Only when the video has them. |
available_caption_languages | The caption tracks YouTube lists in the video's own languages, [{ "language", "kind", "name" }], whether or not you asked for captions. YouTube's machine translations are not listed; the list stops at 100 entries. |
view_count, like_count, comment_count | Counts as YouTube shows them. |
tags, categories, language | Tags, YouTube categories and the video's language. |
thumbnail_url | Thumbnail link. |
captions_available, caption_language, caption_kind | Whether a caption track in your languages was found, which one, and whether it is manual (creator) or auto (YouTube-generated). |
caption_text, caption_segments | The caption text, and the caption lines with start and end seconds. |
billing | Whether this row was charged. |
The Dataset has two views: Videos (title, channel, date, duration, counts and caption status) and Captions text.
How to scrape YouTube videos
- Paste your video URLs. Watch links,
youtu.belinks, Shorts, live replays and embed links work, up to 1,000 per run. For a whole channel or playlist, usechannelUrlsinstead. - Choose captions. Keep Include captions on and list your languages in order,
for example
["en", "es"]. Turn it off if you only need the video data. - Set a run budget in the run options if you want a hard cap on the spend.
- Start the run and open the Dataset. One row per URL. Export it as JSON, CSV or Excel, or read it through the API.
Input
{"urls": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"],"includeCaptions": true,"captionLanguages": ["en"]}
| Field | What it does |
|---|---|
urls | Up to 1,000 public YouTube video URLs. Required unless you set datasetId. |
datasetId | Read URLs from another run's dataset. See Chain from another Actor. |
datasetUrlField, maxItems | The dataset field that holds the URL (detected when empty), and how many rows to read (default 100, at most 1,000). |
includeCaptions | Add the caption text and timed lines. Default true. |
captionLanguages | Up to 10 language codes in priority order. Default ["en"]. The first language with a caption track is returned; creator captions are preferred over auto-generated ones. |
Start from a channel or playlist
Put channel or playlist URLs in YouTube channels and playlists (channelUrls) to scrape their newest videos:
{"channelUrls": ["https://www.youtube.com/@TED/videos"],"maxItemsPerSource": 50,"includeCaptions": false}
- Channel URLs:
/@handle,/channel/UC…,/c/…and/user/…, optionally with a/videos,/shortsor/streamstab. Without one, Channel tab (channelTab, defaultvideos) decides. Playlist URLs:/playlist?list=…, in playlist order. - Each row adds
source_url,source_type(youtube_channeloryoutube_playlist) andsource_title. publishedAfter(YYYY-MM-DD) is approximate on YouTube: channel and playlist pages show only a relative age such as "3 weeks ago", so videos up to one such unit older can be included. Shorts have no date at all, sopublishedAftercannot be combined with the Shorts tab.publishedAfterfilters only the entries that were listed. A channel tab lists newest first,maxItemsPerSourcedeep, so it finds every recent video. A playlist keeps its creator's order, which can be oldest first; withpublishedAfterit is listed up to 200 entries deep, and the firstmaxItemsPerSourceentries on or after the date are kept. Newer videos further down a longer playlist are not found.- The listing request goes from Apify's servers directly to YouTube, not through the residential proxy that video data uses.
- Every listed video gets the full per-video data, as for a URL you submit.
maxItemsPerSource(default 20, at most 200) limits how many of the newest items each source contributes. A run holds at most 1,000 items in total, countingurlsand dataset rows.- Each listed item is processed and charged exactly like a URL you submit. Listing itself is free.
- The example link in the URL list is processed and charged too: remove it when you want only listed items.
- Listed items run after
urlsand dataset rows, source by source in input order; an item already in the run is skipped. - A source that cannot be listed becomes one error row with
source_urland anerrornaming it (for examplechannelUrls[1]: …), and it is not charged. The other sources continue. If no source lists anything, the run fails before any charge. - The listing is saved when the run starts, so a restarted run keeps the same items even if the source changed meanwhile.
Scheduled runs: only new items
Turn on Skip items processed by earlier runs (skipPreviouslyProcessed) and run the
Actor on a schedule to get only what is new
since the last run.
- The Actor keeps a key-value store named
polyglot-processed-youtube-scraperin your Apify account, orpolyglot-processed-youtube-scraper--<memoryKey>when you set Memory name (memoryKey), so separate schedules can keep separate memories. Other Actors keep their own stores, even with the samememoryKey. It records each item after the item is delivered and charged; failed items are tried again next time. - It applies to every URL in the run: listed ones, dataset rows and the items listed from sources.
- When nothing is new, the run ends without any charge. Only error rows appear then, for sources or dataset rows that could not be used.
- If the store cannot be opened or read, the run stops before any charge, and the next scheduled run tries again. If an item's record cannot be written, the item is still delivered and the log says so; a later run may process and charge it again.
- Delete the store in Apify Console (Storage → Key-value stores) to start over. Do not run two runs with the same memory at the same time: both would process the same new items.
Chain from another Actor
Run another run that lists YouTube videos first, then paste the dataset ID of that run into Dataset ID
(datasetId) to get data and captions for every one of its YouTube videos:
{ "datasetId": "<dataset ID from the other run>", "maxItems": 200 }
- The Actor reads up to
maxItemsrows (default 100) with your own run's Apify token and takes each row's URL fromwebVideoUrl,url,postUrl,videoUrl,inputUrlorlink, or from the field you name indatasetUrlField. - Dataset URLs run after any
urlsyou list, in dataset order; a dataset URL that is already in the run is skipped. A run takes at most 1,000 URLs in total. - A row without a usable URL becomes an error item with its
dataset_rowindex, and it is not charged. Items from the dataset also carrydataset_row, so you can join the results back to the source rows. - The example link in the URL list is processed and charged too: remove it when you want only the dataset's items.
Output example
An illustrative result for "Me at the zoo": the counts and channel come from an Apify run on 2026-10-30, and the captions from the video's real English caption track. It is not one recorded run; the description and the later caption lines are left out.
{"url": "https://www.youtube.com/watch?v=jNQXAC9IVRw","video_id": "jNQXAC9IVRw","title": "Me at the zoo","author_username": "jawed","author_name": "jawed","author_url": "https://www.youtube.com/@jawed","upload_date": "2005-04-24","duration_s": 19,"view_count": 447196495,"like_count": 20119541,"thumbnail_url": "https://i.ytimg.com/vi_webp/jNQXAC9IVRw/maxresdefault.webp","captions_available": true,"caption_language": "en","caption_kind": "manual","caption_text": "All right, so here we are, in front of the elephants the cool thing about these guys is that they have really... really really long trunks and that's cool (baaaaaaaaaaahhh!!) and that's pretty much all there is to say","caption_segments": [{ "t0": 1.2, "t1": 3.36, "text": "All right, so here we are, in front of the elephants" },{ "t0": 5.318, "t1": 7.974, "text": "the cool thing about these guys is that they have really..." }],"billing": {"status": "paid","events": [{ "event": "video-scraped", "requested_count": 1, "charged_count": 1, "state": "confirmed" }]}}
- A field is left out when YouTube does not show it for that video.
- A video without a caption track in your languages still returns its data, with
captions_available: false, and is charged as usual. - A video whose listed caption track cannot be fetched returns a row with
urlanderror, and is not charged. - The
author_*fields have the same names in our TikTok and Instagram scrapers.
How YouTube data is fetched
- On Apify, the video's metadata and its caption track are requested through Apify's residential proxy, with a traffic limit for each video. That cost is included in the per-video price.
- The Actor uses no YouTube login and no cookies.
- When YouTube blocks a request, returns incomplete video data, or the video is unavailable, the row returns an error and is not charged.
- Captions up to 5 hours. With Include captions on, a video longer than 5 hours returns an error and is not charged. Turn captions off to get its video data.
How much does it cost to scrape YouTube videos?
Pay per event, with no subscription. The Pricing tab shows the current prices.
| Event | Price | When |
|---|---|---|
| Run setup | $0.002 | Once per run. |
| Video scraped | $0.004–$0.005, by discount tier | Per video whose data was returned, with or without captions. |
| Apify Store discount tier | Video scraped |
|---|---|
| Free | $0.005 |
| Bronze | $0.005 |
| Silver | $0.0045 |
| Gold and above | $0.004 |
| Videos in one run | Cost |
|---|---|
| 1 | $0.002 + $0.005 = $0.007 |
| 100 | $0.002 + 100 × $0.005 = $0.502 |
| 1,000 | $0.002 + 1,000 × $0.005 = $5.002 |
Costs above use the Free and Bronze price. At Gold, 1,000 videos cost $4.002.
Video length does not change the price, and captions cost nothing extra. URLs that fail or are rejected are not charged the per-video fee. Apify's own small run-start event is separate and is shown on the Pricing tab.
Use it from the API
Start a run with the Apify API client for JavaScript and read the results:
import { ApifyClient } from 'apify-client'const client = new ApifyClient({ token: process.env.APIFY_TOKEN })const run = await client.actor('andronixmd/youtube-scraper').call({ urls: ['https://www.youtube.com/watch?v=jNQXAC9IVRw'], captionLanguages: ['en'] },{ maxTotalChargeUsd: 0.1 },)const { items } = await client.dataset(run.defaultDatasetId).listItems()for (const item of items) console.log(item.url, item.error ?? item.view_count)
Or start one run over HTTP:
curl -X POST \-H "Authorization: Bearer $APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"urls":["https://www.youtube.com/watch?v=jNQXAC9IVRw"]}' \'https://api.apify.com/v2/actors/andronixmd~youtube-scraper/runs?maxTotalChargeUsd=0.1'
The Actor also works from n8n and other automation tools through Apify's integrations. Schedule a run with the same URLs to track how the counts change over time.
Use it from an AI agent (MCP)
Connect your agent to https://mcp.apify.com. It can find this Actor with search-actors, or
call it by name, andronixmd/youtube-scraper, with call-actor. Use fetch-actor-details first for the
input schema and pricing. Every call starts a new paid run, so always set
callOptions.maxTotalChargeUsd and keep the urls list short:
{ "actor": "andronixmd/youtube-scraper", "input": { "urls": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"], "includeCaptions": true, "captionLanguages": ["en"] }, "callOptions": { "maxTotalChargeUsd": 0.1 } }
call-actor returns the run status and storage IDs, not the results. Read the rows with
get-dataset-items and the run's dataset ID. The fields to use are title, view_count, like_count and error.
With an Apify account, use your API token or MCP OAuth. Without one, an agent can buy a prepaid token from Apify AGI over x402 or MPP and use it as the Bearer token. It starts at $1, the balance is a hard spending cap, and the token expires after 14 days. This is experimental; see agentic payments.
Limitations
- Public videos only. Private, members-only, age-restricted and region-blocked videos, and anything that needs a login, are not supported.
- Videos, channels and playlists. Search URLs are not accepted. One URL in a wrong format rejects the whole input before the run starts. Channel listing from Apify's servers has not been tested at scale; a channel that cannot be listed becomes an error row that is not charged.
- Not every video works. YouTube can block requests or serve incomplete data, so
some URLs return an error row. Check each row's
errorfield and retry failed URLs in a later run. - Restarted runs. If a run is restarted or resurrected, the remaining videos fail without a charge; start a new run for them. A run that Apify moves to another server continues normally. After 20 videos in a row fail without a charge, the run stops requesting YouTube data and the rest fail the same way.
- Data and captions only. No comment text, channel statistics or video and audio files, and no transcript for videos without captions: for those, use YouTube Transcript.
FAQ
Where do the captions come from, and are they accurate?
They are YouTube's own caption tracks, as published. Creator captions are usually
accurate; auto-generated ones can contain errors, and caption_kind tells you which you
got. For videos without captions, or for speaker labels, use
YouTube Transcript, which adds AI
speech-to-text.
Which caption languages can I get? Any language the video has a caption track in. List up to 10 codes in priority order; the first available one is returned.
Are the numbers live? They are what YouTube shows at the moment of the run. Run it again later for new numbers.
Does it scrape channels, playlists, comments or search results?
Channels and playlists, yes: put them in channelUrls, and each listed video is scraped
in full. Comments and search results, no.
Where is my data kept? In your Apify run storage, under your account's access and retention settings. Use the data in line with YouTube's terms and the law that applies to you.
Related Actors
- YouTube Transcript: transcripts from captions, with AI speech-to-text for videos without them, plus SRT, VTT and speaker labels.
- TikTok Video Scraper and Instagram Reel Scraper: the same kind of data for TikTok and Instagram Reels.
- Audio & Video Transcriber: transcripts of podcasts, audio and video files and other sites.