# YouTube Search Scraper - Videos, Shorts & Channels (`cheapapi/youtube-search-scraper`) Actor

YouTube search scraper: videos, Shorts, channels and playlists with views, duration, publish date, channel and position. Any country and language.

- **URL**: https://apify.com/cheapapi/youtube-search-scraper.md
- **Developed by:** [CheapAPI](https://apify.com/cheapapi) (community)
- **Categories:** Videos, Social media, SEO tools
- **Stats:** 5 total users, 5 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event + usage

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 Search Scraper - Videos, Shorts & Channels

Get YouTube search results for any keyword, country and language: every video, Short, channel, playlist, movie and sponsored video, with title, URL, channel, views, duration, publish date, thumbnail, badges and position. One clean row per result.

**Why this Actor**

- **$0.35 per 1,000 results on every Apify plan**, including Free. No start fee and no speed surcharge. Apify platform usage is billed separately by Apify (usually $0.001–$0.005 for a small run). A small page minimum applies only when a page yields fewer than 8 results (see [Pricing](#pricing)).
- **Many keywords in one run**: 1 or 1,000 search terms, each with up to 700 results, all at the same per-result price.
- **40 fields per result** (44 with rank tracking on), including a stable `id`, the exact position, view count, duration in seconds, the channel's ID and URL, and whether the result is a Short, live stream, movie or sponsored video.
- **Every YouTube filter**: sort order, upload date, type, duration, and features such as 4K, live, subtitles and Creative Commons. You can also paste YouTube search URLs.
- **Localized results**: 240+ countries, a single city or region, 90+ interface languages, and desktop or mobile.
- **Rank and new-video tracking**: turn on **Compare with last run** and every row says whether it is new and how many places it moved since the previous run, at no extra cost.
- **Not included**: like counts, comment counts and subscriber counts. They are not on the search page, so you need a separate YouTube video or channel details Actor for them; we do not offer one. Transcripts and comments are available from our separate Actors (see [Not included](#not-included)).

#### Compared with alternatives

Typical job: **10 keywords × 100 results = 1,000 results**.

| | Price per 1,000 results | Typical job on a paid plan | Same job on the Free plan | Like / subscriber counts | Country + language targeting | Many keywords in one run |
|---|---|---|---|---|---|---|
| Most-used all-in-one YouTube Actor (~128,000 users) | $1.00–$4.00 by plan ($2.40–$3.00 on Starter to Business, $1.50 Platinum, $1.00 Diamond), plus $0.17–$1.30 per 1,000 for its channel date filter | $1.00–$3.00 | $4.00 | ✓ | ✗ | ✓ |
| Flat-price YouTube Actor (~30,000 users) | $0.50 on every paid plan | $0.50 | Demo mode only (its listing: 5 runs a month, up to 10 results each) | ✓ (likes) | ✓ | Up to 5 per run (its listing's terms) |
| Cheapest per-result YouTube search Actor (~3,000 users) | $0.25 on paid plans, $2.50 on Free, plus $0.01 start fee per run | $0.35 (10 runs: $0.25 + 10 × $0.01) | $2.60 (10 runs: 1,000 × $0.0025 + 10 × $0.01) | Partly (deeper detail levels) | ✓ | ✗ (one search term per run) |
| **This Actor** | **$0.35 on every plan, no start fee**, plus platform usage | **$0.35** + usage | **$0.35** + usage | ✗ (search page fields only) | ✓ (plus city, device) | ✓ |

Prices are the event fees from public Apify Store listings, checked September 2026. The Store data does not show whether the alternatives bill Apify platform usage on top, so the table compares event fees only. For this Actor, Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005), shown as "+ usage".

Where others are cheaper or do more:

- **The cheapest per-result Actor is cheaper on paid plans when each run has one keyword with more than 100 results.** For example, 1 keyword × 700 results costs $0.185 there and $0.245 here. With 100 results per keyword the event fees are the same ($0.35 for the typical job); with fewer (for example 10 keywords × 20 results: $0.15 there, $0.07 here) this Actor is cheaper. On the Free plan the typical job costs $0.35 plus platform usage here, against $4.00 and $2.60.
- **The all-in-one and flat-price Actors return like counts and more video details** in the same row. This Actor does not open video pages, so it returns only the search page fields and costs less than those two for the typical job ($0.35 plus platform usage, against $0.50 to $4.00).

#### One detail level: search results

This Actor has a single detail level: **everything the YouTube search results page shows** for each result (the 40 fields below). It does not open each video page, so there are no "basic / full" modes and no per-detail surcharges. When you need more about specific videos, pass the `url` or `videoId` fields to our separate Actors: [YouTube Comments Scraper](https://apify.com/cheapapi/youtube-comments-scraper) for comments and replies, and [YouTube Transcript Scraper](https://apify.com/cheapapi/youtube-transcript-scraper) for subtitles and transcripts. You pay for those only for the videos you choose.

#### Not included

| Not included | Why | Use instead |
|---|---|---|
| Like counts, comment counts, subscriber counts, tags, full descriptions | They are on the video or channel page, not on the search page | You need a separate YouTube video or channel details Actor; we do not offer one |
| Comments and replies | Separate page per video | [YouTube Comments Scraper](https://apify.com/cheapapi/youtube-comments-scraper) |
| Subtitles and transcripts | Separate data per video | [YouTube Transcript Scraper](https://apify.com/cheapapi/youtube-transcript-scraper) |
| Google web results for the same keyword | Different search engine | [Google SERP Scraper](https://apify.com/cheapapi/google-serp-scraper) |
| Google search volume of a keyword | Not shown on YouTube search pages | [Keyword Research Tool](https://apify.com/cheapapi/keyword-research-tool) |
| Video downloads, a channel's full upload list | Outside search results | Not covered |

### What data you get

| Field | Type | Example |
|---|---|---|
| `id` | string | `89533ce039f0ef20e094` (stable: same result for the same search = same id in every run) |
| `position` | integer | `1` (rank on the results page, all types counted) |
| `positionInType` | integer | `1` (rank among results of the same type) |
| `type` | string | `video`, `short`, `movie`, `sponsored`, `channel`, `playlist`, `other` |
| `title` | string | `The Complete SEO & AI SEO Course for 2026` |
| `url` | string | `https://www.youtube.com/watch?v=7DRO4rEIHDk` |
| `videoId` / `playlistId` | string | `7DRO4rEIHDk` / `PLxyz…` |
| `channelId`, `channelName`, `channelUrl`, `channelLogo` | string | `UCmW0I6tx3Co4B6T2euHj6iw`, `Surfer Academy and Matt Kenyon` |
| `channelVerified` | boolean | `true` (channel results) |
| `description` | string | snippet shown under the result |
| `highlightedWords` | array | `["SEO"]`, the words YouTube highlighted |
| `badges` | array | `["CC", "4K", "New"]` |
| `viewCount` | integer | `241622` |
| `publishedText` / `publishedAt` | string | `5 months ago` / `2026-04-24T23:08:13.000Z` (estimated) |
| `duration` / `durationSeconds` | string / integer | `50:46` / `3046` |
| `videoCount` | integer | number of videos (channels and playlists) |
| `thumbnailUrl` | string | `https://i.ytimg.com/vi/…/hq720.jpg` |
| `isLive`, `isShort`, `isMovie`, `isSponsored` | boolean | `false` |
| `previewVideos` | array | the first videos of a playlist (id, title, url, duration) |
| `section`, `sectionPosition` | string / integer | the shelf a result belongs to, if any |
| `searchTerm`, `searchUrl`, `country`, `location`, `language`, `device` | string | context of the search |
| `totalResultsEstimate` | integer | `8796486` |
| `spellingCorrection` | object | YouTube's "Showing results for …" correction, if any |
| `scrapedAt` | string | ISO timestamp |
| `extra` | object | fields YouTube added that are not mapped yet (only when present) |
| `isNew`, `firstSeenAt`, `previousPosition`, `positionChange` | boolean / string / integer | only with **Compare with last run**: `false`, `2026-09-01T…`, `8`, `5` (moved up 5 places) |

### How to use

1. Open the Actor in the Apify Console and click **Try for free**.
2. Enter one or more **Search terms**, one per line.
3. Choose **Max results per search** (default 20), the **Country** and the **Language**.
4. Optionally open the advanced sections to add YouTube filters, a city, a device or YouTube search URLs.
5. Click **Start**. The results appear in the **Output** tab. You can download them as JSON, CSV, Excel, XML, HTML or RSS.

Ready-to-paste input:

```json
{
    "searchTerms": ["lofi hip hop", "how to make sourdough bread"],
    "maxResultsPerSearch": 50,
    "country": "US",
    "language": "en",
    "uploadDate": "thisMonth",
    "resultType": "video"
}
```

#### API

cURL:

```bash
curl -X POST "https://api.apify.com/v2/acts/cheapapi~youtube-search-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchTerms":["lofi hip hop"],"maxResultsPerSearch":50,"country":"US","language":"en"}'
```

JavaScript (`apify-client`):

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

const client = new ApifyClient({ token: '<YOUR_TOKEN>' });
const run = await client.actor('cheapapi/youtube-search-scraper').call({
    searchTerms: ['lofi hip hop'],
    maxResultsPerSearch: 50,
    country: 'US',
    language: 'en',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Python (`apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("cheapapi/youtube-search-scraper").call(run_input={
    "searchTerms": ["lofi hip hop"],
    "maxResultsPerSearch": 50,
    "country": "US",
    "language": "en",
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["position"], item["title"], item["viewCount"])
```

### Use cases

- **YouTube SEO and rank tracking**: see where your videos and competitors' videos rank for your keywords in each country, and schedule the Actor to track changes over time.
- **Content research**: find which topics, formats (Shorts or long videos) and lengths win for a keyword, and how many views they get.
- **Influencer and channel discovery**: collect channels and creators that show up for niche searches.
- **Ad intelligence**: see which sponsored videos appear for your keywords.
- **Market and trend monitoring**: track new uploads for a topic with the "Upload date" filter.
- **Datasets for analytics and AI**: build clean, structured datasets of YouTube search results.

### Advanced options

| Option | Default | What it does |
|---|---|---|
| `sortBy` | `relevance` | YouTube sort order: `relevance`, `uploadDate`, `viewCount`, `rating`. |
| `uploadDate` | `any` | `lastHour`, `today`, `thisWeek`, `thisMonth`, `thisYear`. |
| `resultType` | `any` | YouTube's type filter: `video`, `channel`, `playlist`, `movie`. |
| `duration` | `any` | `under4Minutes`, `between4And20Minutes`, `over20Minutes`. |
| `features` | `[]` | Any of `live`, `fourK`, `hd`, `subtitles`, `creativeCommons`, `vr360`, `vr180`, `threeD`, `hdr`, `location`, `purchased`. |
| `searchUrls` | `[]` | YouTube search URLs (`https://www.youtube.com/results?search_query=…&sp=…`). The search term and filters are read from the URL. |
| `extraUrlParameters` | empty | Raw YouTube URL parameters for experts, e.g. `sp=EgIQAQ%253D%253D` (the `sp` value URL-encoded twice). This replaces all filters. |
| `includeTypes` | all | Which result types to keep in the output (`video`, `short`, `movie`, `sponsored`, `channel`, `playlist`, `other`). Dropped results are not charged; a page of 20 that keeps fewer than 8 results adds a $0.0028 `page-checked` fee. |
| `location` | empty | A city or region instead of the whole country, e.g. `Austin,Texas,United States`. |
| `languageName` | empty | A full language name for languages that are not in the list. This overrides Language. |
| `device` | `desktop` | `desktop` or `mobile`. |
| `operatingSystem` | `auto` | `windows` or `macos` (desktop), `android` or `ios` (mobile). |
| `processingSpeed` | `auto` | `auto`, `standard` (1–5 min), `fast` (about 1 min) or `instant` (seconds, up to 200 results). The price is the same at every speed. |
| `maxWaitMinutes` | `60` | Searches that have not finished after this time are reported; they were already submitted, so each pays its page minimum ($0.0028 per requested page of 20). Keep the default unless you need a hard stop. |
| `compareWithLastRun` | `false` | Remembers the results of each search between runs and adds `isNew`, `firstSeenAt`, `previousPosition` and `positionChange` to every row. No extra charge. |
| `monitorName` | empty | Keeps separate histories for different projects, e.g. `client-a`. |

### Monitoring: rank tracking and new videos

1. Turn on **Compare with last run** (optionally give it a **Monitor name**) and save the input as a task.
2. Add an Apify Schedule for the task, for example daily.
3. Each run compares every search with the previous run of the same search (same term, filters, country or city, language and device):
   - `positionChange` shows how many places a result moved (`+5` = moved up 5 places), and `previousPosition` its last position (`null` if it was not in the last run).
   - `isNew: true` marks results this search has never returned before. A video that drops out and comes back is not new again; `firstSeenAt` keeps the date it first appeared.
4. Open the **Changes since last run** view in the Output tab, or keep only rows with `isNew = true` in your Make, Zapier, n8n or Google Sheets step to get "only new videos since the last run".

Every row is still delivered and priced as usual, because rank tracking needs the positions of the results you already know. For the cheapest new-video alert, combine it with **Sort by: Upload date**, **Upload date: Today** and a small **Max results per search** (for example 20: $0.007 per keyword per run). History is kept per search for the 5,000 most recently seen results, in a named key-value store in your account (`youtube-search-monitor…`).

### Example output

One video result for the search term `seo` (US, English, desktop). To keep it short, fields that do not apply to a video (`playlistId`, `channelVerified`, `videoCount`, `previewVideos`), the shelf fields (`section`, `sectionPosition`) and the empty context fields (`location`, `spellingCorrection`) are left out here. In the dataset every row has every field, with `null` where it does not apply.

```json
{
    "id": "89533ce039f0ef20e094",
    "position": 1,
    "positionInType": 1,
    "type": "video",
    "title": "The Complete SEO & AI SEO Course for 2026 (Full Beginner’s Guide)",
    "url": "https://www.youtube.com/watch?v=7DRO4rEIHDk",
    "videoId": "7DRO4rEIHDk",
    "channelId": "UCmW0I6tx3Co4B6T2euHj6iw",
    "channelName": "Surfer Academy and Matt Kenyon",
    "channelUrl": "https://www.youtube.com/channel/UCmW0I6tx3Co4B6T2euHj6iw",
    "channelLogo": "https://yt3.ggpht.com/Bv-ZILjuT_wYllBIiy21S4bHSQqd3twvauDKxTr-AjP7TWSP29FZ2QUErta4PEAVg3hXqyYuxA=s68-c-k-c0x00ffffff-no-rj",
    "description": "Learn SEO in 2026 and rank on Google + AI search (ChatGPT, AI Overviews, and more). Full step-by-step tutorial + 30-day action ...",
    "highlightedWords": ["SEO"],
    "badges": ["CC"],
    "viewCount": 241622,
    "publishedText": "5 months ago",
    "publishedAt": "2026-04-24T23:08:13.000Z",
    "duration": "50:46",
    "durationSeconds": 3046,
    "thumbnailUrl": "https://i.ytimg.com/vi/7DRO4rEIHDk/hq720.jpg",
    "isLive": false,
    "isShort": false,
    "isMovie": false,
    "isSponsored": false,
    "searchTerm": "seo",
    "searchUrl": "https://www.youtube.com/results?search_query=seo",
    "country": "US",
    "language": "en",
    "device": "desktop",
    "totalResultsEstimate": 8796486,
    "scrapedAt": "2026-09-28T15:52:03.307Z"
}
```

A channel result uses the same fields, and the video-only fields are `null` there: `type: "channel"`, `title` and `channelName` hold the channel name, `url` and `channelUrl` hold its link, and `videoCount` and `channelVerified` are filled in.

### Pricing

Typical cost: **$0.35 per 1,000 results** on every plan (e.g. $0.007 for 1 keyword × 20 results), plus Apify platform usage, billed separately. Most runs pay only the `result` fee.

**Apify Free plan:** Apify does not pay developers for usage on its Free plan, so on the Free plan this Actor can be used for up to **$0.25 of results per calendar month** — enough to try it on a small input. When the allowance is used up, the run ends with a clear message (not an error). Any paid Apify plan removes the limit; prices are the same.

This Actor uses pay-per-event pricing, the same on every Apify plan (Free, Starter, Scale, Business and above). Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005); the prices and examples below are event fees only. There is no start fee and no speed surcharge.

| Event | Price (all plans) | When |
|---|---|---|
| `result` | **$0.00035** ($0.35 per 1,000) | Each result delivered to your dataset |
| `page-checked` | $0.0028 | Only for a fetched page of up to 20 results that delivered too few results to pay for itself |

**What `page-checked` is.** Results are fetched in pages of 20, and each fetched page costs us money even when it brings back little. So every fetched page of a search must bring in at least $0.0028. Every 8 delivered results of that search cover one page (8 × $0.00035 = $0.0028); each page that is not covered adds one `page-checked`. A normal search delivers about 20 results per page and never pays it. It appears only when YouTube has fewer than 8 results, a search returns no data, or **Result types to keep** (`includeTypes`) drops most rows. Searches rejected as invalid input are free.

**The wait rule.** A search still waiting when **Maximum wait** (`maxWaitMinutes`, default 60) runs out was already submitted, so it pays `page-checked` for every page requested and delivers nothing. The same applies to a search whose submission got no answer because of a network problem.

| Search | Pages | Results delivered | Pages covered (results ÷ 8, rounded down) | `page-checked` | Total |
|---|---|---|---|---|---|
| 1 keyword × 20 results | 1 | 20 | 1 (all) | 0 | 20 × $0.00035 = **$0.007** |
| 10 keywords × 100 results | 5 each | 1,000 | all | 0 | **$0.35** |
| 1 keyword × 20, keeping only playlists (2 on the page) | 1 | 2 | 0 | 1 | $0.0007 + $0.0028 = **$0.0035** |
| 1 keyword with no results on YouTube | 1 | 0 | 0 | 1 | **$0.0028** |
| 1 keyword × 100, keeping only channels (12 found) | 5 | 12 | 1 | 4 | $0.0042 + $0.0112 = **$0.0154** |
| 1 keyword × 100, still waiting when Maximum wait ends | 5 requested | 0 | 0 | 5 | **$0.014** |

Set **Maximum cost per run** in the run options to cap your spend. The Actor only collects what that limit can pay for, including any page minimums, so fees never push a run over the limit. For example, a $0.05 limit covers 142 results, so with 3 searches of 100 results it collects the first search in full and 42 results of the second, and skips the third. The run summary shows how many searches were skipped.

### Integrations

- **Scheduling**: run the Actor daily or weekly with Apify Schedules to track rankings over time.
- **Webhooks**: get notified or trigger your own pipeline when a run finishes.
- **Make, Zapier, n8n**: use the Apify apps to send results to any tool.
- **Google Sheets, Airtable, Slack**: export the dataset directly, or through the integrations tab.
- **API**: use the REST API or the official JavaScript and Python clients (see above).

### FAQ

**Is there a limit on the Apify Free plan?** Yes: up to $0.25 of this Actor's results per calendar month, enough to try it. Apify pays developers nothing for Free-plan usage while our data costs are real, so this keeps the Actor sustainable. Runs that reach the allowance stop cleanly and keep everything collected so far; the allowance resets on the 1st of the month. Any paid Apify plan has no limit.

**Is it legal to scrape YouTube search results?**
This Actor collects only publicly visible search results. It does not collect private data or log into any account, and you don't need a YouTube API key, a login or a proxy. You are responsible for using the data in line with applicable laws, such as GDPR, and YouTube's terms. If you are unsure, ask a lawyer.

**Is Apify platform usage included?**
No. Apify platform usage (compute) is billed separately by Apify, on top of the event fees. At the default 256 MB memory a small run typically uses about $0.001–$0.005; long runs with many keywords use more. Each run's usage is shown in Apify Console.

**How fresh is the data?**
Every search is run live when you start the Actor, so you get the results YouTube shows at that moment.

**Why did I get fewer results than I asked for?**
YouTube sometimes shows fewer results for niche searches or narrow filters. Results you exclude with "Result types to keep" also count towards the limit. You are charged for the rows delivered, plus the page minimum for pages that delivered fewer than 8 results. The run summary (`RUN_SUMMARY` in the key-value store) lists every search with a problem.

**Why was I charged `page-checked`?**
A page of 20 results was fetched for one of your searches but delivered fewer than 8 results — YouTube had few or no results, the search returned no data, or "Result types to keep" dropped the rest. Each such page costs $0.0028; every 8 delivered results of the search cover one page. `RUN_SUMMARY` shows `pagesChecked`. To get many results of one type without the fee, use the **Result type** search filter instead of "Result types to keep".

**How do I get only Shorts or only channels?**
For channels or playlists, set "Result type" to that type, and YouTube fills every page with it. For Shorts, keep only `short` in "Result types to keep". Shorts are mixed into normal results, so you may get fewer of them.

**Can I get full video details, comments or transcripts?**
This Actor returns what the YouTube search page shows. It does not collect like counts, comments or transcripts. For those, feed the `url` or `videoId` fields into our [YouTube Comments Scraper](https://apify.com/cheapapi/youtube-comments-scraper) or [YouTube Transcript Scraper](https://apify.com/cheapapi/youtube-transcript-scraper).

**How do I control my spending?**
Set **Maximum cost per run** in the run options. The Actor works out how many results that limit pays for before it starts, requests only those, and stops delivering once the limit is reached. You are never charged beyond it.

**Can I schedule it to monitor rankings or get only new videos?**
Yes. Turn on **Compare with last run** and schedule the Actor (for example daily). Every row gets `positionChange`, `previousPosition` and `isNew`; keep rows with `isNew = true` to get only the videos that are new since the last run. See [Monitoring](#monitoring-rank-tracking-and-new-videos). The stable `id` also lets you join runs in your own database.

**Does it collect personal data?**
It collects only what anyone can see on a public YouTube search page: video titles, public channel names, channel IDs and channel links. It does not collect viewer data, email addresses, comments or anything behind a login. If you store or process channel names, make sure your use complies with GDPR and similar laws.

**How do I get help or request a feature?**
Open an issue on the Actor's **Issues** tab in the Apify Console. We read every issue and fix reported problems quickly.

### Limitations

- At most 700 results per search (200 with Instant processing), in YouTube's order. At least 10 results are requested per search.
- `publishedAt` is an estimate based on YouTube's relative date text.
- Some sort options, such as rating, are sometimes ignored or reinterpreted by YouTube.
- The fields depend on what YouTube shows. For example, channels have no view count, and live streams have no duration.
- Like counts, comments, subscriber counts and transcripts are not included (see [Not included](#not-included)).
- **Compare with last run** compares runs with the same search settings; changing the search term, filters, country or city, language or device starts a new history for that search.

# Actor input Schema

## `searchTerms` (type: `array`):

What you would type into the YouTube search box, one per line. Each search term is collected separately. Required, unless you paste YouTube search URLs in the advanced section instead.

## `maxResultsPerSearch` (type: `integer`):

How many results (videos, Shorts, channels, playlists) to collect for every search term, in YouTube's order. You pay for results delivered; a page of 20 that delivers fewer than 8 results (e.g. no results on YouTube) adds a $0.0028 page-checked fee. Up to 700 (up to 200 with Instant processing).

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

YouTube results as seen by a viewer in this country. For a specific city or region, use the advanced location option.

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

Interface language of YouTube (affects localized titles, relative dates and ranking).

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

YouTube's own sort order. YouTube sometimes ignores or reinterprets a sort option; relevance is always supported.

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

Only results uploaded within this period (YouTube's upload-date filter).

## `resultType` (type: `string`):

YouTube's type filter. Use it (rather than “Result types to keep”) when you want many results of one type, because YouTube then fills every page with that type.

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

YouTube's video length filter.

## `features` (type: `array`):

Only results with all of these features (YouTube's feature filters).

## `searchUrls` (type: `array`):

Instead of (or in addition to) search terms, paste YouTube search URLs such as <code>https://www.youtube.com/results?search_query=lofi\&sp=EgIQAQ%3D%3D</code>. The search term and any filters in the URL (<code>sp</code>) are used; filters from the URL win over the filter options above.

## `extraUrlParameters` (type: `string`):

For experts: raw parameters added to the YouTube search URL, e.g. <code>sp=EgIQAQ%253D%253D</code> (the <code>sp</code> value URL-encoded twice). Replaces all filter options above and the filters from search URLs.

## `includeTypes` (type: `array`):

Drop result types you do not need from the output. Dropped results are not charged, but they still count towards “Max results per search” — to get many results of one type, use the “Result type” filter instead. A fetched page of 20 that keeps fewer than 8 results adds a $0.0028 page-checked fee (every 8 delivered results of a search cover one page).

## `location` (type: `string`):

Search from a specific place instead of the whole country, written as <code>City,Region,Country</code>, e.g. <code>Austin,Texas,United States</code>. Overrides Country.

## `languageName` (type: `string`):

Optional full language name (e.g. <code>Portuguese (Brazil)</code>) for languages that are not in the Language list. Overrides Language.

## `device` (type: `string`):

Collect the results a desktop or a mobile visitor sees.

## `operatingSystem` (type: `string`):

Operating system of the simulated browser. Must match the device.

## `processingSpeed` (type: `string`):

How quickly searches are collected. The price per result is the same at every speed.

## `maxWaitMinutes` (type: `integer`):

Searches not finished after this time are reported in the run summary. They were already submitted, so each pays the page minimum ($0.0028 per requested page of 20 results, page-checked). Keep the default unless you need a hard stop.

## `compareWithLastRun` (type: `boolean`):

Remembers which results each search returned in earlier runs and adds isNew, firstSeenAt, previousPosition and positionChange to every row. Use it with a schedule to track rankings or to pick out new videos. Every row is still delivered and priced as usual; there is no extra charge.

## `monitorName` (type: `string`):

Optional. Keeps separate histories for different projects (for example "client-a"). Runs with the same monitor name and the same search settings are compared with each other. Letters, digits and hyphens; up to 40 characters.

## Actor input object example

```json
{
  "searchTerms": [
    "lofi hip hop",
    "how to make sourdough bread"
  ],
  "maxResultsPerSearch": 20,
  "country": "US",
  "language": "en",
  "sortBy": "relevance",
  "uploadDate": "any",
  "resultType": "any",
  "duration": "any",
  "features": [],
  "includeTypes": [
    "video",
    "short",
    "movie",
    "sponsored",
    "channel",
    "playlist",
    "other"
  ],
  "device": "desktop",
  "operatingSystem": "auto",
  "processingSpeed": "auto",
  "maxWaitMinutes": 60,
  "compareWithLastRun": false
}
```

# Actor output Schema

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

No description

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

No description

## `channels` (type: `string`):

No description

## `changes` (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 = {
    "searchTerms": [
        "lofi hip hop",
        "how to make sourdough bread"
    ],
    "maxResultsPerSearch": 20,
    "country": "US",
    "language": "en"
};

// Run the Actor and wait for it to finish
const run = await client.actor("cheapapi/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 = {
    "searchTerms": [
        "lofi hip hop",
        "how to make sourdough bread",
    ],
    "maxResultsPerSearch": 20,
    "country": "US",
    "language": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("cheapapi/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 '{
  "searchTerms": [
    "lofi hip hop",
    "how to make sourdough bread"
  ],
  "maxResultsPerSearch": 20,
  "country": "US",
  "language": "en"
}' |
apify call cheapapi/youtube-search-scraper --silent --output-dataset

```

## MCP server setup

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