Youtube Scraper Pro avatar

Youtube Scraper Pro

Pricing

from $2.00 / 1,000 video results

Go to Apify Store
Youtube Scraper Pro

Youtube Scraper Pro

Full‑fidelity YouTube data extractor for videos, Shorts, live streams, and channels. Built on Apify + Puppeteer for reliable, scalable web scraping that returns complete metadata, engagement stats, caption tracks for transcripts, hashtags/keywords, description links, and channel insights — fast.

Pricing

from $2.00 / 1,000 video results

Rating

0.0

(0)

Developer

Delowar Munna

Delowar Munna

Maintained by Community

Actor stats

2

Bookmarked

34

Total users

0

Monthly active users

2 days ago

Last modified

Share

YouTube Scraper Pro (Apify Actor)

Analytics-ready YouTube data for videos, Shorts, live streams, and channels. Built on the official YouTube Data API v3 with HTTP + Innertube fallbacks — no cookies, no login, no residential proxy required — returning engagement metrics, SEO signals, parsed description links, channel intelligence, and result provenance.

YouTube Scraper Pro banner

Transcripts: this actor can attach captions per video — enable includeTranscript to fill a subtitles array (SRT, VTT, plain text, or JSON — one or more). For standalone / bulk transcript jobs, our dedicated YouTube Transcript Scraper is purpose-built.


At a Glance

  • Official-API sourced: YouTube Data API v3 for core fields, with HTTP + Innertube fallbacks — no cookies, no logged-in session, no residential proxy
  • Scrape by keywords, channel handles (e.g. @mkbhd), channel IDs, playlists, or direct video URLs
  • Returns: title, description, duration, publish date, views, likes, comment count, category, media flags (HD/4K/HDR), hashtags, keywords, parsed description links, monetization status, and rich channel data
  • Provenance on every row: which query produced it, its order, and when it was collected — unique to this actor
  • Spreadsheet-friendly: flat camelCase keys plus a nested channel object; import straight into Google Sheets, Excel, or a database
  • Spend control: cap the whole run with maxItems

Best for: content research, SEO, competitive intelligence, trend analysis, brand monitoring, influencer discovery, and analytics-ready ETL feeds.


How it works

Each video is resolved through a tiered pipeline; every tier only handles what the previous one could not, so most videos never touch a browser:

TierRoleCost
HTTP extractionFetches raw HTML + parses embedded JSON (ytInitialData, ytInitialPlayerResponse)~1s/video, no browser
YouTube Data API v3Batch core fields (views, likes, duration, category, keywords)1 quota unit per 50 videos
Innertube/youtubei/v1/player fallback when HTTP is soft-blockedno browser
TikHubHosted-API fallback for videos the above could not resolve (e.g. datacenter-IP blocks)paid, only when needed
Puppeteer (browser)Last-resort DOM extraction; skipped entirely when nothing is leftrare

No residential proxy is required for normal use. The actor works reliably from datacenter IPs; the TikHub tier absorbs the cases where a raw HTTP fetch is blocked.


Key Features

  • API-first discovery (fast): keyword & #hashtag search via TikHub; channel / playlist / seed-video expansion via the YouTube Data API v3 — no browser for discovery. A browser is only a rare last-resort for videos no API tier can resolve.
  • One discovery field: keywords, #hashtags, channels (URL / @handle / UC…), playlists (URL / PL…), or a seed video (expands to its owning channel). Plus a separate direct-video field.
  • Content coverage: standard videos, Shorts (duration-detected), live/live-replay — filter with contentType
  • Filters & sorting: contentType, videoDuration, titleFilter, uploadDate/date range, and sortBy (relevance / newest / most-viewed), applied to discovered results
  • Localization: 37 countries (regionCode) and 20 languages (language)
  • SEO signals: hashtags, keywords/tags, parsed outbound description links
  • Channel intelligence: id, name, handle, URL, numeric subscriber count, totals, country, profile image, join date, description
  • Monetization detection: isMonetized (+ commentsAllowed, isRatingsAllowed) when reachable
  • Detected language: detectedLanguage (API hint + trigram detection)
  • Optional subtitles: includeTranscript fills a subtitles array (SRT/VTT/txt/JSON, one or more, each + a key-value-store file link) via TikHub captions (off by default; billed only when delivered)
  • Result provenance: source, order, collectedAt on every record
  • Spend cap: maxItems bounds the total results saved across the whole run

