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

Find YouTube videos, channels and Shorts by keyword. Export search ranks, descriptions, publish dates, views, likes, comment counts and creator data when available. Localize search by region and language. Export JSON or CSV. No YouTube API key. Unofficial; not affiliated with YouTube.

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

## Pricing

from $5.00 / 1,000 saved youtube search 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?

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 keyword search for videos, channels and Shorts

Find relevant YouTube content and creators without collecting an entire channel archive. Enter keywords, choose **Videos**, **Channels**, or **Shorts**, and export ranked results with available public details to JSON, CSV, or Excel.

Video and Shorts results include content metadata and a compact creator profile. Channel results include public profile details, statistics, branding, links, and email addresses when directly exposed. No YouTube Data API key or Google login is required.

**Start small:** the prefilled input requests up to 3 videos. At the default 512 MB memory, 3 saved results cost `$0.01505` in Actor events at the listed prices, with platform usage included. Optional fields depend on what YouTube exposes.

> Unofficial tool. Not affiliated with, endorsed by, or sponsored by YouTube or Google.

### Try it in three steps

1. Enter a topic in **Search keywords** and choose the **Result type**.
2. Keep **Maximum results per keyword** at 3 for your first run. The default search region is US and interface language is English.
3. Click **Start**, open the Dataset, and download JSON, CSV, or Excel.

Choose **Videos & Shorts** or **Channels** in the Output table to match your run. **Status & troubleshooting** explains query failures and unfinished details. These views present the same saved rows; switching views does not make more requests or change the raw JSON.

#### Ready-to-run examples

Each public example uses one keyword and up to 3 results:

