Apify Youtube Eng Scraper
Pricing
from $2.00 / 1,000 video-metrics-successes
Apify Youtube Eng Scraper
YouTube views, likes & video metadata from URLs — no API key, proxy fallback included.
Pricing
from $2.00 / 1,000 video-metrics-successes
Rating
5.0
(1)
Developer
Olek Coder
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
3 days ago
Last modified
Categories
Share
YouTube Video Engagement Scraper — Views, Likes, Title & Description
Actor ID: morph_coder~youtube-eng-scraper
Extract YouTube video engagement metrics (views, likes, comments), title, description, channel info, and duration from video URLs.
Default: Innertube scraping — no API key. Optional: your own YouTube Data API v3 key (input or Actor environment) for official API calls — more reliable on large batches, uses your GCP quota.
This Actor is not affiliated with YouTube or Google. Users must comply with YouTube Terms of Service and applicable laws.
Features
- Scrape metrics and metadata from
watch,youtu.be,shorts, andembedURLs - No API key by default — Innertube-based extraction
- Optional BYOK — YouTube Data API v3 (input
youtubeApiKeyor envYOUTUBE_API_KEY) - Smart proxy fallback: direct → Apify datacenter → residential on blocks (optional manual proxy override)
- Optional channel stats (
includeChannelStats) — subscribers, channel views, joined date; deduplicated per channel ID - Structured dataset output with extension stubs for upcoming features
Coming soon
| Feature | Pricing (planned) |
|---|---|
| Subtitles | Per video minute |
| Audio transcription | Per video minute |
| AI summary | Per video minute |
| Sentiment analysis | Per video minute |
Input
| Field | Default | Description |
|---|---|---|
videoUrls | sample watch URL | YouTube video URLs to scrape |
youtubeApiKey | (empty) | Optional BYOK key; enables Data API v3 mode (see below) |
features.*.enabled | false | Future add-ons (not available yet) |
requestDelayMs | 200–400 | Pause between requests (innertube) or between API batches |
includeChannelStats | false | After videos, enrich each row with unique channel stats (subscribers, etc.) |
enableProxyPass2 | false | Retry failed innertube URLs via Apify proxy (ignored in API mode) |
proxyConfiguration | no proxy | Optional override; ignored in API mode |
Channel stats (includeChannelStats)
When enabled, the Actor scrapes videos as usual, collects unique channel.id values from successful rows, fetches channel metadata, then pushes dataset rows with channel.stats:
| Field | Description |
|---|---|
subscriberCount | Total subscribers |
videoCount | Public video count |
viewCount | Total channel views |
joinedAt | Join / creation date when available |
description, country, handle, title | From channel About / API |
Without API key: innertube (getChannel + About tab) — one request per unique channel. With API key: batched channels.list (up to 50 per call). Default pipeline is unchanged when the flag is false.
Deduplication: if many videos share the same channel, the Actor fetches that channel once, writes the same channel.stats on every matching row, and bills the channel add-on once per unique channel ID (see Pricing).
YouTube Data API mode (optional, BYOK)
If you provide an API key, the Actor uses videos.list (official API) instead of Innertube. Good when you need stable results and accept Google quota limits.
| How to set the key | Who typically uses it |
|---|---|
Input youtubeApiKey (secret field) | Per-run BYOK from Apify Console or API |
Actor env YOUTUBE_API_KEY | Apify Console → Actor → Environment variables (key not in run input/logs) |
Priority: input key overrides environment. The key is never logged.
- Up to 50 video IDs per HTTP request;
requestDelayMsapplies between batches, not every video. enableProxyPass2andproxyConfigurationare ignored (API calls go to Google, not YouTube pages).- Missing videos →
status: unavailable. Quota / invalid key →failedrows and the run stops. - Success rows include
extra.dataSource: "youtube-data-api-v3". - Enable YouTube Data API v3 in Google Cloud Console and create an API key; default free quota is ~10,000 units/day (~10,000 single-video lookups).
Output
One dataset row per input URL.
| Field | Description |
|---|---|
url | Input video URL |
videoId | YouTube video ID |
status | success, unavailable, or failed (see below) |
title, description | Video metadata |
durationSeconds | Length in seconds |
publishedAt | ISO date when available |
channel | { id, title, url }; with includeChannelStats, also stats (see below) |
channel.stats | When includeChannelStats: subscribers, video/view counts, joinedAt, description, etc. |
channel.stats.billable | true if this channel was counted for pay-per-event channel-stats-success |
metrics | { viewCount, likeCount, commentCount } |
extra | Tags, category, thumbnails, isLive, isShort, etc. |
extensions | Stubs: subtitles, transcription, aiSummary, sentiment (all null for now) |
billable | true when status is success (pay-per-event video-metrics-success) |
Result statuses
| Status | Meaning | billable (video) | Channel add-on |
|---|---|---|---|
success | Video metrics fetched | yes (video-metrics-success) | only if includeChannelStats and channel fetch succeeded |
unavailable | Deleted, private, region-blocked, etc. | no | no |
failed | Rate limit, empty response, network — may retry with proxy | no | no |
unavailable and failed rows are never charged. Channel stats are an add-on on top of successful video rows, not a replacement.
Example (success)
{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ","videoId": "dQw4w9WgXcQ","status": "success","title": "Rick Astley - Never Gonna Give You Up (Official Video)","description": "...","durationSeconds": 213,"publishedAt": "2009-10-25T06:57:33.000Z","channel": {"id": "UCuAXFkgsw1L7xaCfnd5JJOw","title": "Rick Astley","url": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw"},"metrics": {"viewCount": 1700000000,"likeCount": 18000000,"commentCount": 2400000},"extensions": {"subtitles": null,"transcription": null,"aiSummary": null,"sentiment": null},"billable": true,"fetchedAt": "2026-05-24T12:00:00.000Z"}
URL validation
Each input string is checked before scraping:
| Case | Result |
|---|---|
| Valid YouTube video URL or 11-character video ID | Scraped |
| Not a YouTube domain (e.g. TikTok, Vimeo) | failed — URL is not a YouTube link |
| YouTube channel, playlist-only, homepage | failed — no video ID found |
| Malformed / empty | failed — Invalid URL format |
Supported: youtube.com/watch, youtu.be/…, /shorts/, /embed/, /live/, raw video ID.
Proxy: anti-bot vs country (geo)
Two separate things:
1. Type of IP (main goal of auto-fallback) — whether you look like a normal user or a datacenter bot.
| Level | Purpose |
|---|---|
| Direct | Cheapest; works for many videos |
| Datacenter | When YouTube blocks the run IP (429/403) |
| Residential | Stronger “real user” signal when datacenter is blocked |
Auto-escalation changes IP reputation, not your language settings.
2. Proxy country (geo) — which country YouTube thinks the client is in.
- Matters for region-blocked videos and sometimes localized metadata.
- For most public videos, country is optional; default Apify proxy country is usually enough.
- Does not replace residential vs datacenter — you can have a US residential or US datacenter IP; they behave differently for anti-bot.
To set country manually, enable Apify Proxy in input and choose Proxy country in the Console UI (or apifyProxyCountry in API input, e.g. "US").
Default: direct only (fast, no Apify proxy cost)
All URLs are fetched without proxy. Retryable errors (Empty response, rate limit) → status: failed immediately.
Optional: enableProxyPass2: true
- Pass 1 — direct (same as default).
- Pass 2 — retryable failures via datacenter → residential (slower, paid proxy traffic; may recover ~50% of empty responses on large batches).
Custom proxy: proxyConfiguration.useApifyProxy: true uses your proxy on every URL (single-pass; ignores enableProxyPass2).
Pricing
On Apify Store, this Actor uses pay-per-event billing. Rates are shown on the Store listing and in the run invoice — they are configured in Apify Console → Monetization, not in this README.
Events
| Event | When it fires |
|---|---|
video-metrics-success | One count per dataset row with status: success (video engagement data delivered). |
channel-stats-success | One count per unique channel.id successfully enriched when includeChannelStats is true. Not charged if the channel fetch failed (channel.stats.errorMessage set). |
video-subtitles-minute | Planned — per video minute (future). |
Two layers: successful videos are always billed via video-metrics-success. Channel stats are a separate add-on only when you enable includeChannelStats and the channel profile fetch succeeds.
Deduplication (channel add-on)
The Actor does not charge per duplicate channel on multiple video rows:
- Collect unique channel IDs from successful videos.
- Fetch each channel once.
- Copy
channel.statsonto every row that shares that channel. - Emit one
channel-stats-successevent per unique channel billed.
| Scenario | video-metrics-success | channel-stats-success |
|---|---|---|
success, includeChannelStats off | 1 per success row | 0 |
| 3 success videos, 3 different channels, stats OK | 3 | 3 |
| 10 success videos, same channel, stats OK | 10 | 1 |
Video success, channel fetch failed | 1 | 0 |
failed or unavailable | 0 | 0 |
Transparency
- Store / run cost tab: Apify lists each event and unit count before and after the run.
- Dataset audit: row
billable= video event;channel.stats.billable= channel event applied to that row’s channel (same value on all rows sharing one channel ID).
Maintainer setup (Console)
apify-default-dataset-item→ $0 (do not bill dataset rows separately from custom events).- Register
video-metrics-successandchannel-stats-successas custom events with prices on the platform.
Large batches (100+ URLs)
| Setting | Recommendation |
|---|---|
| Memory | 1024 MB minimum (API: "memory": 1024). 512 MB can OOM on long runs with youtubei.js. |
| Run timeout | at least 3600 s (API: "timeout": 5400). Rule of thumb: URLs × 8 seconds. |
| requestDelayMs | Default 400 for 50+ URLs; use 0–300 for speed. 1200 adds ~8 min per 400 URLs but rarely fixes slowness — proxy retries dominate. |
| Resume | KV checkpoint skips completed videoIds; pass 2 queue is restored after migration. |
| enableProxyPass2 | Default false (fast/cheap). true if you need more successes and accept ~2× run time + proxy cost. |
Expected unavailable | This video is unavailable → status: unavailable (not failed, not billed) |
Run via API
POST https://api.apify.com/v2/acts/morph_coder~youtube-eng-scraper/runs?token=YOUR_TOKENContent-Type: application/json{"videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],"includeChannelStats": true}
Maintainer docs
See DEVELOPMENT.md, CHECKLIST.md, and REFERENCE.md.