Quick Start (Apify)

  1. Create an Actor task and paste one of the JSON inputs below.
  2. Set maxItems if you want to cap total spend for the run.
  3. Run. Export JSON/CSV/Excel to your datastore, Google Sheets, or S3.

Input Schema

The input form is organized into four collapsible sections:

  • 1. What to scrape — the combined discovery field, direct video URLs/IDs, and result limits
  • 2. Filters & Sorting — content type, duration, title filter, sort, dates, trending
  • 3. Advanced — localization and output format
  • 4. Transcript — optional caption extraction

Input Parameters

#FieldKeyTypeRequiredDefaultDescription
1Search, Channels, Playlists & DiscoverysearchQueriesArrayNo[]Discovery sources, auto-detected: a keyword, a #hashtag, a channel (URL / @handle / /channel/UC… / /c/… / /user/… / bare UC…), a playlist (URL or bare PL…/UU…), or a video (URL/ID — treated as a seed: its owning channel is scraped). Each source capped by maxResultsPerQuery
2YouTube URLs or IDsstartUrlsArrayNo[]Direct videos — one record per entry, for that video only (no expansion, exempt from filters). Full URLs (watch?v=…, youtu.be/…, /shorts/…) or bare 11-char IDs. Non-video entries are skipped
3Max videos per sourcemaxResultsPerQueryintegerNo10Caps each discovery source (keyword/hashtag/channel/playlist/seed) individually. Min 1. Doesn't apply to YouTube URLs/IDs (one video each)
4Max results (whole run)maxItemsintegerNo0Global spend cap — total results saved across the run, applied after filter + sort. 0 = no global limit
5Content typecontentTypestringNo"all"all / videos / shorts / live. Shorts detected by duration (≤ 60s); live from broadcast status. Discovered results only
6DurationvideoDurationstringNo"all"all / short (<4m) / medium (4–20m) / long (>20m). Discovered results only
7Sort results bysortBystringNo"relevance"relevance (discovery order) / date (newest) / views (most viewed). Sorts the discovered set before the cap
8Upload date filteruploadDatestringNo"any"any / hour / today / week / month / year. Applies to all discovered sources
9Title filtertitleFilterstringNo""Comma-separated keywords; keep results whose title contains at least one (OR, case-insensitive)
10Include trending videosgetTrendingbooleanNofalseAlso add the Country's trending videos as a source (official Data API; requires an API key)
11From DatedateFromstringNo""Publish-date lower bound (YYYY-MM-DD). Applies to all discovered sources
12To DatedateTostringNo""Publish-date upper bound (YYYY-MM-DD). Applies to all discovered sources
13CountryregionCodestringNo"US"ISO-3166-1 alpha-2. 37 options (US, GB, DE, IN, JP, KR, ID, BR, NG, …)
14LanguagelanguagestringNo"en"IETF BCP-47. 20 options (en, es, de, ja, ko, hi, id, ar, …)
15Output formatoutputModestringNo"rich"rich (nested JSON) or analyticsFlat (nested objects flattened into channel_name, features_isHD, … and arrays joined — spreadsheet-friendly)
16Include TranscriptincludeTranscriptbooleanNofalseFill the subtitles array via TikHub captions. Adds ~1–2s/video; ~60–80% of videos have captions. Billed per delivered subtitle
17Subtitle formatssubtitleFormatsArrayNo["srt"]Multi-select: any of srt, vtt (timestamped), txt (plain text), json ({start,dur,text} segments). Each selected format is added to the subtitles entry
18Transcript LanguagetranscriptLanguagestringNo""Preferred caption language; empty = auto (first available). Only used when Include Transcript is on

