# YouTube Scraper (`vakitek/youtube-scraper`) Actor

Scrape YouTube search results, videos, playlists and channels. Views, likes, comment count, description and exact date on every video, with YouTube's search filters. 2 USD per 1,000 videos, no minimum charge per run.

- **URL**: https://apify.com/vakitek/youtube-scraper.md
- **Developed by:** [Brahim Sliti](https://apify.com/vakitek) (community)
- **Categories:** Videos, Social media
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 video results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## YouTube Scraper

Search YouTube like you would in the search bar, or paste video, playlist and channel links, and get one row per video with views, likes, comment count, description, hashtags and the exact publish date.

YouTube's own search filters work here too: upload date, type, length and sort order.

### What people use it for

- **Market and product research.** Search "espresso machine review" and see which videos, channels and products get the views.
- **Brand monitoring.** Search your brand or your competitors' every week and catch new videos about them.
- **Finding creators.** Search a topic, sort by views, and get the channels behind the top videos.
- **Datasets for analysis or AI.** Pull thousands of videos with their descriptions and engagement numbers.

### How to use it

1. Add **Search terms**, one per line, and/or **Direct URLs** (a video, a playlist, a channel or a YouTube search page).
2. Set **Max regular videos per search term / URL** (default 10). Shorts and streams have their own limits, off by default.
3. Optional, for search terms: **Sorting order** (relevance, rating, date, views), **Date filter** (last hour to last year), **Video type** and **Length filter**.
4. Click **Start**. Export as JSON, CSV or Excel, or pull the results through the API.

```json
{
  "searchQueries": ["espresso machine review"],
  "maxResults": 25,
  "sortingOrder": "views",
  "dateFilter": "month"
}
```

### What you get

```json
{
  "id": "mAYbmcqPphc",
  "title": "The Fellow ES1 Espresso Machine Review",
  "url": "https://www.youtube.com/watch?v=mAYbmcqPphc",
  "viewCount": 755016,
  "likes": 70101,
  "commentsCount": 3200,
  "publishedAt": "2026-08-26T00:00:00.000Z",
  "dateIsApproximate": false,
  "duration": "34:16",
  "durationSeconds": 2056,
  "text": "In this video we review the Fellow ES1...",
  "hashtags": ["#coffee", "#espresso"],
  "channelName": "James Hoffmann",
  "channelUrl": "https://www.youtube.com/@jameshoffmann",
  "isChannelVerified": true,
  "type": "video"
}
```

- Likes, comment count, description, hashtags and the exact date are included on every video, at no extra cost. `publishedAt` is the publish DATE (YouTube doesn't give us the time of day on this product, so it's always midnight UTC); `dateIsApproximate` is `false` once we have that exact date, `true` when all we have is a relative text like "3 weeks ago".
- `input` and `fromYTUrl` tell you which search term or URL each row came from.
- `commentsTurnedOff` is `true` when the creator disabled comments.
- **Top comments (beta, free):** set **Top comments per video** between 1 and 20 to add the first top comments of each video, with author, likes and reply count.

### Pricing

**2 USD per 1,000 videos**, with likes, comment count, description and top comments included.

There is no minimum charge per run: a search returning 10 videos costs 0.02 USD. Error rows are free, and there's no monthly fee or Apify platform usage on top.

Example: 40 search terms with 25 videos each (1,000 videos) costs 2 USD.

### Good to know

- Subscriber count is only filled when the video came from a channel or video URL. YouTube's search results and playlists don't show it.
- This actor doesn't download videos or subtitles. For captions, use our [YouTube Transcript Scraper](https://apify.com/vakitek/youtube-transcript).
- Need a channel's whole catalogue and its stats? Our [YouTube Channel Scraper](https://apify.com/vakitek/youtube-channel-videos) does it for 0.80 USD per 1,000.
- You don't need a proxy, a YouTube account or a YouTube API key.

### Use it from n8n, Make or an API

- **Small inputs**: call `run-sync-get-dataset-items` and read the items back directly. Set **Time budget (seconds)** (default 240) to how long you are willing to wait: the actor stops starting new calls before that point and returns what it already has, so you never hit Apify's 300 second run-sync limit and lose the whole run. Any search term or URL left unfinished comes back as a `TIME_BUDGET_EXCEEDED` row instead of being silently dropped.
- **Big inputs**: start the run with `POST /v2/acts/vakitek~youtube-scraper/runs`, poll `GET /v2/actor-runs/<runId>` (or add `waitForFinish=60`) until the status is `SUCCEEDED`, then read `GET /v2/datasets/<datasetId>/items`. Set **Time budget (seconds)** to `0` (no limit) for this pattern.

### Errors

A bad input never crashes the run. It becomes a row with an `error` code, and you are not charged for it.

| `error` | What happened | Retry? |
| --- | --- | --- |
| `NOT_FOUND` | The video, playlist or channel was deleted, is private or never existed | No |
| `NO_RESULTS` | Nothing matches your search and filters | No |
| `INVALID_INPUT` | An option value is invalid | No |
| `PARSE_ERROR` | YouTube changed its page and we could not read it; we fix these fast, open an issue | No |
| `BLOCKED` | YouTube refused us for now, usually age-restricted content, even after trying every proxy tier | Yes |
| `UPSTREAM_ERROR` | Something went wrong on YouTube's side or ours | Yes |
| `UPSTREAM_UNAVAILABLE` | Our API was unreachable | Yes |
| `TIME_BUDGET_EXCEEDED` | The time budget ran out before this search term or URL finished | Yes |

Some rows also carry a `legacyError` field with the old, pre-unification code name (for example `VIDEO_NOT_FOUND`, `PLAYLIST_NOT_FOUND`, `CHANNEL_NOT_FOUND` or `LOGIN_REQUIRED`) so a pipeline still matching on it keeps working while it migrates to `error`.

### Reliability

Success rate, last 30 days: 98.9 % of 281 results across 31 runs (updated 2026-10-10). Failures counted: blocks, errors on our side, and runs that failed or timed out. Not counted: videos with no captions, private or deleted videos, bad links.

### FAQ

**Is this an alternative to the YouTube Data API?**
Yes, for public data. You don't need an API key and there's no daily quota: you pay per video returned.

**I already use another YouTube scraper on Apify. Do I have to change my code?**
Probably not much. The input (`searchQueries`, `startUrls`, `maxResults`...) and most output fields follow the most used YouTube scraper on the Store. One difference: our `date` is the relative text YouTube shows ("1 month ago"), so use `publishedAt` for an ISO date.

**Can I call it from my code or from an AI agent?**
Yes, like any Apify actor: REST API, the Python and JavaScript clients, or the Apify MCP server. The examples are in the API tab.

**Something broke or a field is missing?**
Open an issue on this page. We read every one and usually answer within a day.

# Changelog

This Actor's version history is a separate document: https://apify.com/vakitek/youtube-scraper/changelog.md

# Actor input Schema

## `searchQueries` (type: `array`):

Enter search terms just like you would enter them in YouTube's search bar.

## `startUrls` (type: `array`):

YouTube video, playlist, channel or search-results-page URLs. Ignored fields from search terms below don't apply to these (a channel URL, for instance, always uses maxResults as its video cap, not maxResultsShorts/maxResultStreams).

## `maxResults` (type: `integer`):

Maximum number of regular videos to scrape per search term or URL.

## `maxResultsShorts` (type: `integer`):

Maximum number of Shorts to scrape per search term. Only applies to searchQueries, not startUrls.

## `maxResultStreams` (type: `integer`):

Maximum number of live/past streams to scrape per search term. Only applies to searchQueries, not startUrls. YouTube's search has no dedicated stream filter, so streams are recognized from the same regular-video results (Streamed .../currently-live), not fetched separately.

## `sortingOrder` (type: `string`):

YouTube sorting parameter for search. Only applies to searchQueries.

## `dateFilter` (type: `string`):

YouTube upload date filter for search. Only applies to searchQueries.

## `videoType` (type: `string`):

YouTube video type filter for search. Only applies to searchQueries.

## `lengthFilter` (type: `string`):

YouTube video length filter for search. Only applies to searchQueries.

## `maxComments` (type: `integer`):

Number of top comments to add to each video (0 to 20). 0 = off, no extra request. First page of top comments only, replies not included. Free during beta.

## `language` (type: `string`):

Interface language (hl) requested from YouTube, as an ISO 639-1 code (e.g. fr, de, ja). Controls which language translated titles/descriptions come back in. It does NOT change the transcript or video content language, only YouTube's own UI strings.

## `country` (type: `string`):

Geolocation (gl) requested from YouTube, as an ISO 3166-1 alpha-2 code (e.g. FR, DE, JP).

## `timeBudgetSecs` (type: `integer`):

Stop and return what is ready after this many seconds, so n8n/Make run-sync calls never time out. 0 = no limit.

## Actor input object example

```json
{
  "searchQueries": [
    "espresso machine review"
  ],
  "startUrls": [],
  "maxResults": 10,
  "maxResultsShorts": 0,
  "maxResultStreams": 0,
  "sortingOrder": "relevance",
  "dateFilter": "",
  "videoType": "",
  "lengthFilter": "",
  "maxComments": 0,
  "language": "en",
  "country": "US",
  "timeBudgetSecs": 240
}
```

# Actor output Schema

## `results` (type: `string`):

Videos, Shorts and streams found by the search queries or URLs, with views, likes, comment count, description and channel info. Error items carry an `error` code and the `input` that failed.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQueries": [
        "espresso machine review"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vakitek/youtube-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "searchQueries": ["espresso machine review"] }

# Run the Actor and wait for it to finish
run = client.actor("vakitek/youtube-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "espresso machine review"
  ]
}' |
apify call vakitek/youtube-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vakitek/youtube-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/MZQMsYuM5MiNErObc/builds/erJGA4nLmAi0fYyny/openapi.json