- [Find YouTube videos by keyword and region](https://apify.com/arjun_code/youtube-search-scraper/examples/find-youtube-videos-by-keyword-and-region)
- [Find YouTube channels by keyword](https://apify.com/arjun_code/youtube-search-scraper/examples/find-youtube-channels-by-keyword)
- [Find YouTube Shorts by keyword](https://apify.com/arjun_code/youtube-search-scraper/examples/find-youtube-shorts-by-keyword)

#### Default video input

```json
{
  "searchQueries": ["AI automation"],
  "searchType": "videos",
  "maxResultsPerQuery": 3,
  "sortBy": "relevance",
  "uploadDate": "any",
  "duration": "any",
  "searchCountry": "US",
  "searchLanguage": "en"
}
```

For channels or Shorts, change only `searchType` to `channels` or `shorts`.

### What data will I get?

One run searches for one result type. Unrelated fields are omitted: channel rows do not contain empty video fields, and video or Shorts rows do not contain a full channel About profile.

| Result type | Public data available when exposed |
| --- | --- |
| `channel` | Channel name, ID, handle, description, subscribers, total views, video count, join date, country, avatar, banner, external links, and public emails |
| `video` | Video URL, title, description, thumbnail, publication time, duration, views, likes, comment count, tags, category, chapters, and basic channel identity |
| `short` | Native Shorts URL and the same content-detail fields, with basic channel identity |
| `searchStatus` | A free query-status row for no matches, failed discovery, or a maximum-charge stop |

#### Real channel output

Selected fields from a real public request on **October 18, 2026**, using the default input above with `searchType: "channels"`. Fields not shown here remain available in the full JSON.

```json
{
  "recordType": "channel",
  "detailStatus": "complete",
  "title": "Automate AI Consulting",
  "url": "https://www.youtube.com/@AutomateAIConsulting",
  "channelId": "UCgugjY9T1jv41UcKmaZ5NLQ",
  "channelName": "Automate AI Consulting",
  "channelHandle": "@AutomateAIConsulting",
  "subscriberCount": 26200,
  "subscriberCountText": "26.2K subscribers",
  "totalViewCount": 1823275,
  "videoCount": 421,
  "joinedDate": "2025-03-01",
  "channelCountry": "United States",
  "emails": ["collab@automateaiconsulting.com"],
  "searchQuery": "AI automation",
  "searchRank": 2,
  "searchCountry": "US",
  "searchLanguage": "en",
  "scrapedAt": "2026-10-18T06:17:33.122257Z"
}
```

#### Real video output

Selected fields from the same keyword and default video input, collected on **October 18, 2026**.

```json
{
  "recordType": "video",
  "detailStatus": "complete",
  "videoId": "5TxSqvPbnWw",
  "url": "https://www.youtube.com/watch?v=5TxSqvPbnWw",
  "title": "How to Build & Sell AI Automations: Ultimate Beginner’s Guide",
  "durationSeconds": 6622,
  "durationText": "1:50:22",
  "uploadDate": "2025-06-30",
  "publishedAt": "2025-06-30T23:27:23Z",
  "viewCount": 1234928,
  "viewCountText": "1,234,928 views",
  "likeCount": 35372,
  "commentCount": 2080,
  "categories": ["Education"],
  "channelProfile": {
    "channelId": "UCui4jxDaMb53Gdh-AZUTPAg",
    "channelName": "Liam Ottley",
    "channelHandle": "@LiamOttley",
    "channelUrl": "https://www.youtube.com/channel/UCui4jxDaMb53Gdh-AZUTPAg",
    "subscriberCount": 860000,
    "isVerified": true
  },
  "searchQuery": "AI automation",
  "searchRank": 1,
  "searchCountry": "US",
  "searchLanguage": "en",
  "scrapedAt": "2026-10-18T06:17:37.461137Z"
}
```

#### Real Shorts output

Selected fields from the same keyword with `searchType: "shorts"`, collected on **October 18, 2026**.

```json
{
  "recordType": "short",
  "detailStatus": "complete",
  "videoId": "aeUqEvQ4SPs",
  "url": "https://www.youtube.com/shorts/aeUqEvQ4SPs",
  "title": "Don’t fall for the AI Automation Agency hype (unless you’re technical or have a previous background",
  "durationSeconds": 42,
  "durationText": "0:42",
  "uploadDate": "2025-03-05",
  "publishedAt": "2025-03-05T20:07:49Z",
  "viewCount": 94210,
  "likeCount": 2092,
  "commentCount": 103,
  "channelProfile": {
    "channelId": "UCiGWNa6QK6CiKPvv5-YPv8g",
    "channelName": "Sabrina Ramonov 🍄",
    "channelHandle": "@sabrina_ramonov",
    "channelUrl": "https://www.youtube.com/channel/UCiGWNa6QK6CiKPvv5-YPv8g",
    "subscriberCount": 432000,
    "isVerified": true
  },
  "searchQuery": "AI automation",
  "searchRank": 2,
  "searchCountry": "US",
  "searchLanguage": "en",
  "scrapedAt": "2026-10-18T06:17:41.471128Z"
}
```

Counts, search order, and availability change over time. These are examples of available public data, not a guarantee that every result exposes the same fields.

#### Shared result fields

| Field | Meaning |
| --- | --- |
| `recordType` | `channel`, `video`, or `short` |
| `title`, `url`, `description` | Result identity and available public description |
| `detailStatus` | `complete` when detail extraction finished; `basic` when a request failed and available metadata was retained |
| `detailError` | Reason details remain unfinished, when applicable |
| `searchQuery` | Original keyword |
| `searchRank` | One-based order of matching results returned for this keyword and type |
| `searchCountry` | Requested YouTube search region, not the creator's country |
| `searchLanguage` | Requested YouTube interface language, not the video's spoken language |
| `scrapedAt` | UTC collection timestamp in ISO 8601 format |

#### Channel field reference

| Fields | Meaning |
| --- | --- |
| `channelId`, `channelName`, `channelHandle`, `channelUrl` | Channel identity and canonical public URL |
| `subscriberCount`, `subscriberCountText` | Normalized subscriber count and original displayed label; abbreviated counts can be approximate |
| `totalViewCount`, `videoCount` | Public channel-wide view and video totals |
| `joinedDate`, `joinedDateText` | Join date as `YYYY-MM-DD` when parseable, plus the source label |
| `channelCountry`, `isVerified` | Public channel country and verification indication |
| `avatarUrl`, `bannerUrl` | Avatar and banner image URLs |
| `socialLinks` | External links with `platform`, `url`, and `title` when available |
| `emails` | Addresses directly exposed in public channel data |

The Actor does not sign in, solve CAPTCHAs, or reveal protected business-email controls.

#### Video and Shorts field reference

| Fields | Meaning |
| --- | --- |
| `videoId`, `thumbnailUrl` | Content ID and one selected thumbnail URL |
| `durationSeconds`, `durationText` | Duration in seconds and a readable duration label |
| `uploadDate`, `publishedAt`, `publishedTimeText` | YouTube's available upload date, publication timestamp, and public date label |
| `viewCount`, `viewCountText` | Numeric total views and available displayed label |
| `likeCount`, `commentCount` | Public like and comment totals, when exposed |
| `liveStatus`, `availability`, `ageLimit` | Public content-state metadata, when exposed |
| `videoLanguage` | Audio language identifiable from public metadata; not inferred from the interface language |
| `tags`, `categories` | Public tags and category labels |
| `chapters` | Chapter objects containing `title`, `startSeconds`, and `endSeconds` |
| `channelProfile` | Six-field basic creator identity, without a separate About-page request |

`channelProfile` contains `channelId`, `channelName`, `channelHandle`, `channelUrl`, `subscriberCount`, and `isVerified`. It does not contain full channel history, country, emails, or social links.

### Use cases

- **Content research:** review titles, descriptions, publication dates, and public engagement for a topic.
- **Creator discovery:** find channels relevant to a keyword, then review their public profiles.
- **YouTube SEO research:** save keyword-result snapshots with the query, matching-result order, and collection time.
- **Recurring monitoring:** schedule the same Task and compare exports in your spreadsheet or reporting tool.
- **Automation:** send structured metadata to Google Sheets, a database, or an AI workflow. This Actor does not include transcripts or calculate performance scores.

### Inputs and supported filters

| Field | Type | Default | Accepted values and behavior |
| --- | --- | --- | --- |
| `searchQueries` | `string[]` | `["AI automation"]` | 1–20 unique keyword phrases; the limit applies separately to each phrase |
| `searchType` | `string` | `videos` | `channels`, `videos`, or `shorts`; one type per run |
| `maxResultsPerQuery` | `integer` | `3` | 1–25 matching results per keyword |
| `sortBy` | `string` | `relevance` | `relevance` or `popularity` for channels and videos; Shorts use `relevance` |
| `uploadDate` | `string` | `any` | `any`, `today`, `thisWeek`, `thisMonth`, or `thisYear` for videos |
| `duration` | `string` | `any` | `any`, `under3Minutes`, `3To20Minutes`, or `over20Minutes` for videos |
| `searchCountry` | `string` | `US` | YouTube region used to localize search ranking; not a strict channel-country filter |
| `searchLanguage` | `string` | `en` | YouTube interface and localized-metadata language; not a strict spoken-language filter |

The region and interface-language dropdowns list the values supported by this Actor. Examples include US, GB, IN, DE, JP, and BR, with interface languages such as English, Spanish, German, Japanese, Portuguese, and Chinese. No strict creator-nationality or spoken-language filtering is performed.

#### Which filters apply?

Filters are sent to YouTube during search, before results are selected. Settings that do not apply to the selected type automatically use that type's defaults.

| Result type | Sort | Upload date | Duration |
| --- | --- | --- | --- |
| `channels` | Relevance or popularity | Any time | Any duration |
| `videos` | Relevance or popularity | Supported | Supported |
| `shorts` | Relevance | Any time | Any duration |

`popularity` is YouTube's server-side ranking, not a local sort of returned view counts. Search order can vary with localization, time, and YouTube experiments.

### Pricing and limits

This Actor uses pay-per-event pricing with platform usage included. The [Pricing tab](https://apify.com/arjun_code/youtube-search-scraper/pricing) is the source of truth for current prices and discounts.

| Event | Listed price | What is charged |
| --- | --- | --- |
| Actor Start | `$0.00005` per billed GB | One event per GB of Actor memory, with at least one event per run |
| Saved search result | `$0.005` per row | One saved `channel`, `video`, or `short` result: `$5.00 / 1,000` |
| Query-status row | Free | `searchStatus` rows do not trigger the result event |

**A saved result costs the same whether details finish or fall back to `detailStatus: "basic"`.** A retry within the same run does not create an additional result event for that item: the final row is saved once. Starting another run is a separate billable run.

At the default 512 MB memory, before any discounts:

| Saved results | Result and start event total |
| ---: | ---: |
| 1 | `$0.00505` |
| 3 | `$0.01505` |
| 5 | `$0.02505` |
| 100 | `$0.50005` |
| 500 | `$2.50005` |

The maximum requested scope is `number of keywords × maxResultsPerQuery`: up to **500 results** with 20 keywords and 25 results each. It is a ceiling, not a guaranteed count or guaranteed runtime. YouTube can expose fewer matches.

The Actor respects the maximum run charge. No-result and failed-query status rows do not incur a result charge, but an Actor Start charge can still apply. Any Apify trial or account credits are provided by the platform; this Actor does not promise a separate free allowance.

### API and integrations

Start an asynchronous run with your **Apify API token**. A YouTube API key is not required.

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/arjun_code~youtube-search-scraper/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchQueries": ["AI automation"],
    "searchType": "videos",
    "maxResultsPerQuery": 3,
    "sortBy": "relevance",
    "uploadDate": "any",
    "duration": "any",
    "searchCountry": "US",
    "searchLanguage": "en"
  }'
```

The response identifies the run and its default Dataset. Wait for the run to finish, then retrieve the Dataset items. For a small synchronous request, use `/run-sync-get-dataset-items` instead of `/runs`; asynchronous runs are preferable for larger jobs.

#### Send results to Google Sheets or an automation

1. Save your input as an Apify Task and optionally add a schedule.
2. Use an Apify integration or an HTTP/webhook workflow to fetch the Dataset after the run finishes.
3. Select content rows by `recordType`. If your downstream step requires finished details, also check `detailStatus`.
4. Map the URL or ID, title, keyword, rank, metrics, and `scrapedAt` into your target table. For videos and Shorts, creator fields are nested under `channelProfile`.

n8n, Make, Zapier, and custom API clients can orchestrate this process. They require their own connections and setup; the Actor does not automatically create or update a spreadsheet.

### FAQ and limitations

#### What does complete mean? Can every field be guaranteed?

`detailStatus: "complete"` means the detail extraction finished, not that all fields exist. Creators may not publish tags, chapters, country, or a description, and YouTube may omit or hide other metadata. Unknown numeric values stay `null`, not a fabricated zero.

`detailStatus: "basic"` means a request failed and the Actor preserved available detail or search data. It is not an input mode. Open **Status & troubleshooting** to read `detailError`.

A successful Apify process status does not by itself prove every detail completed. The end-of-run message and `OUTPUT` show completed and partial detail counts separately.

#### What happens after a temporary detail failure?

Normal results are saved as they finish. After a keyword's initial detail work, transiently failed results receive one delayed recovery attempt within a bounded time window, with at most two recovery operations concurrently. Already completed results are not re-extracted.

The Actor retains known metadata if recovery fails, saves that item's final row once, and lists unfinished items in `OUTPUT.incompleteResults`. It does not automatically resume a previous run, and it does not retry indefinitely. Recovery may add runtime; neither fixed response times nor 100% field availability are guaranteed.

#### Why is a field empty although I can see a text label?

Some values are normalized from public labels, which can be abbreviated or localized. `subscriberCountText` preserves the original subscriber label. Join dates are dates, not exact account-creation timestamps.

If a numeric field is unexpectedly empty while its source text contains a usable number, report the run ID and result URL through Issues. A fetch failure is not evidence that the creator withheld the value.

#### Does search rank match every user's YouTube results?

No. `searchRank` describes matching-result order for this run, result type, and query context. It is not a universal position across personalized YouTube sessions.

Results finish concurrently, so Dataset insertion order may differ from rank. Sort by `searchQuery`, then `searchRank`, to restore matching-result order.

#### Can region or language strictly select creator country or spoken language?

No. `searchCountry` and `searchLanguage` set the localized search context. `channelCountry` is a separately exposed channel field, and `videoLanguage` identifies audio language when available.

#### Are Shorts selected only by their duration?

No. Discovery uses YouTube's native Shorts search surface. The regular-video duration filter does not select Shorts.

#### What does a searchStatus row mean?

Read `status`, `errorMessage`, and `suggestion`:

- `noResults`: no matching public results were returned; try a broader keyword or fewer filters.
- `failed`: discovery could not finish; this is not treated as a valid empty search.
- `chargeLimitReached`: the run's maximum charge prevented further result writes.

These query-status rows are visible and free. They can appear alongside content rows.

#### Where is the run summary?

Open the default Key-Value Store record **OUTPUT**, or use the **Run summary** output link. It contains effective filters, counts by query, query statuses including `partial`, completed and partial detail totals, recovery counts, unfinished result URLs, and the maximum-charge status.

The summary helps troubleshoot a run without attaching operational diagnostics to every result.

#### Are view counts on live videos concurrent viewers?

No. `viewCount` represents total views. If the page only displays a concurrent-viewer label, `viewCountText` can contain the unformatted total instead.

#### Can it download videos, comments, transcripts, or a complete channel archive?

No. This Actor searches keywords and collects metadata for selected matches. It does not download media, paginate comments, export transcripts, or enumerate a channel's entire archive. Use the related tools below for those workflows.

#### Can it reveal protected business emails?

No. Only emails directly exposed in public channel data are included.

#### Why can a larger run take longer?

Each selected match needs detail extraction. Localization, separate metadata requests, temporary failures, and result count affect runtime. Start with one keyword and 3 results; do not extrapolate a small successful run into a guaranteed bulk response time.

#### Related YouTube Actors

| Goal | Actor |
| --- | --- |
| Get profiles for known channel handles, IDs, or URLs | [YouTube Channel Details Scraper](https://apify.com/arjun_code/youtube-channel-details-scraper) |
| Get metadata for known video or Shorts URLs or IDs | [YouTube Video and Shorts Details Scraper](https://apify.com/arjun_code/youtube-video-details-scraper) |
| Export a channel's videos, Shorts, and streams | [YouTube Channel Content Scraper](https://apify.com/arjun_code/youtube-channel-content-scraper) |
| Export public comments and replies | [YouTube Comments Scraper](https://apify.com/arjun_code/youtube-comments-scraper) |

#### Support and responsible use

Open the Actor's **Issues** tab with the run ID, sanitized input, affected result URL, and expected field. Do not post API tokens, credentials, or private data.

Use the Actor only for lawful processing of publicly accessible information. You are responsible for complying with applicable laws, privacy requirements, YouTube's terms, and rules governing use of contact information.

# Actor input Schema

## `searchQueries` (type: `array`):

Add one keyword phrase per line. The result limit applies independently to each keyword.

## `searchType` (type: `string`):

Return one consistent result type per run.

## `maxResultsPerQuery` (type: `integer`):

Maximum results returned for each keyword. The Actor attempts to enrich every selected result from its relevant detail page.

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

Use YouTube's relevance or popularity ranking for channel and standard-video searches. Shorts automatically use Relevance.

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

Filter standard videos using YouTube's relative upload-date categories. Channel and Shorts searches automatically use Any time.

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

Filter standard videos using YouTube's duration categories. Channel and Shorts searches automatically use Any duration.

## `searchCountry` (type: `string`):

Select the YouTube content region used for localized search ranking. This is not a strict filter for a channel's country.

## `searchLanguage` (type: `string`):

Select the YouTube interface and localized metadata language used during search. This is not a strict filter for a video's spoken language.

## Actor input object example

```json
{
  "searchQueries": [
    "AI automation"
  ],
  "searchType": "videos",
  "maxResultsPerQuery": 3,
  "sortBy": "relevance",
  "uploadDate": "any",
  "duration": "any",
  "searchCountry": "US",
  "searchLanguage": "en"
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "searchQueries": [
        "AI automation"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("arjun_code/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 = { "searchQueries": ["AI automation"] }

# Run the Actor and wait for it to finish
run = client.actor("arjun_code/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 '{
  "searchQueries": [
    "AI automation"
  ]
}' |
apify call arjun_code/youtube-search-scraper --silent --output-dataset

```

## MCP server setup

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