Filters apply to discovered results only — videos listed directly in YouTube URLs or IDs are always returned as-is (exempt from contentType/videoDuration/titleFilter/date).

Keyword & hashtag search requires a TikHub key; channel/playlist/seed expansion and metadata require the YouTube API key. Both are set as Apify secrets.

Tip: start with a small maxResultsPerQuery (and/or a maxItems) to validate your setup, then scale up.

Input Example — 01: Search with date filtering and a spend cap

{
"searchQueries": ["AI tools", "machine learning", "#openai"],
"maxResultsPerQuery": 20,
"maxItems": 50,
"contentType": "videos",
"sortBy": "views",
"uploadDate": "month",
"videoDuration": "medium",
"regionCode": "US",
"language": "en"
}

Input Example — 02: Direct video URLs and IDs

{
"startUrls": [
"https://www.youtube.com/watch?v=7Sx0o-41r2k",
"https://youtu.be/5oAnKSCP4do",
"QJBP2uy8LcU"
]
}

Input Example — 03: Channels, playlists, and a seed video (all in Discovery)

{
"searchQueries": [
"@MKBHD",
"UCXuqSBlHAE6Xw-yeJA0Tunw",
"https://www.youtube.com/playlist?list=PLBCF2DAC6FFB574DE",
"https://www.youtube.com/watch?v=dQw4w9WgXcQ"
],
"contentType": "all",
"maxResultsPerQuery": 25,
"regionCode": "US",
"language": "en"
}

The last entry is a video URL — in the Discovery field it's a seed: the channel that owns it is scraped for up to maxResultsPerQuery videos. The same value in the YouTube URLs or IDs field would instead return only that one video.

Input Example — 04: With subtitles

{
"searchQueries": ["langchain tutorial"],
"maxResultsPerQuery": 10,
"includeTranscript": true,
"subtitleFormats": ["srt", "json"],
"transcriptLanguage": "en"
}

What you pay

This actor uses Apify's pay-per-event pricing. The live rates are shown on the Pricing tab of the actor page — this README deliberately does not quote figures, because the amounts are set on the platform and can change.

You are charged for:

EventFires whenNotes
ResultA video record is saved to the datasetThe main charge. One per video returned.
Discovery (search)A discovery source (keyword, hashtag, channel, playlist, or seed video) returns at least one resultA discovery that returns zero results is not charged. Direct video URLs never incur a discovery charge — you pay only for the result.
TranscriptA transcript is actually delivered for a videoOnly when includeTranscript is on and captions exist. Videos without captions are not charged.

Controlling spend:

  • Set maxItems to cap the total number of results (and therefore the total result charges) for the whole run.
  • Use maxResultsPerQuery to cap each individual source.
  • Leave includeTranscript off unless you need spoken text — it adds a per-delivered-transcript charge.
  • Error/unavailable rows (see Errors & limitations) are not billed as normal results.

For worked cost examples at the current rates, see the Pricing tab on the actor page.


Output Schema

Each record has 35 top-level fields. Legacy keys (VideoId, PageURL, publishDate) are retained alongside their normalized aliases (id, url, publishedAt) for backward compatibility. Set outputMode: "analyticsFlat" to flatten nested objects into top-level columns for spreadsheets.

Core fields

#FieldTypeDescription
1typeStringOne of video, shorts, live, stream
2isShortBooleanConvenience mirror of type === "shorts"
3VideoIdStringYouTube video ID (legacy key)
4idStringYouTube video ID (camelCase alias of VideoId)
5PageURLStringCanonical watch URL (legacy key)
6urlStringCanonical watch URL (camelCase alias of PageURL)
7titleStringVideo title
8thumbnailUrlString | nullPrimary/hero thumbnail URL
9publishDateString | nullPublish date (date, or ISO if a time is known)
10publishedAtString (ISO-8601) | nullFull timestamp when a real time is known; null when only a date is available (never fabricated)
11durationString | nullHH:MM:SS (e.g. 00:22:43)
12durationSecondsInteger | nullDuration in seconds
13viewCountInteger | nullTotal views
14likeCountInteger | nullTotal likes
15commentCountInteger | nullPublic comment count
16categoryString | nullVideo category

