# YouTube Search Scraper (`seasoned_seaurchin/youtube-search-scraper`) Actor

Scrape YouTube search results by keyword: video titles, channels, views, publish time, duration. Fast pure-fetch engine, no proxy needed.

- **URL**: https://apify.com/seasoned_seaurchin/youtube-search-scraper.md
- **Developed by:** [Z Michael](https://apify.com/seasoned_seaurchin) (community)
- **Categories:** Social media, Videos, SEO tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.20 / 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 Search Scraper

Scrape YouTube search results for any keyword and get a clean dataset of videos — title, channel, views, publish date, duration, thumbnail and URL.

Use it for keyword research, trend monitoring, content gap analysis, competitor tracking, or building video datasets for AI and RAG pipelines.

### What you get

- **Real search results, not estimates** — reads the same result list a person sees on youtube.com
- **Automatic pagination** — keeps loading more until it hits your limit or YouTube runs out of results
- **One row per video** — 10 fields, ready for Sheets, Airtable, Postgres or pandas
- **No API key, no proxy setup, no quota** — nothing to configure except your keywords

### Example output

```json
{
  "query": "ai coding tools",
  "videoId": "QucgvbO5gsM",
  "title": "Free AI Tools So Good They're Making Paid Versions Obsolete",
  "channel": "Vaibhav Sisinty",
  "channelId": "UClXAalunTPaX1YV185DWUeg",
  "views": "538,716 views",
  "publishedTime": "3 months ago",
  "duration": "18:34",
  "thumbnail": "https://i.ytimg.com/vi/QucgvbO5gsM/hqdefault.jpg",
  "url": "https://www.youtube.com/watch?v=QucgvbO5gsM"
}
```

### Use cases

- **Keyword research** — see what actually ranks for a term, with view counts as a proxy for demand
- **Content gap analysis** — compare your niche against what already performs
- **Trend monitoring** — run the same queries on a schedule and diff the results
- **Competitor tracking** — follow a rival's new uploads by searching their topic space
- **Dataset building** — collect video metadata at scale for models, dashboards or research

### Input

| Field | Type | Description |
|---|---|---|
| Search queries | array | One or more keywords. Each produces its own set of results. |
| Max videos per query | integer | 1–1,000. Default 50. |
| Content language | string | Interface language, e.g. `en`, `es`, `ja`. Default `en`. |

### Output fields

| Field | Example |
|---|---|
| query | ai coding tools |
| videoId | QucgvbO5gsM |
| title | Free AI Tools So Good They're Making Paid Versions Obsolete |
| channel | Vaibhav Sisinty |
| channelId | UClXAalunTPaX1YV185DWUeg |
| views | 538,716 views |
| publishedTime | 3 months ago |
| duration | 18:34 |
| thumbnail | https://i.ytimg.com/... |
| url | https://www.youtube.com/watch?v=... |

### Pricing

Pay per video found: **$0.0002 per video**.

- 100 videos ≈ **$0.02**
- 1,000 videos ≈ **$0.20**

You are only charged for videos actually delivered. If a query returns nothing, you pay nothing.

### FAQ

**Do I need a YouTube Data API key?**
No. There is nothing to register and no quota to request. Provide keywords and run.

**How many videos can I get per query?**
You can set a limit up to 1,000. The Actor paginates automatically and stops when it reaches your limit or YouTube stops returning results. For most keywords, that is 100–300 videos.

**Can I search multiple keywords in one run?**
Yes. Pass an array of queries; results are tagged with the `query` field so you can split them later.

**Does it include Shorts?**
Shorts appear in search results when YouTube returns them, and are included with their normal video fields.

**Can I filter by upload date or view count?**
The Actor returns YouTube's default relevance ordering with `publishedTime` and `views` as text fields. Filter or sort after the run using those fields; date-range filtering inside the request is not supported.

**Why do views and dates look like "538,716 views" and "3 months ago"?**
That is exactly how YouTube renders them. Parse to numbers if you need arithmetic.

**Does it work for non-English keywords?**
Yes. Set the content language field to match, e.g. `de`, `pt`, `ko`.

### Related Actors

- [YouTube Comments Scraper](https://apify.com/seasoned_seaurchin/youtube-comments-scraper) — pull comments and engagement for the videos you find here
- [YouTube Channel Videos Scraper](https://apify.com/seasoned_seaurchin/youtube-channel-videos-scraper) — list every upload from a specific channel
- [YouTube Transcript Scraper](https://apify.com/seasoned_seaurchin/youtube-transcript) — get full transcripts with timestamps

### Monitor Mode (daily incremental runs)

Set **Only new items = true** to turn this scraper into a monitor. It remembers what was already delivered for each query/video/channel and returns only **new items since the last run**.

How it works:

1. **First run** = baseline, returns everything
2. **Every run after** = returns only the delta (new comments / newly listed videos)
3. **No new data** = empty dataset, **you are not charged** (pay-per-result billing only fires on delivered items)
4. Combine with [Apify Schedules](https://docs.apify.com/schedule) to run it daily or hourly

Optional **Webhook URL**: whenever new items are found, the actor POSTs a JSON payload — `{event, source, newCount, scannedCount, sample, at}` — to your endpoint (Slack webhook, n8n, Make, your own API). Nothing is sent when there is no new data; failed deliveries never fail the run.

Typical use cases: track brand mentions in new YouTube comments, alert on newly published videos matching a keyword, watch a competitor channel for fresh uploads — without re-paying for data you already have.

# Actor input Schema

## `queries` (type: `array`):

Keywords to search on YouTube. Each query produces one set of results.

## `maxVideosPerQuery` (type: `integer`):

Maximum number of videos to collect for each query.

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

Preferred interface language for requests.

## `onlyNew` (type: `boolean`):

Incremental mode: remember what was already delivered (per query/video/channel) and output only NEW items since the last run. The first run returns everything (baseline); subsequent runs return only the delta. With no new items the run finishes with an empty dataset and you are not charged.

## `notifyWebhook` (type: `string`):

If set, a POST request with JSON {event, source, newCount, scannedCount, sample, at} is sent whenever new items are found. Nothing is sent when there is no new data. Failed deliveries are logged but never fail the run.

## Actor input object example

```json
{
  "queries": [
    "ai coding tools"
  ],
  "maxVideosPerQuery": 50,
  "language": "en",
  "onlyNew": false
}
```

# Actor output Schema

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

Videos matching the search queries.

# 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 = {
    "queries": [
        "ai coding tools"
    ],
    "maxVideosPerQuery": 50,
    "language": "en",
    "onlyNew": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("seasoned_seaurchin/youtube-search-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 = {
    "queries": ["ai coding tools"],
    "maxVideosPerQuery": 50,
    "language": "en",
    "onlyNew": False,
}

# Run the Actor and wait for it to finish
run = client.actor("seasoned_seaurchin/youtube-search-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 '{
  "queries": [
    "ai coding tools"
  ],
  "maxVideosPerQuery": 50,
  "language": "en",
  "onlyNew": false
}' |
apify call seasoned_seaurchin/youtube-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,seasoned_seaurchin/youtube-search-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/RKqRsijuV52QNe4e9/builds/yhc4L0vmi2AP7fASU/openapi.json
