# YouTube Scraper Lowcost (0.3$/1K 🤑) (`sones/youtube-scraper-lowcost`) Actor

Scrape videos, Shorts and streams from YouTube channels, playlists and video URLs, with exact dates and views. $0.30 per 1,000 videos.

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

## Pricing

from $0.30 / 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.

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 (Low-Cost)

Scrape the videos, Shorts and live streams of YouTube channels and playlists, with **exact publish dates and exact view counts**, for **$0.30 per 1,000 videos**. No YouTube account, no API key, no quota.

### What does YouTube Scraper do?

Paste channels, playlists or video links. You get one row per video with its title, link, exact view count, exact publish date, duration, thumbnail and channel (name, id, handle, link and subscriber count).

- 📺 **Channels**: their Videos, Shorts and Live tabs. Enter a channel as `https://www.youtube.com/@mkbhd`, `@mkbhd`, or a `/channel/`, `/c/` or `/user/` link. A link to one tab, such as `https://www.youtube.com/@mkbhd/shorts`, scrapes that tab.
- 📃 **Playlists**: every video of a playlist, in the playlist's order.
- 🎬 **Single videos**: the details of each video link you paste.
- 📅 **Date filter**: only the videos published after a date, or in the last `7 days`, for daily or weekly monitoring.

### Why is it cheaper?

- 💰 **$0.30 per 1,000 videos**, a fraction of what most YouTube scrapers charge.
- 🎯 **Exact numbers included.** Exact publish dates and exact view counts are in the price, not an extra.
- ⚡ **Fast.** No browser runs behind it: 616 videos from 6 channels, a playlist and 2 video links took 43 seconds, all with exact dates and views.
- 🧾 **You pay for the videos you get.** A channel that does not exist or a tab with no videos has no per-item charge. The only other charge is $0.005 per run start (per GB of memory; runs use 1 GB by default).

### Who uses it?

- **Marketers and agencies**: track competitors' uploads, compare views across channels, find the formats that work.
- **Creators**: benchmark your channel against others in your niche.
- **AI and data teams**: build video lists to feed transcript, comment or analytics pipelines.
- **Researchers**: collect publishing histories with exact dates.

### How to use it