State flags

#FieldTypeDescription
17isLiveBooleanWhether the item is/was a live stream
18isMembersOnlyBooleanMembers-only gated flag
19isPrivateBooleanPrivate/unavailable to public
20isFamilySafeBoolean | nullFamily-safe flag if exposed
21isMonetizedBoolean | nullMonetization detectable flag
22isRatingsAllowedBoolean | nullWhether likes/dislikes are enabled
23commentsAllowedBoolean | nullWhether comments are enabled

Content & media

#FieldTypeDescription
24descriptionString | nullCreator-written description
25descriptionLinksArrayOutbound links parsed from the description ({url, text})
26subtitlesArrayCaptions — empty [] unless includeTranscript is on and captions exist. See shape below
27keywordsArrayTags/keywords
28hashtagsArrayHashtags from title/description
29featuresObjectMedia flags: isHD, is4K, isHDR, isVR180, is360 (each Boolean | null)

subtitles entry: one object per caption track, carrying type, language, and — for each selected subtitleFormats — an inline <fmt> value plus a <fmt>Url link to the file in the run's key-value store (signed URL on the platform). <fmt> is srt/vtt/txt (String) or json (Array of {start, dur, text} in seconds). type is auto_generated (the TikHub captions list does not distinguish auto vs manual, so this is best-effort). Example with subtitleFormats: ["srt","json"]:

"subtitles": [
{
"type": "auto_generated", "language": "en",
"srtUrl": "https://api.apify.com/v2/key-value-stores/<id>/records/subtitles_<vid>_en_auto_generated.srt?signature=…",
"srt": "1\n00:00:01,360 --> 00:00:03,040\n[♪♪♪]\n\n2\n…",
"jsonUrl": "https://api.apify.com/v2/key-value-stores/<id>/records/subtitles_<vid>_en_auto_generated.json?signature=…",
"json": [ { "start": 1.36, "dur": 1.68, "text": "[♪♪♪]" },]
}
]

Derived analytics

Computed by this actor from the fields above — not source-native YouTube values. null when the required inputs are missing.

#FieldTypeDescription
30engagementRateNumber | null(likeCount + commentCount) / viewCount
31videoAgeDaysInteger | nullWhole days since publication
32viewsPerDayInteger | nullviewCount / max(videoAgeDays, 1)
33detectedLanguageString | null2-letter language code — API audio/default-language hint, else trigram detection over title+description

Channel & provenance

#FieldTypeDescription
34channelObjectChannel metadata (see below)
35provenanceObjectorder (Integer | null), source (keyword/hashtag/channel/playlist/seed/trending/startUrls), query, collectedAt (ISO-8601)

channel object: id, name, handle, url, subscriberCount (Integer | null — normalized), subscriberCountText (String | null — the display form "4.42M subscribers" when the video page is read; the raw count as a string, e.g. "201000", on the API-only path), totalViews, totalVideos, country, profileImage, description, createdAt, links.

Channel-level fields (subscriberCount, totalViews, totalVideos, country, description, profileImage, handle, url, createdAt) are populated by a batched channels.list call (one per unique channel per run) when a YouTube API key is configured; without a key most remain null. links is not populated (it requires scraping the channel About page) and is always empty.

Sample output

A real record from a keyword run (searchQueries: ["tesla"], includeTranscript: true, subtitleFormats: ["srt","vtt","txt","json"]). Long fields (srt/vtt/txt/json, description) are truncated here with ; the caption files are also linked in the run's key-value store. On datacenter IPs the DOM-only fields (isMonetized/commentsAllowed/isRatingsAllowed) may be null — see Field availability below.

