# YouTube Scraper API: Videos, Transcripts, Shorts & Channels (`sauliusautomatesit/youtube-scraper-api`) Actor

Scrape YouTube videos, Shorts and live streams from search results, channels and playlists, with the full transcript of each video at no extra cost. Exact views, likes, publish date, duration, tags and description. No API key, no quota, no login; also via MCP. $2 per 1,000 videos.

- **URL**: https://apify.com/sauliusautomatesit/youtube-scraper-api.md
- **Developed by:** [Saulius AutomatesIT](https://apify.com/sauliusautomatesit) (community)
- **Categories:** Videos, Social media, AI
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 1,000 videos

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 API: Videos, Transcripts, Shorts & Channels

Scrape YouTube search results, whole channels, playlists and single videos or Shorts. Every video comes back with **exact view count, like count, publish date, duration, category, tags, hashtags, description and channel**. Channel inputs also give the channel's subscriber count. Tick **Include transcripts** and every row also carries the video's full transcript, **at no extra cost**.

No YouTube API key, no daily quota, no login, no browser. **$2 per 1,000 videos.**

### What you can use it for

- **Content and competitor research**: every video a channel has published, with views and likes, to see what works.
- **Keyword and trend research**: the top videos for any search term, newest first or most viewed, filtered by upload date and length.
- **Influencer discovery**: search a niche and get the channels behind the videos that rank.
- **Shorts research**: a channel's Shorts tab, or Short URLs, with views and likes.
- **Transcript datasets for AI and RAG**: metadata and full transcript of every video in a channel, playlist or search, in one row per video, for $2 per 1,000.
- **Data for AI agents and dashboards**: fresh YouTube metrics through the API, n8n, Make, Zapier or the Apify MCP server.

### YouTube Data API vs this Actor

| | YouTube Data API v3 | This Actor |
|---|---|---|
| Setup | Google Cloud project, API key | an Apify token |
| Daily limit | 10,000 quota units; one search costs 100, so about 100 searches a day. More needs Google's quota audit | none |
| Search filters | yes | sort by date, views or rating; upload date; duration |
| Like count, tags, category | yes, with a second call per batch | in every row |
| Transcripts | only for videos you own | any video with captions, included in the price |
| Price | free within the quota | $2 per 1,000 videos |

If 100 searches a day is enough and you already run a Google Cloud project, use the official API. If you need thousands of videos today, use this Actor.

### How to use it

1. Put keywords in **Search queries**, or paste URLs in **YouTube URLs**: videos, Shorts, channels (`@handle`, `/channel/UC...`), playlists or search pages.
2. Set **Max videos per input** (default 50, up to 5,000 per search, playlist or channel tab).
3. Optional: sort and filter searches; choose **videos**, **shorts** and/or **streams** for channels.
4. Run it and download the results as JSON, CSV or Excel, or read them through the API.

#### Input example

```json
{
  "searchQueries": ["web scraping tutorial", "iphone 17 review"],
  "startUrls": [
    "https://www.youtube.com/@mkbhd",
    "https://www.youtube.com/playlist?list=PLu0W_9lII9agwh1XjRt242xIpHhPT2llg",
    "https://www.youtube.com/shorts/R6yNUnRXZ64"
  ],
  "maxResults": 100,
  "sortBy": "date",
  "uploadDate": "month",
  "channelContent": ["videos", "shorts"],
  "includeTranscripts": true,
  "transcriptLanguages": ["en"]
}
```

### Output

One item per video:

```json
{
  "type": "video",
  "videoId": "u0p_dBCEDs4",
  "url": "https://www.youtube.com/watch?v=u0p_dBCEDs4",
  "title": "How to Cook Pasta Perfectly: Here's Everything You Need to Know",
  "description": "...",
  "viewCount": 3054295,
  "likeCount": 21908,
  "durationSeconds": 140,
  "duration": "2:20",
  "publishedAt": "2013-05-03T07:56:37-07:00",
  "uploadedAt": "2013-05-03T07:56:37-07:00",
  "category": "Howto & Style",
  "keywords": ["Cooking", "pasta", "noodles", "tips", "kitchen", "recipe"],
  "hashtags": [],
  "channelId": "UCxAS_aK7sS2x_bqnlJHDSHw",
  "channelName": "America's Test Kitchen",
  "channelHandle": "@AmericasTestKitchen",
  "channelUrl": "https://www.youtube.com/channel/UCxAS_aK7sS2x_bqnlJHDSHw",
  "thumbnailUrl": "https://i.ytimg.com/vi/u0p_dBCEDs4/maxresdefault.jpg",
  "isShort": false,
  "isLiveContent": false,
  "isFamilySafe": true,
  "isUnlisted": false,
  "detailsComplete": true,
  "source": "search",
  "input": "cooking pasta",
  "searchQuery": "cooking pasta",
  "position": 8,
  "scrapedAt": "2026-10-05T18:07:42.808Z"
}
```

- `type` is `video`, `short` or `stream` (a live stream, live now or finished).
- Channel inputs add `channelSubscribers`, `channelSubscribersText` and `channelVideoCount` (YouTube shows subscribers rounded, such as 21.3M). Playlist inputs add `playlistId` and `playlistTitle`.
- `position` is the video's place in the search results, channel tab or playlist.
- `detailsComplete` is `false` on the rare row where YouTube refused the full details: views, likes, date, channel and description are still there, but tags, category and exact publish time are not.
- A video that is private, deleted or not available gives a free `error` row and costs nothing.
- With **Include transcripts** on, each row adds `transcript` (plain text), `transcriptLanguage` and `transcriptIsAutoGenerated`, plus `transcriptSegments` (`text`, `start`, `duration` in seconds) when timestamps are on. No captions: `transcript` is null and `transcriptError` says why. The **Transcripts** tab of the dataset shows them as a table.

The run summary (videos delivered, unavailable videos, failures) is saved as `OUTPUT` in the run's key-value store.

### Pricing

Pay per video, no subscription:

| Event | Price |
|---|---|
| Video | $0.002 ($2 per 1,000 videos) |
| Actor start | $0.00005 |

Transcripts are included: a video with its transcript is still $0.002. A search with 50 videos costs $0.10. A whole channel with 1,000 videos costs $2. Bronze, Silver and Gold Apify plans get 5%, 10% and 15% off. Proxy and compute are included. Apify's free plan's $5 of monthly credit covers about 2,500 videos.

### Use it from code

#### API (cURL)

```bash
curl -X POST "https://api.apify.com/v2/acts/sauliusautomatesit~youtube-scraper-api/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries": ["web scraping tutorial"], "maxResults": 20}'
```

#### Python

```bash
pip install apify-client
```

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("sauliusautomatesit/youtube-scraper-api").call(run_input={
    "startUrls": ["https://www.youtube.com/@mkbhd"],
    "maxResults": 200,
})
videos = [v for v in client.dataset(run.default_dataset_id).iterate_items() if v["type"] != "error"]
for v in sorted(videos, key=lambda v: v["viewCount"] or 0, reverse=True)[:10]:
    print(v["viewCount"], v["likeCount"], v["title"])
```

`run.default_dataset_id` is for `apify-client` 3.x; on 2.x write `run["defaultDatasetId"]`. Pass `max_total_charge_usd=1` to `.call()` to cap a run at $1.

#### JavaScript

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

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('sauliusautomatesit/youtube-scraper-api').call({ searchQueries: ['lofi hip hop'], sortBy: 'views' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((v) => `${v.viewCount} ${v.url}`));
```

#### MCP (Claude, Cursor, any MCP client)

Add `https://mcp.apify.com/?tools=sauliusautomatesit/youtube-scraper-api` as a remote MCP server and your agent can search YouTube as a tool.

### Limits, honestly

- Search returns what YouTube search shows a visitor in the United States, in English. Very deep searches thin out: YouTube usually stops after several hundred results for one query.
- Comment counts are not included.
- Transcripts come from the video's captions (uploaded or YouTube's auto captions) as plain text, with optional timestamps. Videos without captions get `transcriptError: NO_CAPTIONS`. For SRT, VTT, chunked text or speech to text on videos without captions, use YouTube Transcript Scraper below.
- Subscriber counts come from channel inputs and are rounded by YouTube (21.3M). Search results do not include them.
- Public videos only. No login, so no private, members-only or age-restricted videos.

