# TikTok Hashtag Video Feed & Stats Extractor (`nimbryxo-studio/tiktok-hashtag-video-feed-and-stats-extractor`) Actor

Collect a TikTok hashtag's total view/video counts plus the video feed underneath it - captions, author, music, and engagement - with automatic fallback when the feed is blocked.

- **URL**: https://apify.com/nimbryxo-studio/tiktok-hashtag-video-feed-and-stats-extractor.md
- **Developed by:** [Nimbryxo-studio](https://apify.com/nimbryxo-studio) (community)
- **Categories:** Social media, Videos, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 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?

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 Video Feed & Stats Extractor

Pull videos and aggregate stats from any TikTok hashtag page without logging in. Point it at one or more hashtags and get back each hashtag's total view/video counts, plus the individual video feed underneath it — captions, author details, music, and engagement counts — in one dataset.

### What this actor does

- Accepts any number of hashtags, with or without the `#` symbol, and processes each independently
- Pulls hashtag-level stats (total video count, total view count, commerce flag, cover images) from the hashtag's TikTok page
- Pages through the video feed under each hashtag (`posts` mode) with per-video captions, author, music, and engagement metrics, up to `maxPostsPerHashtag`
- In `auto` mode, falls back from the hashtag feed to a single page of TikTok keyword-search results (`topPosts`), and finally to the stats record alone, when the feed is blocked; `posts` mode has no such fallback
- Empty fields are omitted from every record

### Output per hashtag metadata record

- `recordType` — always `"hashtag_metadata"`
- `searchedHashtag` — the hashtag you requested, lowercased and without `#`
- `hashtagId` — TikTok's internal challenge ID
- `hashtagName` — normalized hashtag name without `#`
- `desc` — hashtag description text
- `videoCount` — total videos posted under this hashtag, as TikTok reports it (a numeric string, since counts can be very large)
- `viewCount` — total views across all videos under this hashtag (numeric string)
- `isCommerce` — whether TikTok classifies this as a branded/commercial hashtag
- `profileLarger` / `profileMedium` / `profileThumb` / `coverLarger` / `coverMedium` / `coverThumb` — cover image URLs, when TikTok provides them
- `announcementTitle` / `announcementBody` — hashtag campaign announcement text, when present
- `shareMeta` — `{title, desc}` used for social-sharing previews

This record is written first for each hashtag when `includeHashtagMetadata` is on, and always in `metadata` mode. In `topPosts` mode, if TikTok doesn't return the hashtag's stats, the record still appears but holds only `recordType` and `searchedHashtag`.

### Output per video record

- `recordType` — always `"post"`
- `searchedHashtag` — the hashtag this video was found under
- `postId`, `postType` (`video` or `slideshow`), `postUrl`
- `caption`, `textLanguage`, `locationCreated`
- `createTime` (Unix epoch), `createdAt` (ISO 8601)
- `stitchEnabled`, `shareEnabled`, `duetEnabled`, `isAd`
- `playCount`, `likeCount`, `commentCount`, `shareCount`, `collectCount`, `repostCount`
- `author` — `{id, secUid, username, displayName, bio, verified, privateAccount, roomId, avatarUrl, followerCount, followingCount, heartCount, videoCount}` (the counts appear when TikTok includes them with the video)
- `music` — `{id, title, authorName, original, duration, album, playUrl, coverUrl}`
- `video` — `{width, height, duration, ratio, playUrl, cover}`
- `images[]` — slide images with `{ordinal, width, height, urlList}`, present only for slideshow posts
- `hashtags[]` — hashtags tagged in the caption (including the one you searched, when present), as `{name, id, isCommerce}`
- `mentions[]` — `@` mentions in the caption, as `{username, start, end, awemeId}` (character offsets in the caption)
- `mediaUrlExpiresAt` — expiry timestamp of the signed media URLs, when detectable

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `hashtags` | array | – | Hashtags to scrape, with or without `#` (required, at least one) |
| `mode` | string | `auto` | `metadata` (stats only), `posts` (hashtag video feed), `topPosts` (one page of keyword-search results, at most 50 videos), or `auto` (posts → topPosts → stats only) |
| `maxPostsPerHashtag` | integer | `50` | Max videos per hashtag in `posts`, `topPosts` and `auto` (0–500); ignored in `metadata` mode; `0` returns no videos |
| `includeHashtagMetadata` | boolean | `true` | Also emit the hashtag stats record before the video records; `metadata` mode emits it regardless |

#### Example: lightweight stats check

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

#### Example: campaign hashtag deep dive

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

#### Example: brand hashtag video pull only

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

### Use cases

- **Brand teams** measuring reach of a branded or campaign hashtag via its total view/video counts
- **Social media managers** pulling the current top videos under a hashtag for competitive content review
- **Trend researchers** collecting video samples from a niche hashtag to analyze creator patterns
- **Agencies** comparing hashtag volume across several client or competitor tags in a single run
- **Growth marketers** monitoring how fast a hashtag's video count is climbing over successive runs

### FAQ

**Does this need a TikTok login or cookies?**
No. Hashtag stats and the video feed are both pulled from TikTok's public pages without any account.

**Why would a run only return the metadata record and no videos?**
TikTok's hashtag video feed sometimes blocks automated access. In `auto` mode the actor falls back to keyword search, and if that also comes back empty it still returns the hashtag stats record rather than failing the run. In `posts` mode there is no search fallback, so a blocked feed leaves only the stats record (or nothing, if `includeHashtagMetadata` is off). If TikTok won't return even the hashtag's stats after repeated attempts, that hashtag produces no records.

**What's the difference between `posts` and `topPosts`?**
`posts` reads TikTok's dedicated hashtag video feed page by page. `topPosts` runs a TikTok keyword search for the hashtag text and takes the videos from the first page of results, so it returns at most 50 videos and some of them may not actually carry the hashtag. `auto` tries `posts` first and only falls back to `topPosts` if the feed comes back empty.

**Why did I get fewer videos than `maxPostsPerHashtag`?**
The actor stops when TikTok reports no more pages for the hashtag feed or blocks a page mid-run, and `topPosts` (including the `auto` fallback) never goes past one search page of up to 50 videos.

**Does `viewCount` reflect only the videos I scraped?**
No — it's TikTok's all-time aggregate view count for every video ever posted under that hashtag, independent of how many videos this run collected.

**Do I need to include the `#` symbol?**
No. `#fyp`, `fyp` and `FYP` are treated identically, and duplicates in the list are processed once.

**Is this affiliated with TikTok?**
No. This is an independent actor that reads TikTok's public hashtag pages and is not operated or endorsed by TikTok.

# 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("nimbryxo-studio/tiktok-hashtag-video-feed-and-stats-extractor").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("nimbryxo-studio/tiktok-hashtag-video-feed-and-stats-extractor").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 nimbryxo-studio/tiktok-hashtag-video-feed-and-stats-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nimbryxo-studio/tiktok-hashtag-video-feed-and-stats-extractor"
        }
    }
}
```

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/FSS2ebxYm0XcCsrgp/builds/JbUW6RcduuzN2roVp/openapi.json
