# YouTube Data Scraper — videos, search, and channels (`dangul/youtube-data-scraper`) Actor

Fetch YouTube video metadata, run searches with deep pagination, and pull channel details. Returns real data instead of bot-check errors.

- **URL**: https://apify.com/dangul/youtube-data-scraper.md
- **Developed by:** [Daniel Gulla](https://apify.com/dangul) (community)
- **Categories:** Developer tools, Videos, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 result returneds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## YouTube Data Scraper

Fetch YouTube video metadata, run searches with real pagination, and pull channel details —
in one actor.

**Why this one returns data.** YouTube blocks the datacenter address ranges that scraping
platforms run on. A scraper calling YouTube directly from that infrastructure gets
*"Sign in to confirm you're not a bot"* rather than results, which is why so many actors in
this category quietly return empty datasets. This one routes every request through a
residential connection, so it gets the same responses a normal viewer would.

### Three things in one actor

```json
{
  "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
  "searchQueries": ["web scraping tutorial"],
  "channels": ["@mkbhd"],
  "maxResultsPerQuery": 100,
  "sortSearchBy": "views"
}
```

You can use any one of them on its own, or all three in a single run.

#### 1. Video details

Full metadata for a specific video:

| Field | Description |
|---|---|
| `title` · `description` | Video title and full description |
| `channel` · `channelId` · `channelUrl` | Uploader details |
| `viewCount` · `durationSeconds` | Statistics |
| `keywords` | The video's own tags — useful for SEO research |
| `publishDate` · `uploadDate` · `category` | Publication metadata |
| `thumbnails` | All available thumbnail URLs |
| `availableCaptionLanguages` | Every caption language the video offers |
| `isLive` · `isFamilySafe` | Flags |

#### 2. Search

Paginated search results, sortable by **relevance**, **upload date**, **view count**, or
**rating**. Ask for 500 results and you get 500 — pagination is handled for you.

Each result includes `videoId`, `title`, `channel`, `viewCount`, `durationText`,
`publishedText`, and `thumbnail`.

#### 3. Channels

Channel identity and recent uploads: `channelId`, `title`, `description`, `keywords`,
`avatar`, plus a list of recent videos with view counts and publish dates.

### What the channel option does and does not cover

Be aware of this before you buy: the channel option returns a channel's **recent uploads**,
not its entire back catalogue. For most channels that is roughly the latest 15 videos.

If you need a channel's full history, use `searchQueries` instead — search paginates deeply
and will return hundreds of results.

This is stated plainly because a scraper that promises a full catalogue and delivers fifteen
videos is worse than one that tells you the limit up front.

### Pricing

Pay per result returned. A video detail counts as one result, each search result counts as
one, and a channel counts as one. **Failed lookups cost you nothing** — they still appear in
the dataset with an `error` field so nothing disappears silently.

### What people use it for

- **Competitor and market research** — track what is being published in a niche
- **SEO and keyword research** — video keywords, titles, and view counts at scale
- **Content discovery** — find videos to summarise, transcribe, or reference
- **Trend monitoring** — sort by upload date to watch a topic in near real time
- **Dataset building** — structured YouTube metadata for analysis or AI pipelines

Pairs naturally with the **YouTube Transcript Scraper**: use this actor to find videos, then
that one to read what was said in them.

### Notes and limits

- Private, deleted, and age-restricted videos cannot be fetched.
- Subscriber counts are returned only when they can be read reliably; the field is `null`
  rather than a guessed number.
- Each item is fetched independently — one failure never aborts the run.
- This actor reads publicly available data only.

### Support

Something not returning what you expect? Open an issue on the **Issues** tab with the input
you used.

# Actor input Schema

## `videoUrls` (type: `array`):

Videos to fetch full details for. Accepts watch links, youtu.be, Shorts, or bare 11-character IDs.

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

Search terms. Each returns up to the result limit below, paginated for you.

## `channels` (type: `array`):

Channel handles or URLs (@name, /channel/UC..., /c/..., /user/...). Returns channel details plus recent uploads.

## `maxResultsPerQuery` (type: `integer`):

How many videos to return for each search query.

## `maxVideosPerChannel` (type: `integer`):

Upper bound on recent uploads returned per channel. See the README for what this covers.

## `sortSearchBy` (type: `string`):

Ordering applied to search queries.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "searchQueries": [],
  "channels": [],
  "maxResultsPerQuery": 50,
  "maxVideosPerChannel": 50,
  "sortSearchBy": "relevance"
}
```

# 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 = {
    "videoUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("dangul/youtube-data-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 = { "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"] }

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

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

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

```

## CLI example

```bash
echo '{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ]
}' |
apify call dangul/youtube-data-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=dangul/youtube-data-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/9vjfzxhhOF51P6kaP/builds/9RqTmkiC4EbP2vtdH/openapi.json