### Related Actors

- [YouTube Transcript Scraper](https://apify.com/sauliusautomatesit/youtube-transcript-scraper): transcript specialist: SRT, VTT, clean text and chunks for RAG, language fallback, $2.50 per 1,000.
- [Google Trends API](https://apify.com/sauliusautomatesit/google-trends-api): search interest over time, including YouTube search.
- [Bing Search API](https://apify.com/sauliusautomatesit/bing-search-api): web results for any list of queries.

### FAQ

**Do I need a YouTube API key or Google account?** No. The Actor reads what YouTube shows any visitor.

**Is there a daily limit?** No quota. Large runs take longer: about 1,000 videos in 6 minutes.

**Can I get all videos of a channel?** Yes. Paste the channel URL and set **Max videos per input** to the channel's video count (up to 5,000 per tab). Choose videos, Shorts and live streams separately.

**Can I get transcripts too?** Yes. Turn on **Include transcripts**. Each video row gets `transcript`, `transcriptLanguage` and `transcriptIsAutoGenerated`; turn on **add timestamps** for every caption line with its start time. No extra charge.

**Can I monitor a channel or keyword?** Yes. Save the input as a task, sort by upload date, and schedule it.

**Is it legal?** It collects publicly visible video data. You are responsible for how you use it and for complying with the laws that apply to you.

# Actor input Schema

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

One keyword or phrase per line, as you would type it into YouTube search. Each query returns up to "Max videos per input" videos.

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

Video, Short, channel, playlist or search URLs, one per line: `https://www.youtube.com/watch?v=...`, `https://www.youtube.com/shorts/...`, `https://www.youtube.com/@handle`, `https://www.youtube.com/channel/UC...`, `https://www.youtube.com/playlist?list=...`.

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

Most videos to return for each search query, playlist and channel tab. A video URL always returns one video.

## `sortBy` (type: `string`):

Order of search results. Applies to search queries only.

## `uploadDate` (type: `string`):

Only videos uploaded in this period. Applies to search queries only.

## `duration` (type: `string`):

Only videos of this length: short is under 4 minutes, medium 4 to 20 minutes, long over 20 minutes. Applies to search queries only.

## `channelContent` (type: `array`):

Which channel tabs to read for channel URLs: long videos, Shorts, live streams. A URL that already ends in /videos, /shorts or /streams uses that tab only.

## `includeTranscripts` (type: `boolean`):

Add each video's transcript (captions or YouTube's auto captions) to its row as plain text. Included in the per video price, no extra charge. Videos without captions get transcriptError NO_CAPTIONS.

## `transcriptLanguages` (type: `array`):

Preferred caption languages, best first, as codes like en, es, de. When none match, English or the first available track is used.

## `transcriptTimestamps` (type: `boolean`):

Also add transcriptSegments: every caption line with its start and duration in seconds.

## `concurrency` (type: `integer`):

How many videos are fetched at the same time.

## `proxyConfiguration` (type: `object`):

Apify Proxy is used by default and is included in the price. Change only if you know you need to.

## Actor input object example

```json
{
  "searchQueries": [
    "web scraping tutorial"
  ],
  "maxResults": 10,
  "sortBy": "relevance",
  "uploadDate": "any",
  "duration": "any",
  "channelContent": [
    "videos"
  ],
  "includeTranscripts": false,
  "transcriptLanguages": [
    "en"
  ],
  "transcriptTimestamps": false,
  "concurrency": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One row per video with views, likes, dates, duration, channel and tags. Download as JSON, CSV or Excel, or read it from this API endpoint.

## `summary` (type: `string`):

Videos delivered, videos unavailable, inputs without videos and failures.

# 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": [
        "web scraping tutorial"
    ],
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("sauliusautomatesit/youtube-scraper-api").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": ["web scraping tutorial"],
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("sauliusautomatesit/youtube-scraper-api").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": [
    "web scraping tutorial"
  ],
  "maxResults": 10
}' |
apify call sauliusautomatesit/youtube-scraper-api --silent --output-dataset

```

## MCP server setup

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

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/zbfdidlXOafedxCXJ/builds/KtigBdwmDSPsuBCDZ/openapi.json
