# TikTok Hashtag Scraper: TikTok Hashtag Views & Videos (`xmolodtsov/tiktok-hashtag-scraper`) Actor

Get TikTok hashtag views, video counts and videos for any hashtag. Each video comes with its caption, views, likes, comments, shares, music, hashtags and creator profile with follower counts. No login. Export JSON, CSV or Excel, or use the API. Pay only per result.

- **URL**: https://apify.com/xmolodtsov/tiktok-hashtag-scraper.md
- **Developed by:** [Yevhenii Molodtsov](https://apify.com/xmolodtsov) (community)
- **Categories:** Social media, Videos, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 tiktok hashtag video results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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

![TikTok Hashtag Scraper: TikTok Hashtag Views & Videos logo](https://api.apify.com/v2/key-value-stores/2DxCOvbMjhvK3S1qP/records/tiktok-hashtag-scraper-avatar-128)

### What does TikTok Hashtag Scraper do?

TikTok Hashtag Scraper collects TikTok hashtag views and videos: for any hashtag you get its total views and video count, and each video posted under it as a clean, structured row with the caption, views, likes, comments, shares and saves, the music, the other hashtags used and the creator's profile with follower counts. It is built for marketers tracking a trend, brands and agencies looking for creators in a niche, researchers studying what gets posted under a tag, and developers who need TikTok hashtag data in a spreadsheet, database or pipeline, with no TikTok account, login or cookies.

- **Videos by hashtag**: enter one or many hashtags, with or without `#`, or paste a `tiktok.com/tag/…` link.
- **Creator stats included**: each video carries its creator's followers, following, total likes and video count, so you can rank creators without a second scraper.
- **Hashtag stats**: every row has `searchHashtag` with the hashtag's name, ID, total views and number of videos on TikTok.
- **Spreadsheet-ready**: counts are plain numbers, not "1.2M" strings, and video, creator and music IDs are kept as exact strings.
- **No duplicates**: the same hashtag typed twice (`#Cooking` and `cooking`) is scraped once, and each video appears only once per run.
- **Clear errors**: a hashtag that doesn't exist gives one error row instead of disappearing silently.
- **No browser**: plain HTTP requests, so 100 videos take under 30 seconds.

### Use cases

- **Brands and agencies finding creators**: scrape a few hundred #booktok videos, sort by `authorMeta.fans` and keep the creators who already post there.
- **Marketers running hashtag analytics**: set **Maximum videos per hashtag** to 1 and schedule a daily run. Each row's `searchHashtag` holds the tag's total views and video count, so tracking 20 hashtags costs 20 results a day.
- **Researchers comparing content across tags**: pull #skincare, #travel and #fitness in one run and compare captions, languages, music and engagement side by side.

### What data does TikTok Hashtag Scraper extract?

One dataset item per video, with these fields:

| Field | Description |
|---|---|
| `id` / `webVideoUrl` | Video ID (string) and link |
| `text` / `textLanguage` | Caption and its detected language |
| `createTime` / `createTimeISO` | When the video was posted (Unix seconds / ISO 8601) |
| `playCount` / `diggCount` / `shareCount` / `commentCount` / `collectCount` / `repostCount` | Views, likes, shares, comments, saves and reposts |
| `authorMeta` | Creator's ID, handle, display name, bio, avatar, verified badge, followers (`fans`), following, total likes (`heart`) and video count |
| `musicMeta` | Sound name, artist, ID (string), cover and whether it is an original sound |
| `videoMeta` | Duration, width, height, definition, cover image link and, when TikTok lists them, subtitle file links |
| `hashtags` / `mentions` / `detailedMentions` | Hashtags and users mentioned in the caption |
| `effectStickers` / `isSlideshow` / `slideshowImageLinks` | Effects used, photo-slideshow flag and, for slideshows, the image links |
| `isAd` / `isSponsored` / `isPinned` | Ad and pinned flags |
| `locationMeta` | Tagged location, only when the video has one |
| `searchHashtag` | The hashtag the video was found under: `name`, total `views`, `id` and `videoCount` |
| `input` | The hashtag exactly as you entered it |

The **Overview** table in the Output tab shows the hashtag, creator, followers, caption, views, likes, shares, comments, duration, music, date and link side by side.

### How to scrape TikTok hashtags

#### In Apify Console

1. Open the Actor in Apify Console and add one or more hashtags to **Hashtags**, one per line.
2. Set **Maximum videos per hashtag** (100 by default).
3. Click **Start**. When the run finishes, open the **Output** tab and download the videos as JSON, CSV or Excel.

#### Through the API

Start a run and get the videos back in one call with `run-sync-get-dataset-items`:

```bash
curl -X POST "https://api.apify.com/v2/acts/xmolodtsov~tiktok-hashtag-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hashtags": ["sourdough", "#BookTok"], "resultsPerPage": 50}'
```

Or use the JavaScript client (the Python client works the same way):

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('xmolodtsov/tiktok-hashtag-scraper').call({
    hashtags: ['sourdough', '#BookTok'],
    resultsPerPage: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((v) => [v.searchHashtag.name, v.authorMeta.name, v.playCount]));
```

#### With AI agents (MCP)

The Actor is available through Apify's MCP server at [mcp.apify.com](https://mcp.apify.com) as `xmolodtsov/tiktok-hashtag-scraper`. Connect an MCP client such as Claude or Cursor to `https://mcp.apify.com?tools=xmolodtsov/tiktok-hashtag-scraper` and it can call the Actor as a tool with the same input and read the videos back, for example "get 50 #booktok videos and list the creators with the most followers". Pricing and free-plan limits apply as usual.

### How much does it cost to scrape TikTok hashtags?

You pay per result: each row written to the dataset is one result. Platform usage, including the residential proxies the Actor uses, is included in the price (pay-per-event), so there are no extra compute or proxy charges on top. The price depends on your Apify plan's tier:

| Apify plan (discount tier) | Price per 1,000 results |
|---|---|
| Free | $2.40 |
| Starter (Bronze) | $1.60 |
| Scale (Silver) | $1.20 |
| Business (Gold) and the Platinum and Diamond tiers | $0.80 |

For example, 500 videos from #sourdough cost $0.80 on Starter, and 10 hashtags × 100 videos cost $0.80 on Business. Set a maximum cost per run in the run options and the Actor stops cleanly when it is reached, keeping everything scraped so far.

#### Is it free?

You can try it on the Apify free plan, which comes with monthly platform credit. On the free plan this Actor returns up to **10 results per run** (error rows included) and allows **5 runs per calendar month**; the count resets on the 1st. These limits are set by the developer, not by Apify. Any paid Apify plan removes them.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `hashtags` | array of strings | (required) | Hashtags to scrape, with or without `#`, or `tiktok.com/tag/…` URLs. Matching ignores `#` and letter case, so repeats are scraped once. A hashtag can't contain spaces. |
| `resultsPerPage` | integer | `100` | Maximum videos per hashtag. A higher number is safe: each hashtag stops when TikTok has no new videos to give (see Limits). |
| `proxyConfiguration` | object | Apify residential | Leave as is. The Actor rotates through European residential exits by default. Change it only to route through your own proxies. |

```json
{
    "hashtags": ["sourdough", "#BookTok", "https://www.tiktok.com/tag/cooking"],
    "resultsPerPage": 200
}
```

### Output

Each video is one dataset item. This is the Overview table of a real run with the hashtags #skincare, #travel and #fitness:

![TikTok Hashtag Scraper output: Overview table of TikTok videos by hashtag with creator, followers, caption, views, likes, shares, comments, music and date](https://api.apify.com/v2/key-value-stores/2DxCOvbMjhvK3S1qP/records/tiktok-hashtag-scraper-output-table.png)

And this is a full item from the #cooking feed (long media links shortened):

```json
{
    "id": "7676392545902972191",
    "text": "You’ve got to trust the process! 🙃 Chocolate making with Amaury Guichon 🤯 #fyp #foryou #chocolate #cooking #foodporn ",
    "textLanguage": "en",
    "createTime": 1787299471,
    "createTimeISO": "2026-08-21T08:04:31.000Z",
    "isAd": false,
    "authorMeta": {
        "id": "6618195296668418053",
        "name": "foodporn",
        "profileUrl": "https://www.tiktok.com/@foodporn",
        "nickName": "Foodporn",
        "verified": true,
        "signature": "Foodporn is your guide to all things delicious 😋🍜🥐🍔",
        "bioLink": null,
        "avatar": "https://p16-common-sign.tiktokcdn-eu.com/…/7310444044553814021~tplv-tiktokx-cropcenter:1080:1080.jpeg?…",
        "commerceUserInfo": { "commerceUser": false },
        "privateAccount": false,
        "region": null,
        "roomId": "",
        "ttSeller": false,
        "createTime": 0,
        "following": 1705,
        "friends": 0,
        "fans": 5600000,
        "heart": 122100000,
        "video": 4051,
        "digg": 628,
        "followDatasetUrl": null,
        "originalAvatarUrl": "https://p16-common-sign.tiktokcdn-eu.com/…/7310444044553814021~tplv-tiktokx-cropcenter:1080:1080.jpeg?…"
    },
    "musicMeta": {
        "musicName": "оригінальний аудіозапис",
        "musicAuthor": "Vitaly Meloman",
        "musicOriginal": true,
        "playUrl": "https://v45.tiktokcdn-eu.com/…",
        "coverMediumUrl": "https://p16-common-sign.tiktokcdn-eu.com/…/c97e8588042d9198a179d72c6a5c0e6e~tplv-tiktokx-cropcenter:720:720.jpeg?…",
        "originalCoverMediumUrl": "https://p16-common-sign.tiktokcdn-eu.com/…/c97e8588042d9198a179d72c6a5c0e6e~tplv-tiktokx-cropcenter:720:720.jpeg?…",
        "musicId": "7647930548907690770"
    },
    "webVideoUrl": "https://www.tiktok.com/@foodporn/video/7676392545902972191",
    "videoMeta": {
        "height": 1024,
        "width": 576,
        "duration": 179,
        "coverUrl": "https://p16-common-sign.tiktokcdn-eu.com/…~tplv-tiktokx-origin.image?…",
        "definition": "540p",
        "format": "mp4",
        "subtitleLinks": null,
        "transcriptionLink": null,
        "originalCoverUrl": "https://p16-common-sign.tiktokcdn-eu.com/…~tplv-tiktokx-origin.image?…"
    },
    "diggCount": 32000,
    "shareCount": 17900,
    "playCount": 1100000,
    "collectCount": 3156,
    "commentCount": 815,
    "repostCount": 0,
    "mentions": [],
    "detailedMentions": [],
    "hashtags": [
        { "id": "229207", "name": "fyp" },
        { "id": "42164", "name": "foryou" },
        { "id": "12763", "name": "chocolate" },
        { "id": "18973", "name": "cooking" },
        { "id": "15782", "name": "foodporn" }
    ],
    "effectStickers": [],
    "isSlideshow": false,
    "isPinned": false,
    "isSponsored": false,
    "mediaUrls": [],
    "input": "cooking",
    "searchHashtag": {
        "name": "cooking",
        "views": 552444789984,
        "id": "18973",
        "videoCount": 19215376
    }
}
```

A hashtag that doesn't exist gives one error row instead of videos:

```json
{
    "url": "https://www.tiktok.com/tag/zzqxvnonexistenttag8812",
    "input": "zzqxvnonexistenttag8812",
    "error": "Hashtag #zzqxvnonexistenttag8812 not found on TikTok",
    "errorCode": "HASHTAG_NOT_FOUND"
}
```

An input that isn't a hashtag at all (for example, text with spaces) gives a similar row with `errorCode` `INVALID_HASHTAG`. Error rows are dataset items, so they are billed like results.

### Guarantees, limits and run status

#### When does a run fail?

- **FAILED** when a hashtag fails and the run returns no videos at all, or when more hashtags fail than the larger of 2 and 20% of your hashtags (with 20 hashtags, the 5th failure fails the run). Retry a failed run as a whole.
- **FAILED** when the input has no hashtags.
- **SUCCEEDED** otherwise. Hashtags that don't exist, invalid inputs and repeated hashtags are part of your data, not failures: they never fail the run and the status message counts them (for example "Scraped 120 videos from 3 hashtags (1 not found)").
- A run that stops at your maximum cost per run, or at the free-plan cap, ends **SUCCEEDED** with a status message saying so. A sixth free-plan run in the same calendar month ends SUCCEEDED with no results and a message explaining the limit.

Every run also writes a `STATISTICS` record to its key-value store with each hashtag's outcome, videos and pages scraped, request counts and the run duration.

#### Limits

- **How deep a hashtag goes**: TikTok serves a visitor only part of each hashtag's feed, however many videos the hashtag has. Large hashtags give about 350–550 videos (measured: #sourdough 490–540, #cooking 400+). Very generic tags give far fewer because TikTok serves a small feed for them: #fyp returns about 180. `searchHashtag.videoCount` shows the hashtag's full size on TikTok.
- **Where the videos come from**: results come from TikTok's European hashtag feed. The Actor widens it by querying several European regions in turn and stops when a region adds almost no new videos. There is no country filter.
- **Speed**: 100 videos take under 30 seconds. Each extra region adds fewer new videos than the one before, so asking for the maximum takes a few minutes per hashtag (#sourdough to 489 videos: about 3.5 minutes). Up to 3 hashtags run at the same time.
- **Order**: videos arrive in the order TikTok's feed serves them, not sorted by date or views. Sort and filter the dataset afterwards.
- **Not included**: the Actor doesn't download video files or cover images and doesn't fetch subtitle text or transcripts, so `mediaUrls` is empty and `transcriptionLink` is `null`. Media links in the output are signed by TikTok and expire after a while.

### Integrations

- **Exports**: download any dataset as JSON, CSV, Excel, XML, JSONL, RSS or HTML from the Output tab or the API.
- **Schedules**: use [Apify schedules](https://docs.apify.com/platform/schedules) to re-scrape the same hashtags daily or weekly and follow a trend over time.
- **Webhooks**: send finished runs to your own endpoint with [webhooks](https://docs.apify.com/platform/integrations/webhooks).
- **No-code tools**: connect the Actor to Make, Zapier, n8n, Google Sheets and more through [Apify integrations](https://docs.apify.com/platform/integrations).
- **API clients**: the [Apify API](https://docs.apify.com/api/v2) has JavaScript and Python clients, shown above.

### More scrapers from this developer

**TikTok:** [TikTok Search Scraper](https://apify.com/xmolodtsov/tiktok-search-scraper): videos and creators for any keyword, pay per result · [TikTok Profile Scraper (Pay Per Result)](https://apify.com/xmolodtsov/tiktok-profile-scraper): profiles, followers and latest posts by username · [TikTok Comments Scraper](https://apify.com/xmolodtsov/tiktok-comments-scraper): comments and full reply threads from any video · [TikTok Sound & Music Scraper](https://apify.com/xmolodtsov/tiktok-sound-scraper): videos that use a sound or song

**Social & news:** [Reddit Search Scraper](https://apify.com/xmolodtsov/reddit-scraper): posts by keyword, subreddit or author · [Google News Scraper](https://apify.com/xmolodtsov/google-news-scraper): Google News results as clean full-text articles

**E-commerce:** [Prom.ua Product Search Scraper](https://apify.com/xmolodtsov/prom-ua): Prom.ua product search results, no browser needed · [Amazon Product Search & Bestsellers Scraper](https://apify.com/xmolodtsov/amazon-search-scraper): search results, Best Sellers and product details from Amazon

**Maps & leads:** [Google Maps Scraper](https://apify.com/xmolodtsov/google-maps-scraper): places, leads and emails from Google Maps

**Ads:** [Facebook Ad Library Scraper (Meta Ads Library)](https://apify.com/xmolodtsov/facebook-ads-library-scraper): ads from the Meta Ad Library, with EU reach and payers

**Video:** [YouTube Transcript Scraper](https://apify.com/xmolodtsov/youtube-transcript-scraper): transcripts, subtitles and captions from YouTube videos

### FAQ

#### How many videos can I get per hashtag?

About 350–550 for large hashtags, and around 180 for very generic ones such as #fyp. That is how much of each feed TikTok serves to a visitor, so setting a higher limit won't return more.

#### Why did I get fewer videos than I asked for?

Usually because the hashtag's feed ran out (see Limits). Other reasons: a video that already appeared under another hashtag in the same run isn't repeated, the free plan caps a run at 10 results, the run reached your maximum cost per run, or the hashtag doesn't exist (you get a `HASHTAG_NOT_FOUND` row instead).

#### Can I export the data to CSV or Excel?

Yes. Download the dataset as JSON, CSV, Excel, XML or HTML from the Output tab, or fetch it through the API. The Overview table shows the hashtag, creator, followers, caption, counts and link side by side.

#### How do I find creators for a hashtag?

Every video carries its creator's `authorMeta`, with followers (`fans`), total likes (`heart`), video count, bio and verified badge. Scrape the hashtag, then sort or deduplicate the dataset by `authorMeta.name` to get a creator list for the niche. To get each creator's latest posts next, paste the handles into [TikTok Profile Scraper](https://apify.com/xmolodtsov/tiktok-profile-scraper).

#### What about private or deleted videos?

Only public videos appear in TikTok's hashtag feed, so videos from private accounts are never returned. A video deleted after your run stays in your dataset, but its link stops working.

#### Do I need a TikTok account or my own proxies?

No. The Actor never logs in and uses Apify residential proxies by default. Their cost is included in the price per result.

#### How long does a run take?

About 30 seconds for 100 videos, and a few minutes per hashtag when you ask for the maximum.

#### Is it legal to scrape TikTok?

This Actor only collects data that TikTok shows publicly to any visitor, without logging in. It never accesses private accounts or anything behind a login. Videos and profiles can still contain personal data (handles, display names, bios, avatars), which laws such as the GDPR in the EU and the CCPA in California protect. Only collect personal data when you have a lawful reason to, keep only what you need, and store it responsibly. You are responsible for how you use the data; if you are unsure, consult a lawyer.

### Support

Found a bug or need a field that isn't there? Open an issue in the **Issues** tab on this Actor's page. Include the run ID so the run's log and `STATISTICS` record can be checked.

# Changelog

This Actor's version history is a separate document: https://apify.com/xmolodtsov/tiktok-hashtag-scraper/changelog.md

# Actor input Schema

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

Hashtags to scrape, one per line, with or without <code>#</code> (e.g. <code>cooking</code> or <code>#cooking</code>). A <code>tiktok.com/tag/…</code> URL works too. Repeated hashtags are scraped once.

## `resultsPerPage` (type: `integer`):

Maximum number of videos to scrape from each hashtag. Each video is one paid result. TikTok serves only part of each hashtag feed: about 350–550 videos for large hashtags, fewer for some very broad ones (e.g. #fyp: about 180). <strong>Free Apify plan:</strong> at most 10 results per run in total (error rows included) and 5 runs per calendar month.

## `proxyConfiguration` (type: `object`):

Apify residential proxies are used by default, rotating through European countries: TikTok serves deeper hashtag feeds there. Change it only if you want to route through your own proxies.

## Actor input object example

```json
{
  "hashtags": [
    "cooking"
  ],
  "resultsPerPage": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

One item per TikTok video under the requested hashtags: caption, play/like/share/comment counts, author profile, music, hashtags and the source hashtag's views and video count.

# 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": [
        "cooking"
    ],
    "resultsPerPage": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("xmolodtsov/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": ["cooking"],
    "resultsPerPage": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("xmolodtsov/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": [
    "cooking"
  ],
  "resultsPerPage": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call xmolodtsov/tiktok-hashtag-scraper --silent --output-dataset

```

## MCP server setup

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