# Tiktok Hashtag Scraper (`crawlerbros/tiktok-hashtag-scraper`) Actor

Scrape TikTok videos by hashtag without cookies. Extracts video metadata (views, likes, comments, shares), author info, music metadata, and more. Features anti-bot detection, residential proxy support, and human-like browsing behavior.

- **URL**: https://apify.com/crawlerbros/tiktok-hashtag-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Videos, Social media, Developer tools
- **Stats:** 31 total users, 6 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $3.00 / 1,000 results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## TikTok Hashtag Scraper

Scrape TikTok hashtag pages to collect metadata statistics and the videos posted under any hashtag. Three flexible modes let you pull only the hashtag stats, only the video feed, or both in a single run — all without cookies or login.

### What this actor does

- Accepts one or more hashtags (with or without the `#` symbol) and scrapes each one
- Retrieves hashtag metadata from TikTok's challenge stats: view count, video count, description, and cover images
- Fetches the paginated video feed for each hashtag and returns full post rows with engagement stats
- Supports four modes: `metadata` (stats only, always reliable), `posts` (video feed), `topPosts` (search-based fallback), and `auto` (tries posts, falls back gracefully)
- Automatically falls back to metadata-only when TikTok blocks the post feed, ensuring at least one record per hashtag
- Empty fields are omitted

### Output per hashtag metadata record

- `rowType` — always `"hashtag_metadata"`
- `hashtagId` — unique TikTok challenge/hashtag ID
- `hashtagName` — normalized hashtag name without `#`
- `desc` — hashtag description text
- `videoCount` — total number of videos using this hashtag
- `viewCount` — total view count across all videos using this hashtag
- `isCommerce` — whether this is a branded/commercial hashtag
- `profileLarger` — large cover image URL (when present)
- `profileMedium` — medium cover image URL (when present)
- `shareMeta.title` — share title
- `shareMeta.desc` — share description

### Output per post record

- `postId` — unique TikTok video ID
- `postUrl` — direct URL to the video
- `caption` — full caption text
- `searchedHashtag` — the hashtag used to find this post
- `author.id` — author's TikTok user ID
- `author.secUid` — author's secondary unique ID
- `author.username` — author handle
- `author.displayName` — author display name
- `author.verified` — verification status
- `author.avatarUrl` — author profile image URL
- `likeCount` — total likes
- `commentCount` — total comments
- `shareCount` — total shares
- `playCount` — total plays/views
- `music.id` — sound ID
- `music.title` — sound title
- `music.authorName` — sound creator name
- `music.original` — whether it is an original sound
- `hashtags` — array of hashtag names parsed from caption
- `scrapedAt` — ISO 8601 timestamp of when the record was collected

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `hashtags` | string\[] | — | Hashtags to scrape (with or without `#`). Required, minimum 1. |
| `mode` | string | `"auto"` | Scrape mode: `auto`, `metadata`, `posts`, or `topPosts`. |
| `maxPostsPerHashtag` | integer | 50 | Maximum videos to collect per hashtag when mode includes posts (0–500). |
| `includeHashtagMetadata` | boolean | `true` | Emit a metadata stats row for each hashtag in addition to post rows. |

#### Example: hashtag stats only (lightest run)

```json
{
  "hashtags": ["fyp", "trending", "viral"],
  "mode": "metadata"
}
```

#### Example: posts with metadata

```json
{
  "hashtags": ["cooking"],
  "mode": "auto",
  "maxPostsPerHashtag": 100,
  "includeHashtagMetadata": true
}
```

#### Example: competitor hashtag research

```json
{
  "hashtags": ["nikerunning", "adidasoriginals"],
  "mode": "posts",
  "maxPostsPerHashtag": 200,
  "includeHashtagMetadata": false
}
```

#### Example: trend monitoring

```json
{
  "hashtags": ["summerfashion", "ootd", "streetstyle"],
  "mode": "auto",
  "maxPostsPerHashtag": 50,
  "includeHashtagMetadata": true
}
```

### Use cases

- **Social media managers** tracking hashtag performance and video count growth over time
- **Brand marketing teams** monitoring branded hashtag campaigns and measuring reach via view count
- **Content creators** identifying high-volume hashtags to include in their posts for discoverability
- **Market researchers** collecting video datasets around industry-specific hashtags for sentiment analysis
- **Agencies** auditing competitor hashtag strategies to benchmark engagement and volume
- **Journalists** monitoring event or news hashtags in real time for content discovery

### FAQ

**Q: Do I need a TikTok account or cookies?**\
A: No. Metadata mode works without any authentication. Post scraping uses TikTok's public API, though success rates vary by IP and session.

