# YouTube Channel Videos Scraper (`outspoken_strategy/youtube-profile-posts-scraper`) Actor

Paste a YouTube channel URL (or @handle) and get that channel's videos for any period. Date filtering, multi-channel input, auto-pagination. Returns title, description, publish date, views, duration and thumbnail.

- **URL**: https://apify.com/outspoken\_strategy/youtube-profile-posts-scraper.md
- **Developed by:** [code craker](https://apify.com/outspoken_strategy) (community)
- **Categories:** Lead generation, Social media, Other
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $15.00 / 1,000 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?

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 Channel Videos Scraper

Paste a YouTube channel URL (or @handle) and get that channel's videos as structured data — title, description, approximate publish date, view count, duration and thumbnail. Supports several channels per run, a date range with early-stop pagination, and works without any login.

### Input

| Field | Description |
| --- | --- |
| `profileUrl` | One channel: `https://www.youtube.com/@nasa`, a `/channel/UC...` URL, a legacy `/c/` or `/user/` URL, an `@handle`, a bare handle, or a bare `UC...` id. Several channels can be pasted one per line. |
| `profileUrls` | Several channels as an array. `numberOfPosts` applies **per channel**. |
| `numberOfPosts` | Maximum videos to return per channel (default 100, up to 2000). |
| `scrapeAll` | Keep paginating until the target count, the date boundary, or the end of the channel (default on). |
| `timeSince` / `timeUntil` | Inclusive date range (`yyyy-mm-dd`, UTC). **Approximate** — channel pages only expose relative times ("3 weeks ago"). The actor stops paginating once the feed passes below `timeSince`. |
| `proxyConfiguration` | Defaults to Apify RESIDENTIAL proxy with US exits. |

The actor fetches with plain HTTP first (fast, cheap) and escalates to a real browser only when YouTube blocks the requests.

### Output

One dataset item per video:

```json
{
    "id": "dQw4w9WgXcQ",
    "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "title": "How We Are Going to the Moon",
    "description": "NASA is going back to the Moon...",
    "text": "How We Are Going to the Moon\n\nNASA is going back to the Moon...",
    "channelName": "NASA",
    "channelId": "UCLA_DiR1FfKNvjuUpBHmylQ",
    "channelUrl": "https://www.youtube.com/@NASA",
    "publishedTimeText": "3 weeks ago",
    "created_at": "2026-08-03T10:00:00.000Z",
    "viewCount": 1234567,
    "duration": "12:34",
    "durationSeconds": 754,
    "thumbnail": "https://i.ytimg.com/vi/...",
    "isLive": false,
    "profileHandle": "nasa",
    "profileUrl": "https://www.youtube.com/@NASA"
}
```

Items also carry normalized aliases (`author {name, id, profileUrl}`, `createdTime`, `viewsCount`) so they drop into pipelines built for our other scrapers.

### Notes

- Publish dates are derived from YouTube's relative times, so they get less precise the older the video ("2 years ago" spans months). For hard date cutoffs on recent content the accuracy is good (days/weeks granularity).
- A nonexistent or terminated channel is skipped with a warning instead of failing the run.
- Check `DEBUG_HTML` in the run's key-value store when a run returns nothing.

# Actor input Schema

## `profileUrl` (type: `string`):

The YouTube channel to scrape, e.g. https://www.youtube.com/@nasa. Also accepted: a /channel/UC... URL, a legacy /c/ or /user/ URL, an @handle, a bare handle, or a bare UC... channel id. You can paste several channels, one per line. For a clean list use "profileUrls" below instead.

## `profileUrls` (type: `array`):

Several channels to scrape — each is scraped separately and the results are combined. "Number of videos" applies PER channel.

## `numberOfPosts` (type: `integer`):

Maximum number of videos to return per channel (after date filtering).

## `scrapeAll` (type: `boolean`):

Keep paginating until the target count is reached, the date range is passed, or the channel runs out of videos. When unchecked only the first page (~30 videos) is returned.

## `timeSince` (type: `string`):

Only return videos published on or after this date (format: yyyy-mm-dd). Approximate — see the section note. The actor stops paginating once the feed passes below this date.

## `timeUntil` (type: `string`):

Only return videos published on or before this date (format: yyyy-mm-dd). Approximate — see the section note.

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

Proxy to route traffic through. RESIDENTIAL proxies with a country set are recommended; the actor first tries plain HTTP requests and escalates to a real browser only when YouTube blocks them.

## `headless` (type: `boolean`):

Applies only when the actor escalates to a real browser. Uncheck to run it headed (useful only for local debugging).

## Actor input object example

```json
{
  "profileUrl": "https://www.youtube.com/@nasa",
  "profileUrls": [],
  "numberOfPosts": 100,
  "scrapeAll": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  },
  "headless": true
}
```

# Actor output Schema

## `videos` (type: `string`):

The scraped videos as dataset items — one item per video, with title, description, channel, approximate publish date, view count, duration and thumbnail.

# 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 = {
    "profileUrl": "https://www.youtube.com/@nasa",
    "profileUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("outspoken_strategy/youtube-profile-posts-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 = {
    "profileUrl": "https://www.youtube.com/@nasa",
    "profileUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("outspoken_strategy/youtube-profile-posts-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 '{
  "profileUrl": "https://www.youtube.com/@nasa",
  "profileUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call outspoken_strategy/youtube-profile-posts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,outspoken_strategy/youtube-profile-posts-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/vcaxi91dvT4cncV6t/builds/pDkqHZOTaMF7ei1Xf/openapi.json