{
"type": "video",
"isShort": false,
"VideoId": "qoh_rrgcUQ4",
"id": "qoh_rrgcUQ4",
"PageURL": "https://www.youtube.com/watch?v=qoh_rrgcUQ4",
"url": "https://www.youtube.com/watch?v=qoh_rrgcUQ4",
"title": "Tesla's Most Underrated Achievement Just Became Normal",
"thumbnailUrl": "https://i.ytimg.com/vi/qoh_rrgcUQ4/maxresdefault.jpg",
"publishDate": "2026-07-27",
"publishedAt": "2026-07-27T18:51:11Z",
"duration": "00:40:47",
"durationSeconds": 2447,
"viewCount": 15390,
"likeCount": 985,
"commentCount": 71,
"category": "Science & Technology",
"isLive": false,
"isMembersOnly": false,
"isPrivate": false,
"isFamilySafe": null,
"isMonetized": null,
"isRatingsAllowed": null,
"commentsAllowed": null,
"description": null,
"descriptionLinks": [],
"subtitles": [
{
"type": "auto_generated",
"language": "en",
"srtUrl": "https://api.apify.com/v2/key-value-stores/<id>/records/subtitles_qoh_rrgcUQ4_en_auto_generated.srt?signature=…",
"srt": "1\n00:00:00,080 --> 00:00:04,000\nTeslas are now driving coast to coast\n…",
"vttUrl": "https://api.apify.com/v2/key-value-stores/<id>/records/subtitles_qoh_rrgcUQ4_en_auto_generated.vtt?signature=…",
"vtt": "WEBVTT\n\n00:00:00.080 --> 00:00:04.000\nTeslas are now driving coast to coast\n…",
"txtUrl": "https://api.apify.com/v2/key-value-stores/<id>/records/subtitles_qoh_rrgcUQ4_en_auto_generated.txt?signature=…",
"txt": "Teslas are now driving coast to coast without a single intervention. …",
"jsonUrl": "https://api.apify.com/v2/key-value-stores/<id>/records/subtitles_qoh_rrgcUQ4_en_auto_generated.json?signature=…",
"json": [ { "start": 0.08, "dur": 3.92, "text": "Teslas are now driving coast to coast" }, "…" ]
}
],
"keywords": ["tesla", "tsla", "tesla stock", "investing", "…"],
"hashtags": [],
"features": { "isHD": null, "is4K": null, "isHDR": null, "isVR180": null, "is360": null },
"engagementRate": 0.06862,
"videoAgeDays": 0,
"viewsPerDay": 15390,
"detectedLanguage": "en",
"channel": {
"id": "UC4DBLlq1x0AKmip1QJUcbXg",
"name": "Brighter with Herbert",
"subscriberCount": 201000,
"subscriberCountText": "201000",
"totalViews": 89815604,
"totalVideos": 2516,
"country": "US",
"description": "Interviews about the future (Tesla, SpaceX, Robots and AI) …",
"profileImage": "https://yt3.ggpht.com/…",
"createdAt": "2012-10-24",
"handle": "@brighterwithherbert",
"url": "https://www.youtube.com/@brighterwithherbert"
},
"provenance": { "source": "keyword", "query": "tesla", "order": 1, "collectedAt": "2026-07-28T00:26:25.553Z" }
}

Field availability & nullability

This actor extracts public data. Not every field is available for every video — a null means "not available for this video", not an error. Plan your downstream models for nullable fields.

