# YouTube Hashtag Scraper (`s-r/youtube-hashtag-scraper`) Actor

- **URL**: https://apify.com/s-r/youtube-hashtag-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** Social media, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Hashtag Scraper

Scrape YouTube videos by hashtag at scale. Give this actor a list of hashtags and it returns every video YouTube surfaces under each one, with full metadata: titles, channels, view counts, durations, thumbnails, publish dates, and more. It talks directly to YouTube's internal InnerTube web API, so there is no official API key to manage, no OAuth flow, and no daily quota to burn through.

Hashtags are how discovery works on YouTube now. Campaigns, challenges, product launches, and trends all cluster under a tag. This actor turns that cluster into structured data you can filter, sort, and pipe into a spreadsheet or database.

### What you get

Every row is one video. For each hashtag you request, you get back:

- **Video identity**: `video_id`, `url`, `title`, `description`, and a short `description_snippet`
- **The tag that matched**: `hashtag` (the exact hashtag this video was found under)
- **Channel data**: `channel_name`, `channel_id`, `channel_url`, and `channel_subscribers`
- **Timing**: `published_text` (like "3 weeks ago"), `published_date`, and `is_live`
- **Engagement**: `view_count`, `like_count`, `comment_count`
- **Format**: `duration_seconds`, `duration_text`, `category`, `thumbnail_url`
- **Run metadata**: `fetched_in_seconds` per video

Fields like `like_count`, `comment_count`, `channel_subscribers`, `published_date`, and `category` are only populated when you enable `fetch_details` (see Input below).

### Why scrape YouTube hashtags

YouTube has a Data API, but it does not expose hashtag feeds. You can search for a keyword, list a channel's uploads, or read a playlist, but there is no official endpoint that says "give me every video tagged #blackfriday." The hashtag landing pages you see in the YouTube app are rendered from an internal API that the public Data API never touches. If you want that data, you have to go get it yourself.

That gap matters because hashtags are where intent lives. When a brand runs a campaign, when a creator starts a challenge, or when a topic starts trending, the videos organize themselves under a shared tag. Tracking that tag over time tells you how a trend is spreading, who is participating, and which videos are pulling the views. A keyword search cannot do this cleanly, because keyword results mix in old and unrelated content. A hashtag feed is the creators' own signal of what a video is about.

This actor reads that feed directly. You pass hashtags with or without the `#`, and it walks YouTube's InnerTube pagination to pull as many videos as you ask for, up to 1000 per hashtag. Because it uses the same web endpoints the browser uses, there is no key, no quota, and no per-project rate limit to negotiate.

### Input

| Field | Type | Required | Description |
|---|---|---|---|
| `hashtags` | array of strings | Yes | Hashtags to scrape. Include the `#` or leave it off, both work (e.g. `["shorts", "#gaming"]`). |
| `max_results` | integer | No | Videos to return per hashtag, 1 to 1000. |
| `fetch_details` | boolean | No | When true, fetches each video's page for `like_count`, `comment_count`, `channel_subscribers`, exact `published_date`, and `category`. Slower but richer. |
| `country` | string | No | Country code for the YouTube region (e.g. `US`, `GB`, `DE`). |
| `language` | string | No | Language code for titles and metadata (e.g. `en`, `es`, `de`). |

A minimal run needs only `hashtags`. Turn on `fetch_details` when you need engagement numbers or exact dates; leave it off when you only need the fast feed-level fields.

### Output

Each dataset item is one video. Here is a real row with `fetch_details` enabled:

```json
{
  "video_id": "dQw4w9WgXcQ",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "title": "Our #blackfriday deals are live",
  "description": "Full breakdown of every discount in this year's sale. #blackfriday #deals",
  "description_snippet": "Full breakdown of every discount in this year's sale.",
  "hashtag": "#blackfriday",
  "channel_name": "Example Store",
  "channel_id": "UCabc123def456",
  "channel_url": "https://www.youtube.com/channel/UCabc123def456",
  "channel_subscribers": 128000,
  "published_text": "2 days ago",
  "published_date": "2026-07-11",
  "view_count": 45210,
  "like_count": 1830,
  "comment_count": 214,
  "duration_seconds": 187,
  "duration_text": "3:07",
  "category": "People & Blogs",
  "thumbnail_url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg",
  "is_live": false,
  "fetched_in_seconds": 0.42
}
````

The `hashtag` field tells you which of your input tags matched this video, so when you scrape several hashtags in one run you can still group and compare results per tag.

### Use cases

**Trend researchers** want to know how a topic moves. Scrape a hashtag on a schedule, store the `view_count` and `published_date` for each video, and you can chart how fast a trend is growing, when it peaked, and which videos drove the spike. Because you get `channel_subscribers`, you can also tell whether a trend is being carried by big channels or by a long tail of small creators.

**Campaign and UGC monitors** live and die by hashtag participation. If your brand launched `#mychallenge`, this actor gives you every public video using it: who posted, how many views they pulled, how engaged their audience was via `like_count` and `comment_count`, and when they published. That is your user-generated-content leaderboard, refreshed on demand, without asking creators to tag you manually.

**Social listening and competitive intelligence** teams track the hashtags their competitors own. Pull a rival's branded tag weekly and you see their content cadence, their best-performing videos, and which creators are amplifying them. Cross-reference `category` and `duration_text` to understand what format is landing.

**Content discovery and curation** is the simplest use. Editors and community managers scrape a niche hashtag, sort by `view_count`, and surface the strongest recent videos to feature, react to, or license. The `description_snippet` and `thumbnail_url` fields make it easy to preview candidates without opening YouTube at all.

### How it compares

| | This actor | streamers/youtube-video-scraper-by-hashtag |
|---|---|---|
| Price per video | **$0.0016** | $0.002 |
| Price per 1000 videos | **$1.60** | $2.00 |
| Volume discount | Same low rate at every volume | None, flat rate |
| Max videos per hashtag | 1000 | Comparable |
| Optional engagement details | Yes, via `fetch_details` | Yes |
| API key required | No | No |

We charge 20 percent less per video and we beat the competitor at every volume, because their rate is flat and never drops. Whether you pull 100 videos or 100,000, you pay $1.60 per thousand.

### Pricing

Pay-per-event, so you only pay for what you actually scrape.

- **$0.0016 per video** returned ($1.60 per 1000 videos)
- **$0.002 per run** actor-start fee

There is no monthly subscription and no minimum. A run that returns 500 videos across your hashtags costs $0.002 + (500 x $0.0016) = $0.802.

### Limits and gotchas

- **Hashtag feeds are bounded by YouTube.** A hashtag page only exposes a finite number of videos. If a tag is small, you will get fewer than your `max_results` cap, and that is YouTube's limit, not the actor's.
- **`fetch_details` adds one request per video.** It pulls each video's page for likes, comments, subscribers, exact date, and category. Expect runs to take noticeably longer with it on. Leave it off when feed-level fields are enough.
- **Engagement fields are empty without `fetch_details`.** `like_count`, `comment_count`, `channel_subscribers`, `published_date`, and `category` only populate in detail mode. The feed itself does not carry them.
- **Free-tier runs are capped at 10 results per run.** Upgrade to a paid Apify plan to remove the cap and pull the full 1000 per hashtag.
- **`view_count` and `like_count` are point-in-time.** They reflect the moment of scraping. For trend tracking, run on a schedule and store snapshots.
- **`published_text` is relative, `published_date` is exact.** The feed gives you fuzzy strings like "3 weeks ago"; the exact `published_date` only arrives with `fetch_details`.
- **Region and language shift results.** `country` and `language` change which videos YouTube surfaces and in what language the metadata comes back. Set them deliberately.

### FAQ

