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

YouTube search API–style keyword scraper on Apify: run queries with optional country/lang, get first-page video hits (IDs, titles, channels, views) without burning official Data API quota.

- **URL**: https://apify.com/scrapemamba/youtube-search-scraper.md
- **Developed by:** [Scrape Mamba](https://apify.com/scrapemamba) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

**YouTube Search Scraper** is an Apify Actor for **YouTube search API**–style keyword discovery: pass one or many queries and get structured first-page video rows (IDs, titles, channels, views, thumbnails) you can schedule, export, and join. Built by **ScrapeMamba**, this **apify youtube scraper** wraps ScrapeMamba’s `POST /youtube/search` endpoint so teams that want to **scrape YouTube** search listings — or run a **youtube keyword scraper** — do not maintain HTML parsers or a browser farm. Use it as a suite **youtube scraper** when workflows start from phrases instead of hand-picked IDs.

Actor URL: <https://apify.com/scrapemamba/youtube-search-scraper>

Pricing on Apify: **$2.30 per 1,000 results** (billed for successful Dataset rows).

This Actor is the discovery step of the ScrapeMamba YouTube suite. Seed catalogs with keywords, then enrich with **YouTube Video Scraper**, expand graphs with **YouTube Related Videos Scraper**, or snapshot charts with **YouTube Trending Scraper**.

***

### Overview

Search powers topic monitoring, competitive coverage, content ideation, creator lead lists, and warehouse seed tables. Many teams looking for a **YouTube search API** want keywords → video IDs without building scrapers. Google’s official **YouTube Data API** `search.list` can do that — with Cloud project setup, API keys or OAuth, daily quotas, and a Google-shaped JSON contract.

This Actor is a different path: an Apify-native **youtube scraper** that calls ScrapeMamba’s search surface, maps public SERP-style listings into a stable schema, and parallelizes queries for research and monitoring pipelines. It is not a drop-in clone of Google’s Search API; it is practical when you need first-page public hits in JSON/CSV on a schedule.

**Behavioral fact:** the endpoint is **`/youtube/search`**, and this Actor fetches the **first search page only**. There is no continuation / infinite-scroll path. If a next-page token would be required, the Actor short-circuits. Cap volume with `maxResults` (default `"50"`, range **1–500**); you will not get an unbounded SERP crawl from one query.

Under the hood:

1. `queries` is validated as a non-empty string list.
2. Optional `country` is normalized (default **`US`**); optional `lang` is passed when set.
3. Up to **8 workers** process queries concurrently.
4. Each query calls `POST /youtube/search` with `{ query, country, lang }`.
5. Items without a mappable `videoId` are filtered out.
6. Success rows are `type: "video"` with `query`, `page`, mapped fields, and `raw`.
7. Per-query failures are `type: "error"` with `query` and `error` so one bad term does not kill the run.

***

### YouTube Data API search vs this Actor

| Dimension | Official YouTube Data API `search.list` | This Actor (ScrapeMamba on Apify) |
|-----------|------------------------------------------|-----------------------------------|
| Quotas | Daily unit quotas; search is relatively expensive | Apify result pricing + ScrapeMamba usage |
| Orchestration | Your code, jobs, and storage | Apify Input, Dataset, schedules, webhooks |
| Pagination | `pageToken` / multi-page when quota allows | **First page only** (by design) |
| Output | Google JSON as returned | Mapped Apify Dataset rows + `raw` |
| Locale | `regionCode` / `relevanceLanguage` | Input `country` / `lang` (default `US`) |
| Best when | Contractual Search API semantics matter | Keyword → ID lists inside Apify pipelines |

Choose the official API for Google SLAs and multi-page `pageToken` crawls. Choose this Actor for a **youtube scraper api** workflow on Apify: keywords in, Dataset out, no browser ops.

***

### Who this is for

- Teams building a **youtube keyword scraper** for monitoring, ideation, or CRM seeding
- Analysts who need first-page public search snapshots by country
- Pipelines that already use Apify and need discovery upstream of Video / Related / Subtitles

### Who this is not for

- Anyone seeking a **YouTube video downloader** — this Actor extracts **metadata and listing text**, not media files
- Products that require page 2+ of YouTube search from a single query
- Workflows that need official Google Search API contractual semantics and multi-page pagination

***

### What it does

- Runs one or many search keywords in a single Actor run
- Optional **country** (ISO, default `US`) and **language** targeting
- Caps results per query with `maxResults` (1–500, default 50)
- Emits structured listing fields plus the originating `query`
- Keeps the original API item under `raw`
- Records per-query errors as Dataset rows
- Parallelizes across up to **8** workers

***

### Use cases

**Topic and brand monitoring** — Schedule product names, brand aliases, and competitor keywords. Diff exports for new `videoId`s; enrich hits with Video Scraper.

**Catalog and CRM seeding** — Produce keyword → ID lists, then hydrate with Video Scraper and optional Subtitles. Keep `maxResults` modest until you know keyword noise.

**Competitive locale coverage** — Same queries with different `country` values (`US`, `GB`, `IN`). Do not assume one market’s first page matches another.

**Agent and automation pipelines** — Call via the Apify API with a dynamic `queries` array, then chain Video / Related / Subtitles. Per-query `type: "error"` rows keep partial success easy.

**Editorial sampling** — Snapshot what currently ranks for a phrase. This is a **first-page snapshot**, not a historical search archive.

***

### What data can it extract?

| Field | Description |
|-------|-------------|
| `type` | `"video"` on success; `"error"` on failure |
| `query` | Search term that produced the row |
| `page` | Page index (first page in practice) |
| `videoId` | Canonical 11-character video ID |
| `title` | Video title |
| `author` | Channel / uploader display name |
| `channelId` | Channel ID when present |
| `views` | View count or view text when available |
| `length` | Duration string when available |
| `publishedTime` | Publish label when present |
| `description` / `text` | Short snippet (often truncated) |
| `thumbnail` | Preview image URL |
| `url` | Watch URL |
| `isShort` | Hint when the listing is a Short |
| `raw` | Original item payload |
| `error` | Present on `type: "error"` rows |

Null fields are normal when listings omit stats. Join on `videoId`.

***

### Input

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `queries` | `string[]` | **Yes** | — | Search keywords |
| `country` | `string` | No | `"US"` | ISO country code |
| `lang` | `string` | No | — | Optional UI language (e.g. `en`) |
| `maxResults` | `string` / number | No | `"50"` | Max results **per query**, clamped **1–500** |

Console prefill: `queries` = `nodejs`, `machine learning`; `country` / `maxResults` = `US` / `50`; optional `lang` = `en`.

```json
{
  "queries": ["nodejs", "machine learning"],
  "country": "US",
  "lang": "en",
  "maxResults": "50"
}
```

**Tips:** Prefer focused phrases. Dedupe duplicate queries. `maxResults` is per query (ten × 50 ≈ 500 video rows). `country` alone is often enough for locale ranking.

***

### Output

Success rows use **`type: "video"`** with `query`, `page`, mapped fields, and `raw`. Failures:

```json
{
  "type": "error",
  "query": "some keyword",
  "error": "HTTP 500: Upstream request failed after retries"
}
```

#### Success example

```json
{
  "type": "video",
  "query": "nodejs",
  "page": 1,
  "videoId": "abc123xyz12",
  "title": "Node.js Crash Course",
  "author": "Dev Channel",
  "channelId": "UCxxxxxxxxxxxxxxxxxxxxxx",
  "views": 89000,
  "length": "12:34",
  "publishedTime": "2 years ago",
  "thumbnail": "https://i.ytimg.com/vi/abc123xyz12/hqdefault.jpg",
  "url": "https://www.youtube.com/watch?v=abc123xyz12",
  "raw": { }
}
```

Treat `videoId` as the join key; `views` / `publishedTime` formats vary by listing.

***

### How to run on Apify Console

1. Open **[YouTube Search Scraper](https://apify.com/scrapemamba/youtube-search-scraper)**.
2. Edit Input `queries`, `country` (default `US`), optional `lang`, and `maxResults` (default `50`).
3. Smoke-test with 1–2 queries and `maxResults` of `10`–`20`.
4. Start the run; open the Dataset; export JSON / CSV / Excel.
5. Filter `type: "error"` before joining on `videoId`.
6. Save as a task + schedule, or call via the Apify API.

**Checklist:** one known keyword → confirm `videoId` / `title` / `query` → scale and schedule.

***

### Apify API example

```bash
curl "https://api.apify.com/v2/acts/scrapemamba~youtube-search-scraper/runs" \
  -H "Content-Type: application/json" \
  -d '{
    "queries": ["nodejs", "machine learning"],
    "country": "US",
    "lang": "en",
    "maxResults": "50"
  }'
```

```bash
curl "https://api.apify.com/v2/actor-runs/RUN_ID/dataset/items"
```

Apify Client SDKs (JS/Python) accept the same Input. Webhooks can trigger enrichment when a run succeeds.

***

### Pricing

- **$2.30 / 1,000 results** on this Apify listing
- ScrapeMamba usage is separate from Apify compute

Rough estimate: `(video rows) / 1000 × $2.30`. `maxResults` is per query; errors and thin pages change row counts.

***

### Errors and status handling

Retries on **429 / 500 / 502 / 503 / 504** (up to 3 attempts, delays 2s / 5s / 10s); **60s** timeout.

| Situation | Behavior |
|-----------|----------|
| Empty / invalid `queries` | Exit code `1` |
| HTTP failures after retries | Per-query `type: "error"` row |
| Items without `videoId` | Skipped |
| Partial query failures | Other queries continue |

Inspect logs and Dataset `type: "error"` rows when some keywords are missing.

***

### Best practices

1. Validate with 1–2 queries before large batches.
2. Do not design products that need page 2+ from this Actor — refine queries or use other Actors.
3. Set `country` intentionally when comparing markets.
4. Cap `maxResults` realistically; 500 does not invent a second page.
5. Dedupe `videoId` across related keywords.
6. Chain Search → Video / Related / Trending as needed.
7. Daily snapshots usually beat constant live crawling for monitoring.
8. Public data only.
9. Prefer mapped fields in warehouses; use `raw` for schema debugging.

***

### Limitations

- **First search page only** — no infinite scroll / continuation
- Result count bounded by first-page yield and `maxResults`
- Ranking and fields vary by `country` / `lang` and YouTube UI changes
- Not a substitute for official Data API contractual Search semantics
- Public listings only; **not a media downloader**

***

### Troubleshooting

| Symptom | What to try |
|---------|-------------|
| Immediate failure, no rows | Ensure `queries` is a non-empty string list |
| Fewer rows than `maxResults` | Expected for first-page search / filtered items |
| Wrong language or creators | Set `country` / `lang` explicitly |
| Need deeper pagination | Not supported — split queries or change strategy |
| Duplicates across queries | Dedupe on `videoId` in ETL |
| Intermittent 5xx | Client retries; inspect that query’s error row |

***

### FAQ

#### Is this a YouTube search API for keywords?

Functionally for many pipelines, yes: pass keywords (`queries`) and receive structured hits. Technically it is ScrapeMamba’s `/youtube/search` on Apify — not Google’s official `search.list`.

#### YouTube API search by keyword vs this Actor — which should I use?

Use **Google’s YouTube Data API** for official quotas, multi-page `pageToken` search, and Google’s contractual response. Use **this Actor** for Apify Datasets, schedules, and first-page public keyword discovery without managing Google Cloud quotas yourself.

#### Does it scrape only the first page of YouTube search?

**Yes.** Intentional limitation — no infinite-scroll or continuation. `maxResults` only caps first-page items (1–500). Design around refined queries and schedules, not deep SERP crawls.

#### How do I scrape YouTube search results on Apify?

Pass `queries`, optionally set `country` / `lang` / `maxResults`, start the run, export the Dataset or pull via Apify API / Client.

#### Can I use this as a youtube keyword scraper for monitoring?

Yes. Save a keyword list as a task, schedule it, and diff `videoId` sets over time. Keep `maxResults` modest and dedupe across queries.

#### Is this a YouTube video downloader?

No. Listing **metadata** only (IDs, titles, channels, stats text, thumbnails) — not video or audio files.

#### Defaults and parallelism?

`maxResults` defaults to `"50"` (1–500 per query). `country` defaults to `US`. Up to **8** workers. `queries` is required.

#### Can I pass channel URLs as queries?

No — use search **keywords**. Channel uploads → **Channel Videos Scraper**; single-video metadata → **Video Scraper**.

#### How do I enrich hits / how is this different from Trending?

Enrich distinct `videoId`s with **[YouTube Video Scraper](https://apify.com/scrapemamba/youtube-video-scraper)**. Search is keyword-driven; **Trending Scraper** snapshots charts without search terms.

#### Can I call this from Python?

Yes — Apify Client for Python with the same Input. The Actor runtime is JS on Apify; your client can be Python, Node, or curl.

#### Is private or age-gated content supported?

No. Public data only.

***

### Pipeline patterns

**Keyword → enrich:** Search → dedupe `videoId` → Video Scraper → optional Subtitles / Related.

**Locale comparison:** Same `queries`, different `country` tasks; compare which IDs appear per market.

**Monitoring:** Schedule a fixed keyword set; store Datasets by date; alert on new `videoId`s.

***

### Export and automation

Dataset download (JSON / CSV / Excel), Apify Dataset API, tasks + **schedules**, **webhooks** for enrichment, and integrations that consume Dataset URLs.

***

### Related ScrapeMamba Actors

| Actor | Best for |
|-------|----------|
| [YouTube Video Scraper](https://apify.com/scrapemamba/youtube-video-scraper) | Enrich search hit IDs |
| [YouTube Trending Scraper](https://apify.com/scrapemamba/youtube-trending-scraper) | Charts instead of keywords |
| [YouTube Related Videos Scraper](https://apify.com/scrapemamba/youtube-related-videos-scraper) | Recommendation neighbors from a hero video |

Also in the suite: Channel, Channel Videos, Channel Shorts, Subtitles.

***

### Compliance note

Use only on **public** YouTube search listings, in line with YouTube’s terms, applicable law, and your policies. Do not scrape private or login-walled content. You remain responsible for lawful use of collected data.

# Actor input Schema

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

Search keywords.

## `country` (type: `string`):

Optional ISO country code (e.g. US, GB, IN).

## `lang` (type: `string`):

Optional UI language (e.g. en).

## `maxResults` (type: `string`):

Maximum results per query (1–500).

## Actor input object example

```json
{
  "queries": [
    "nodejs",
    "machine learning"
  ],
  "country": "US",
  "lang": "en",
  "maxResults": "50"
}
```

# Actor output Schema

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

Default dataset items produced by this Actor.

# 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": [
        "nodejs",
        "machine learning"
    ],
    "country": "US",
    "lang": "en",
    "maxResults": "50"
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapemamba/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": [
        "nodejs",
        "machine learning",
    ],
    "country": "US",
    "lang": "en",
    "maxResults": "50",
}

# Run the Actor and wait for it to finish
run = client.actor("scrapemamba/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": [
    "nodejs",
    "machine learning"
  ],
  "country": "US",
  "lang": "en",
  "maxResults": "50"
}' |
apify call scrapemamba/youtube-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapemamba/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/4PgL0qDbJDMQdEbHr/builds/KxBNk4LHL2PblyFR9/openapi.json