Field(s)May be null when
likeCount, commentCountThe creator has hidden likes/comments, or comments are disabled
isMonetized, isFamilySafe, isRatingsAllowedThe signal is not exposed for that video
publishedAtOnly a publish date (no time) is available — the field stays null rather than inventing a time
categoryNot exposed in the available metadata
channel.subscriberCount / subscriberCountTextThe channel hides its subscriber count
channel.totalViews, totalVideos, country, description, profileImage, handle, url, createdAtNo API key configured (these come from a channels.list enrichment call), or the channel hides them
channel.linksAlways empty — requires scraping the channel About page (not part of this actor)
subtitlesEmpty [] unless includeTranscript is on and the video has captions (~60–80% do)
detectedLanguageTitle/description too short to detect and no API language hint
DislikesAlways unavailable — YouTube no longer exposes dislike counts publicly

Captions are opt-in via includeTranscript (→ subtitles). For standalone/bulk transcript jobs, use the YouTube Transcript Scraper.


Errors & limitations

  • Unavailable videos (private, removed, age-restricted, geo-blocked, members-only) produce a typed error record rather than vanishing silently (see below).
  • Date filtering applies to Search Keywords only, not direct URLs.
  • Dislikes are never available (YouTube removed public dislike counts).
  • Transcripts/captions are opt-in (includeTranscriptsubtitles array); for standalone/bulk transcript jobs use the dedicated transcript actor linked above.
  • Rate limits: the actor throttles itself to respect YouTube; very large jobs should be batched by topic/channel.

Error records

When an input can't be resolved, the dataset gets a typed error row instead of dropping it silently. Error rows are never billed as results and don't count against maxItems. Filter them out with type != "error".

{
"type": "error",
"input": "https://www.youtube.com/watch?v=...",
"videoId": "...",
"errorCode": "PRIVATE",
"errorMessage": "This video is private",
"retryable": false,
"source": "startUrls",
"collectedAt": "2026-07-25T10:00:00.000Z"
}

errorCode is one of PRIVATE, AGE_RESTRICTED, MEMBERS_ONLY, VIDEO_UNAVAILABLE, GEO_BLOCKED, BLOCKED, NETWORK_ERROR, EXTRACTION_FAILED. retryable tells you whether re-running the input might succeed (transient) or never will (permanent).

Run summary

Every run writes a RUN_SUMMARY record to the default key-value store (and logs it): inputs provided, results saved, and a per-code error breakdown — so you can tell "requested vs returned" at a glance without scanning the dataset.


Integrations

Because this runs on the Apify platform, its dataset plugs into the standard Apify integrations with no extra work:

  • Export: JSON, CSV, Excel, XML directly from the dataset
  • Google Sheets / Airtable / databases: push results via Apify integrations
  • Automation: Make, Zapier, and n8n connectors
  • Webhooks: trigger downstream workflows on run completion
  • API & clients: fetch results via the Apify API, or the JavaScript / Python Apify clients
  • MCP / AI agents: the dataset is reachable by AI-agent tooling through the Apify platform

Compared to alternatives

Honest positioning against other YouTube actors on Apify:

YouTube Scraper Pro (this actor)Typical high-volume scrapersTypical low-cost scrapers
Data sourceOfficial YouTube Data API v3 + HTTP/Innertube/TikHubUnofficial extractionUnofficial extraction
Cookies / login requiredNoSometimesSometimes
Result provenance (source/order/time)YesRarelyRarely
Monetization + parsed description linksYesSometimesRarely
Single-video URLsSupportedVariesOften not allowed
TranscriptsSeparate transcript actorSometimes built inRarely
Raw throughput (videos/sec)Competitive, not the leaderHigher on some actorsVaries
PriceMid-marketOften lowerLowest

Where we win: official-API sourcing, provenance, monetization/description-link depth, single-video support, and a simple schema. Where others win: raw throughput and rock-bottom price. Choose this actor when you want trustworthy, analytics-ready data over the cheapest-possible bulk dump.


Performance

  • HTTP-first: most videos are saved directly over HTTP without launching a browser; the Puppeteer tier is a rare last resort.
  • Concurrency: up to 10 parallel requests.
  • Memory: default 2 GB (min 1 GB / max 4 GB). Pure-HTTP runs work at 1 GB; the default leaves headroom for the occasional browser fallback.