**How do I find YouTube videos by hashtag?**
Enter one or more hashtags in the `hashtags` input, with or without the `#`, and run the actor. It reads YouTube's internal hashtag feed and returns every video it surfaces, up to 1000 per tag, with full metadata for each.

**Can I track a campaign hashtag on YouTube over time?**
Yes. Schedule the actor to run daily or weekly on your campaign hashtag and store each run's output. Because every row carries `view_count`, `published_date`, and `channel_subscribers`, you can chart participation and reach as the campaign unfolds.

**Do I need a YouTube API key or Google account?**
No. The actor uses YouTube's InnerTube web API, the same endpoints the website uses. There is no API key, no OAuth, and no daily quota to manage.

**How many videos can I get per hashtag?**
Up to 1000, set via `max_results`. The real ceiling is whatever YouTube exposes for that specific hashtag, so smaller tags will return fewer.

**Why are like counts and subscriber numbers missing from my results?**
Those fields only populate when you enable `fetch_details`. The plain hashtag feed does not include engagement or subscriber data, so the actor fetches each video's page to get them when detail mode is on.

### Related Actors

- [Youtube Scraper](https://apify.com/s-r/youtube-scraper) - Scrape YouTube videos by search term, channel, or video URL.
- [Youtube Shorts Scraper](https://apify.com/s-r/youtube-shorts-scraper) - Scrape YouTube Shorts from any channel with full engagement data.
- [Youtube Comments](https://apify.com/s-r/youtube-comments) - Scrape all comments from any YouTube video.

# Actor input Schema

## `hashtags` (type: `array`):

Hashtags to scrape, with or without the # prefix. One per line.

## `max_results` (type: `integer`):

Maximum videos to collect per hashtag (1–1000).

## `fetch_details` (type: `boolean`):

Enrich every video with likes, channel subscribers, comment count, full description, exact publish date and category (extra requests per video).

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

Two-letter country code (gl).

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

Two-letter interface language code (hl).

## Actor input object example

```json
{
  "hashtags": [
    "webscraping"
  ],
  "max_results": 20,
  "fetch_details": true,
  "country": "US",
  "language": "en"
}
```

# 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 = {
    "hashtags": [
        "webscraping"
    ],
    "max_results": 20,
    "country": "US",
    "language": "en"
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/youtube-hashtag-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 = {
    "hashtags": ["webscraping"],
    "max_results": 20,
    "country": "US",
    "language": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/youtube-hashtag-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "hashtags": [
    "webscraping"
  ],
  "max_results": 20,
  "country": "US",
  "language": "en"
}' |
apify call s-r/youtube-hashtag-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=s-r/youtube-hashtag-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "YouTube Hashtag Scraper",
        "description": "",
        "version": "0.1",
        "x-build-id": "EIPIuk8Krh4AziHZc"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/s-r~youtube-hashtag-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-s-r-youtube-hashtag-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/s-r~youtube-hashtag-scraper/runs": {
            "post": {
                "operationId": "runs-sync-s-r-youtube-hashtag-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/s-r~youtube-hashtag-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-s-r-youtube-hashtag-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "hashtags"
                ],
                "properties": {
                    "hashtags": {
                        "title": "Hashtags",
                        "type": "array",
                        "description": "Hashtags to scrape, with or without the # prefix. One per line.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "max_results": {
                        "title": "Max videos per hashtag",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum videos to collect per hashtag (1–1000).",
                        "default": 20
                    },
                    "fetch_details": {
                        "title": "Fetch full video details",
                        "type": "boolean",
                        "description": "Enrich every video with likes, channel subscribers, comment count, full description, exact publish date and category (extra requests per video).",
                        "default": true
                    },
                    "country": {
                        "title": "Country",
                        "type": "string",
                        "description": "Two-letter country code (gl).",
                        "default": "US"
                    },
                    "language": {
                        "title": "Language",
                        "type": "string",
                        "description": "Two-letter interface language code (hl).",
                        "default": "en"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