1. [Create a free Apify account](https://console.apify.com/sign-up).
2. Open the Actor and paste channels, playlists or videos in **Channels, playlists or videos**.
3. Pick the **Channel content** you want (Videos, Shorts, Live) and how many **Videos per channel tab or playlist**.
4. Optionally set **Published after** to get only recent videos.
5. Click **Start**, then download the results as JSON, CSV, Excel or HTML, or read them through the Apify API.

### Input

```json
{
    "urls": [
        "https://www.youtube.com/@mkbhd",
        "@veritasium",
        "https://www.youtube.com/playlist?list=PLAqhIrjkxbuWI23v9cThsA9GvCAUhRvKZ",
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ],
    "contentTypes": ["videos", "shorts"],
    "maxResults": 100,
    "newerThan": "7 days",
    "exactDetails": true
}
```

| Field          | Type    | Required | Description                                                                                                                                                                                |
| -------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `urls`         | Array   | **Yes**  | Channel links or handles, playlist links or `PL…` ids, video links or ids.                                                                                                                 |
| `contentTypes` | Array   | No       | Which tabs of each channel to scrape: `videos`, `shorts`, `streams` (the Live tab). A channel link that names a tab (`…/@mkbhd/shorts`) scrapes that tab instead. Default: `["videos"]`.   |
| `maxResults`   | Integer | No       | The most videos to get from each channel tab and each playlist (1 to 5,000). A video link always gives one video. Default: `50`.                                                           |
| `newerThan`    | String  | No       | Only videos published after this date: `2026-01-01`, `2026-01-01T12:00:00Z`, a time before the run starts (`7 days`, `24 hours`, `2 weeks`, `3 months`), or a Unix timestamp.              |
| `exactDetails` | Boolean | No       | Exact publish date and exact view count for each video. Turn off for a faster run with dates as YouTube shows them ("3 days ago") and rounded view counts ("1.2M views"). Default: `true`. |

A channel with two content types counts as two channel tabs: `@mkbhd` with Videos and Shorts gives up to 100 videos and up to 100 Shorts when `maxResults` is 100. Entries that are not YouTube channels, playlists or videos are skipped and counted in the run's status; the same entry twice is scraped once.

### Output

One row per video:

```json
{
    "type": "video",
    "videoId": "scwlR0QHGOk",
    "url": "https://www.youtube.com/watch?v=scwlR0QHGOk",
    "title": "The NEW Tesla Roadster: My Honest Reaction",
    "viewCount": 11499564,
    "viewCountText": "11M views",
    "durationSeconds": 1365,
    "durationText": "22:45",
    "publishedAt": "2026-10-17T02:09:23.000Z",
    "publishedTimeText": "3 days ago",
    "thumbnailUrl": "https://i.ytimg.com/vi/scwlR0QHGOk/hqdefault.jpg",
    "channelId": "UCBJycsmduvYEL83R_U4JriQ",
    "channelName": "Marques Brownlee",
    "channelHandle": "@mkbhd",
    "channelUrl": "https://www.youtube.com/@mkbhd",
    "subscriberCountText": "21.4M subscribers",
    "input": "https://www.youtube.com/@mkbhd/videos",
    "scrapedAt": "2026-10-20T23:11:44.718Z"
}
```

- `type` is `video`, `short` or `stream` (a live stream, past or live right now). Shorts link to their Shorts page.
- `viewCount` and `publishedAt` are exact with **Exact dates and view counts** on. With it off, `viewCount` is read from the rounded text and `publishedAt` is `null` unless the date filter needed it; `viewCountText` and `publishedTimeText` always show YouTube's own wording. A video whose details YouTube does not give keeps the rounded view count and a `null` `publishedAt`; under a date filter, it is left out when the date YouTube shows could fall on either side of the filter's date.
- `input` is the page the video comes from: the channel tab (`…/@mkbhd/shorts`), the playlist or the video link. Join on it to tell your sources apart.
- `subscriberCountText` is filled for videos from a channel tab.

The dataset's **Overview** tab shows the thumbnail, title, type, channel, views, duration and dates of each video.

Each run also saves a `RUN_SUMMARY` record in its key-value store: how many videos were exported, and for every channel tab, playlist and video whether it was scraped, had no videos, was not found, or could not be scraped.

### Pricing

- **$0.30 per 1,000 videos** ($0.0003 per video)
- **$0.005 per run start** (per GB of memory; runs use 1 GB by default)

Besides the run start, you pay only for the rows in your dataset. 1,000 videos with exact dates and view counts cost $0.305. Set a spending limit on the run and the scraper stops when it reaches it.

### Limits

- **Subscriber counts are rounded** ("21.4M subscribers"): YouTube shows no exact count without signing in.
- **Shorts tiles show no date and no length** on YouTube, so `publishedTimeText` and `durationText` are empty for Shorts. With exact details on, `publishedAt`, `durationSeconds` and `viewCount` are exact; with them off, `publishedAt` and `durationSeconds` are empty (unless the date filter needed the date) and `viewCount` is read from the rounded text.
- **The date filter** keeps the videos published after its date, by their exact date when the one YouTube shows ("3 days ago") cannot tell. The Videos and Shorts tabs list videos newest first, so a tab stops at its first older video. The Live tab lists live streams first and past ones only roughly by date, and a playlist keeps its owner's order: both are read to their end or to your limit.
- **A video link entered as a watch link is typed `video`** even when it is a Short; paste Shorts as `/shorts/` links to get `short`.
- **Members-only videos have no view count**: YouTube shows it to members only.
- A channel without the tab you asked for (no Shorts, no live streams) gives no videos for that tab, with no per-item charge.

### FAQ

**Do I need a YouTube API key?** No. There is no quota either.

**How many videos can I get from a channel?** Up to 5,000 per tab and per run. Raise `maxResults` and the scraper keeps going through the channel's history.

**How do I monitor channels every day?** Schedule the Actor daily with **Published after** set to `2 days` (or weekly with `9 days`), and de-duplicate on `videoId` where you keep the rows. The margin covers a run that starts late or a video that YouTube dates near the boundary; a run that restarts keeps the cutoff of its first start. `24 hours`, `2 weeks` and `3 months` work too.

**Can I get transcripts?** Yes, with [YouTube Transcript Scraper (Low-Cost)](https://apify.com/sones/youtube-transcript-scraper-lowcost): paste the video links this Actor gives you.

**Why is a channel "not found"?** The handle or link does not lead to a channel on YouTube. Check it in your browser.

**What if a channel cannot be scraped?** It is reported in the run's status and `RUN_SUMMARY`. Run it again later; you pay only for the videos you got, and the run start.

### Legal

This Actor collects public information that YouTube shows to anyone without signing in. You are responsible for how you use the data: check that your use is lawful in your country and complies with YouTube's Terms of Service, and handle any personal data according to the laws that apply to you (such as the GDPR). Read Apify's article on [whether web scraping is legal](https://blog.apify.com/is-web-scraping-legal/).

# Actor input Schema

## `urls` (type: `array`):

Channel links (https://www.youtube.com/@mkbhd, /channel/UC…, /c/… or /user/… links, or just @mkbhd), playlist links or ids (PL…), and video links or ids. A channel gives its latest videos, a link to one of its tabs (https://www.youtube.com/@mkbhd/shorts) that tab's, a playlist its videos, a video link that one video.

## `contentTypes` (type: `array`):

Which of each channel's tabs to scrape: Videos, Shorts, Live (past and current live streams). Channel links that name a tab (https://www.youtube.com/@mkbhd/shorts), playlists and video links are not affected.

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

The most videos to get from each channel tab and each playlist, in the order YouTube lists them: newest first on the Videos and Shorts tabs. A video link always gives one video.

## `newerThan` (type: `string`):

Only get videos published after this date. Accepts a date such as 2026-01-01, a date and time such as 2026-01-01T12:00:00Z, a time before the run starts such as 7 days, 24 hours, 2 weeks or 3 months, or a Unix timestamp. Leave empty for all videos.

## `exactDetails` (type: `boolean`):

Get each video's exact publish date and exact view count. Turn off for a faster run where dates read as YouTube shows them ("3 days ago") and view counts are rounded ("1.2M views").

## `proxy` (type: `object`):

Leave on automatic. To send every request through your own proxies instead, choose 'Own proxies' and enter their URLs.

## Actor input object example

```json
{
  "urls": [
    "https://www.youtube.com/@mkbhd",
    "@veritasium",
    "https://www.youtube.com/playlist?list=PLAqhIrjkxbuWI23v9cThsA9GvCAUhRvKZ",
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "contentTypes": [
    "videos"
  ],
  "maxResults": 10,
  "newerThan": "7 days",
  "exactDetails": true,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# 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 = {
    "urls": [
        "https://www.youtube.com/@mkbhd"
    ],
    "maxResults": 10,
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("sones/youtube-scraper-lowcost").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 = {
    "urls": ["https://www.youtube.com/@mkbhd"],
    "maxResults": 10,
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("sones/youtube-scraper-lowcost").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 '{
  "urls": [
    "https://www.youtube.com/@mkbhd"
  ],
  "maxResults": 10,
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call sones/youtube-scraper-lowcost --silent --output-dataset

```

## MCP server setup

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

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/I83SNZKKMseCM8qwR/builds/eQqn582QRVg3jDhmS/openapi.json