Throughput benchmark pending re-measurement. The previously published figure (~7s/video) described an older browser-heavy path and no longer reflects the HTTP-first architecture. A refreshed videos-per-minute benchmark will be added after a fresh Apify run.


  • SEO research: surface keywords, tags, hashtags, and linking practices
  • Content strategy: analyze formats, titles, and posting cadence
  • Competitive intelligence: benchmark creators and track launches
  • Market/academic research: study trends by niche, region, or language
  • Brand monitoring: find mentions and categorize sentiment downstream
  • Influencer discovery: filter by views/engagement within your topics
  • Analytics ETL: feed provenance-tagged, normalized rows into a warehouse

FAQ

Where does the data come from? The official YouTube Data API v3 for core fields, with HTTP page extraction and the Innertube API as fallbacks, and a hosted-API tier (TikHub) for videos that datacenter IPs can't reach directly. No cookies, no login, no residential proxy.

Do I need a residential proxy? No. The actor works reliably from datacenter IPs. Residential proxy is not required and not part of the standard input.

How do I control how much I spend? Set maxItems to cap the total results for the whole run, and maxResultsPerQuery to cap each source. Pricing is per event — see What you pay and the Pricing tab.

What am I charged for? Per result saved, plus a discovery event for search/channel/playlist sources. Direct video URLs incur no discovery charge. See What you pay.

Can I get transcripts or subtitles? Yes — set includeTranscript: true to fill the subtitles array via TikHub captions (off by default; billed per delivered subtitle). Choose one or more subtitleFormatssrt/vtt (timestamped), txt (plain text), or json ({start,dur,text} segments); each entry includes every selected format inline plus a key-value-store file link. For standalone / bulk transcript jobs, the dedicated YouTube Transcript Scraper is purpose-built.

Can I scrape a whole channel? Yes — put the channel's @handle, channel ID (UC…), or channel URL into the Discovery field. You can also drop in a video URL/ID there and it's treated as a seed — resolved to the channel that owns it. Use maxResultsPerQuery to limit videos per source.

Can I search by hashtag? Yes — put a #tag (or a youtube.com/hashtag/<tag> URL) in the Discovery field. It's routed through TikHub search (requires a TikHub key).

Can I target a country or language? Yes — set regionCode (37 countries) and language (20 codes).

Can I sort or filter results? Yes — sortBy (relevance / newest / most-viewed), plus contentType, videoDuration, titleFilter, uploadDate, and dateFrom/dateTo. These are applied to the discovered set. Videos listed directly in YouTube URLs or IDs are exempt (always returned).

Can I get trending videos? Yes — set getTrending: true to also scrape the Country's currently trending videos (via the official Data API chart=mostPopular). Requires a YouTube API key; the count follows maxResultsPerQuery.

Can I filter by date? Yes — dateFrom and dateTo (YYYY-MM-DD), applied to all discovered sources. (For relative windows, uploadDate is simpler.)

What about Shorts and live videos? Use contentType (all / videos / shorts / live). Shorts are detected by duration (≤ 60s), live from broadcast status. Every record is tagged with type (video/shorts/live) and isShort/isLive flags. Videos listed directly in YouTube URLs or IDs are always returned regardless of this filter.

Are dislikes available? No — YouTube no longer exposes dislike counts publicly. There is no dislike field.

Why are some fields null? null means the value isn't public for that video (hidden counts, restricted content, or channel data not fetched). See Field availability & nullability.

How do I import into Google Sheets or Excel? Export the dataset as CSV/Excel, or push it via the Apify Google Sheets integration. Flat camelCase keys make columns clean; the channel object expands into channel/... columns.

What happens to unavailable videos? Private, removed, age-restricted, geo-blocked, or members-only videos produce a typed error record (with an errorCode and a retryable flag) instead of vanishing. Error records aren't billed as results and don't count against maxItems. A RUN_SUMMARY in the key-value store gives you the requested-vs-returned totals and a per-code error breakdown.