**Q: What is the difference between `posts` and `topPosts` mode?**\
A: `posts` mode uses TikTok's paginated hashtag video feed. `topPosts` uses a search-based approach as a fallback when the feed is blocked. `auto` mode tries both in sequence and falls back to metadata-only if needed.

**Q: Why might I get fewer posts than `maxPostsPerHashtag`?**\
A: TikTok limits how many posts are exposed via the hashtag feed API, typically 400–800 videos per hashtag. The actor stops when TikTok returns no more results.

**Q: What does `viewCount` on the metadata row represent?**\
A: It is TikTok's aggregate view count across all videos ever posted under that hashtag, not just the videos you scraped in this run.

**Q: Can I scrape multiple hashtags in one run?**\
A: Yes. Pass multiple values in the `hashtags` array. Each is processed in sequence with the same mode and limit settings.

**Q: Is the `#` symbol required in the input?**\
A: No. The actor normalizes the input and strips any leading `#` characters automatically.

**Q: What does `isCommerce` mean in the metadata row?**\
A: TikTok marks certain hashtags as commercial or branded challenges. This field reflects TikTok's own classification.

### Related TikTok Scrapers

Build a complete TikTok data pipeline with our full suite:

| Scraper | URL |
|---|---|
| TikTok Post Scraper | https://apify.com/crawlerbros/tiktok-post-scraper |
| TikTok Profile Scraper | https://apify.com/crawlerbros/tiktok-profile-scraper |
| TikTok Comments Scraper | https://apify.com/crawlerbros/tiktok-comments-scraper |
| TikTok Search Scraper | https://apify.com/crawlerbros/tiktok-search-scraper |
| TikTok Music Scraper | https://apify.com/crawlerbros/tiktok-music-scraper |
| TikTok Transcript Scraper | https://apify.com/crawlerbros/tiktok-transcript-scraper |
| TikTok Followers Scraper | https://apify.com/crawlerbros/tiktok-followers-scraper |
| TikTok Mention Scraper | https://apify.com/crawlerbros/tiktok-mention-scraper |
| TikTok Profile Mention Scraper | https://apify.com/crawlerbros/tiktok-profile-mention-scraper |
| TikTok Playlist Scraper | https://apify.com/crawlerbros/tiktok-playlist-scraper |
| TikTok Explore Scraper | https://apify.com/crawlerbros/tiktok-explore-scraper |
| TikTok For You Scraper | https://apify.com/crawlerbros/tiktok-for-you-scraper |
| TikTok Downloader | https://apify.com/crawlerbros/tiktok-downloader-api |
| TikTok Ads Library Scraper | https://apify.com/crawlerbros/tiktok-ads-library-scraper-pro |
| TikTok Top Ads Scraper | https://apify.com/crawlerbros/tiktok-top-ads-scraper |
| TikTok Hashtag Trends Scraper | https://apify.com/crawlerbros/tiktok-hashtag-trends-scraper |
| TikTok LIVE Scraper | https://apify.com/crawlerbros/tiktok-live-scraper |

# Actor input Schema

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

List of TikTok hashtags to scrape. You can include or omit the # symbol. Example: comedy, #dance, fyp

## `mode` (type: `string`):

What to scrape per hashtag. 'metadata' emits one stats record per hashtag (always works). 'posts' fetches videos (may be blocked). 'topPosts' tries a search fallback. 'auto' tries posts, falls back to topPosts, then metadata-only.

## `maxPostsPerHashtag` (type: `integer`):

Maximum number of posts to scrape per hashtag (when mode includes posts). Set to 0 to skip posts entirely (equivalent to metadata-only mode). Has no effect in metadata-only mode.

## `includeHashtagMetadata` (type: `boolean`):

When scraping posts, also emit a 'hashtag\_metadata' record with the challenge stats (videoCount, viewCount, description, etc.) at the start of each hashtag's results.

## Actor input object example

```json
{
  "hashtags": [
    "fyp"
  ],
  "mode": "metadata",
  "maxPostsPerHashtag": 5,
  "includeHashtagMetadata": true
}
```

# Actor output Schema

## `data` (type: `string`):

Dataset containing hashtag metadata records and/or post records. Use 'recordType' field to distinguish: 'hashtag\_metadata' rows have challenge stats; post rows have full video metadata.

# 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": [
        "fyp"
    ],
    "mode": "metadata",
    "maxPostsPerHashtag": 5,
    "includeHashtagMetadata": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/tiktok-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": ["fyp"],
    "mode": "metadata",
    "maxPostsPerHashtag": 5,
    "includeHashtagMetadata": True,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/tiktok-hashtag-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 '{
  "hashtags": [
    "fyp"
  ],
  "mode": "metadata",
  "maxPostsPerHashtag": 5,
  "includeHashtagMetadata": true
}' |
apify call crawlerbros/tiktok-hashtag-scraper --silent --output-dataset

```

## MCP server setup

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