Best Practices

  1. Start small: validate with maxResultsPerQuery: 5–10 (and a maxItems cap).
  2. Filter early: set contentType and videoDuration; use uploadDate/dateFrom/dateTo to narrow results.
  3. Bulk processing: paste many entries into Discovery (keywords / channels / playlists / hashtags) or YouTube URLs or IDs (one per line).
  4. Batch thoughtfully: group by topic/channel.
  5. Schema-first: build downstream models against the stable keys above; treat nullable fields as nullable.

Compliance

  • Intended for legitimate research & business intelligence.
  • Collects only public information.
  • Uses the official YouTube Data API v3; respects its Terms of Service.
  • Respect YouTube's Terms of Service and applicable laws in your jurisdiction.

Changelog

  • v3.1 (this release — pending deploy):
    • API-first discovery: keyword & #hashtag search via TikHub; channel/playlist/seed-video expansion via the YouTube Data API — no browser for discovery (was the main slowdown on datacenter IPs). Browser is now a rare last-resort for videos no API tier can resolve.
    • 🧭 Input reorganized to match the sibling video-finder: one combined Discovery field + a Direct URLs field; contentType select and titleFilter replace the per-type toggles/caps; discovery filters/sort applied client-side (fetch → filter → sort → cap).
    • 🌐 detectedLanguage field (API hint + franc-min trigram detection)
    • 📝 Optional subtitles (includeTranscript + multi-select subtitleFormats (srt/vtt/txt/json) + transcriptLanguage) via TikHub captions — each entry has inline content + a key-value-store file link; off by default, billed per delivered subtitle (new transcript pay-per-event)
    • 🏷️ Channel enrichment now also fills handle, url, createdAt for API-discovered records
  • v3.0:
    • 🔑 API keys wired as Apify secrets (@youtube_api_key_scraper_pro, shared @tikhub_api_key) — no hardcoded keys
    • 🛰️ New TikHub reliability tier between Innertube and the browser: recovers datacenter-blocked videos and avoids browser visits
    • 🧮 Global spend cap via maxItems
    • 🧱 Normalized output: id/url aliases, publishedAt (ISO, null when only a date is known), isShort, numeric channel.subscriberCount + subscriberCountText
    • 📊 Derived analytics: engagementRate, videoAgeDays, viewsPerDay
    • 🧾 analyticsFlat output mode for spreadsheet-friendly flat columns
    • 🧮 Discovery event is not charged when a search/channel returns zero results
    • 🧯 Typed error records for failed inputs (never billed) + a RUN_SUMMARY in the key-value store
    • 🔤 Sorting (sortBy) and server-side filters (uploadDate, duration) for search
    • 🔥 Trending videos input (getTrending) via the official Data API
    • 📡 Live-stream control (includeLiveStreams) + per-content-type caps (maxVideos/maxShorts/maxLiveStreams)
    • 🏷️ Channel enrichment: channel.totalViews/totalVideos/country/description filled via a cached channels.list call; profileImage now populated from the video page
    • 🗂️ Input form reorganized (What to scrape / Filters / Advanced); localization expanded to 37 countries and 20 languages
    • 🧠 Memory default 4 GB → 2 GB (browser fallback is now rare)
    • 📝 Documentation reconciled with the code (30 fields; captions/transcripts pointed to the dedicated actor)
  • v2.8: 3-tier hybrid extraction (HTTP + API + optimized browser); graceful degradation on datacenter IPs
  • v2.7: Removed captions field (required residential proxy, always null on datacenter IPs)
  • v2.6: Hybrid YouTube Data API v3 + web scraping architecture; residential proxy made optional
  • v2.5: Date-range filtering for search queries; bulk URL upload
  • v2.0: Performance tuning, richer channel fields, improved localization

Get Help

  • Issues & feature requests → GitHub / Apify support
  • Need something custom? Open an issue describing your dataset needs