# TikTok Discover / Explore Scraper (`coregent/tiktok-discover-explore-scraper`) Actor

Scrape TikTok Explore videos by category. Extract ranked trending videos with creators, captions, plays, likes, comments, shares, hashtags, sound/music metadata and video URLs. No login or cookies required.

- **URL**: https://apify.com/coregent/tiktok-discover-explore-scraper.md
- **Developed by:** [Delowar Munna](https://apify.com/coregent) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 explore 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.

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 Discover / Explore Scraper

Scrape TikTok Explore videos by category. Extract ranked trending videos with creators, captions, plays, likes, comments, shares, hashtags, sound/music metadata and video URLs. Export clean JSON, CSV or Excel. **No TikTok login or cookies required.**

![TikTok Discover / Explore Scraper — trending TikTok Explore videos by category](https://raw.githubusercontent.com/coregentdevspace/tiktok-discover-explore-scraper-assets/main/thumbnail-tiktok-discover-explore-scraper.png)

### What is TikTok Explore?

**Explore** (also called **Discover**) is TikTok's own curated feed of trending videos, grouped into native categories such as *Technology*, *Food*, *Sports* or *Comedy*. You don't search it — TikTok decides what's in it and in what order.

This Actor retrieves that feed, category by category, and returns every video with its **category** and its **native Explore rank**.

### How is this different from keyword search?

| Actor | Input | What you get |
|---|---|---|
| **TikTok Discover / Explore Scraper** (this one) | a category | TikTok's own Explore-ranked videos for that category |
| TikTok Keyword Search Scraper | a search term | videos TikTok's search returns for your query |
| TikTok Viral Video Finder | your criteria | videos scored/filtered for virality by Coregent |

Use Explore when you want to see **what TikTok itself is pushing** in a category — trend discovery, category monitoring, content ideation, creator discovery and sound/hashtag discovery — without having to guess keywords first.

### What does it extract?

For each video, per category:

- **Lineage & rank** — `category`, `categoryId`, `categoryName`, `rank`
- **Video** — `videoId`, canonical `videoUrl`, `playUrl`, `coverUrl`, `description`, `createdAt`, `durationSeconds`, `language`
- **Engagement** — `stats.plays`, `stats.likes`, `stats.comments`, `stats.shares`, `stats.saves`
- **Creator** — `creator.id`, `secUid`, `username`, `displayName`, `profileUrl`, `avatarUrl`, `isVerified`, `followers`
- **Hashtags & mentions** — `hashtags[]`, `mentions[]`
- **Music / sound** — `music.id`, `title`, `author`, `url`, `audioUrl`, `isOriginal`
- **Subtitles** (opt-in) — `subtitles[]` with language, format and URL
- **Derived metrics** (Coregent-computed, not TikTok-native) — `derived.engagementRate`, `derived.ageHours`, `derived.playsPerHour`

### Supported categories

| Input value | TikTok category |
|---|---|
| `ALL` | All (mixed Explore feed) |
| `ANIMATION_COMICS` | Animation & comics |
| `PERFORMANCE` | Performance |
| `BEAUTY` | Beauty care |
| `GAMING` | Game |
| `COMEDY` | Comedy |
| `DAILY_LIFE` | Daily life |
| `FAMILY` | Family |
| `RELATIONSHIPS` | Emotional relationship |
| `DRAMA` | Drama |
| `FASHION` | Dress up |
| `DUBBING` | Dubbing |
| `FOOD` | Food |
| `SPORTS` | Sports |
| `ANIMALS` | Animals |
| `SOCIETY` | Society |
| `AUTOMOTIVE` | Car |
| `EDUCATION` | Education |
| `FITNESS_HEALTH` | Fitness & health |
| `TECHNOLOGY` | Technology |
| `SINGING_DANCING` | Singing & dancing |

Values are case-insensitive and duplicates are ignored. An unknown value is reported as `UNSUPPORTED_CATEGORY` in the run summary; the rest of the run continues.

### Input

| Parameter | Type | Default | Description |
|---|---|---|---|
| `categories` | string\[] | `["ALL"]` | Explore categories to scrape (see table above) |
| `maxResultsPerCategory` | integer | `100` | Max unique videos saved per category, after filters (1–1000) |
| `includeVideoUrls` | boolean | `true` | Add `playUrl` (canonical `videoUrl` is always included) |
| `includeCreator` | boolean | `true` | Add the `creator` object |
| `includeHashtags` | boolean | `true` | Add `hashtags[]` and `mentions[]` |
| `includeMusic` | boolean | `true` | Add the `music` object |
| `includeSubtitles` | boolean | `false` | Add `subtitles[]` where TikTok provides them |
| `minViews` / `minLikes` / `minComments` / `minShares` | integer | `0` | Only keep videos at or above these counts (0 = off) |
| `postedWithin` | string | `"any"` | `any`, `24 hours`, `7 days`, `30 days`, `90 days` |
| `maxConcurrency` | integer | `4` | Categories scraped in parallel (1–8) |

Turning a field group off sets it to `null`; it doesn't change the price.

#### Example: minimal

```json
{
  "categories": ["ALL"],
  "maxResultsPerCategory": 100
}
```

#### Example: multi-category

```json
{
  "categories": ["TECHNOLOGY", "EDUCATION", "FITNESS_HEALTH", "FOOD"],
  "maxResultsPerCategory": 250
}
```

#### Example: high engagement only

```json
{
  "categories": ["ALL"],
  "maxResultsPerCategory": 1000,
  "minViews": 100000,
  "minLikes": 5000
}
```

#### Example: fresh videos

```json
{
  "categories": ["TECHNOLOGY"],
  "maxResultsPerCategory": 500,
  "postedWithin": "7 days"
}
```

### Output

One row = **one video in one category**. If the same video appears in two categories you selected, you get one row per category, each with its own rank.

![TikTok Explore videos in the Explore Videos table view](https://raw.githubusercontent.com/coregentdevspace/tiktok-discover-explore-scraper-assets/main/tiktok-discover-explore-scraper-output-explore-videos-table-view.png)
*Explore Videos table view — ranked videos per category with engagement and creator columns.*

The dataset has five output tabs. Below is the same real video (Food category) as each tab shows it. Long signed media links are shortened with `?...` here; the dataset contains the full links.

##### Explore Videos (default)

```json
{
  "category": "FOOD",
  "rank": 6,
  "videoUrl": "https://www.tiktok.com/@azixstarr.asmr/video/7693194203555286290",
  "description": "🌶️ Fresh Green Chili Mixing — Spicy, Tangy & Full of Flavor! 😋🔥 #Viral #ForYou #Yummy #GreenChili #spicyfood ",
  "createdAt": "2026-10-05T14:42:44.000Z",
  "durationSeconds": 16,
  "stats.plays": 1000000,
  "stats.likes": 15700,
  "stats.comments": 314,
  "stats.shares": 1487,
  "creator.username": "azixstarr.asmr",
  "coverUrl": "https://p16-common-sign.tiktokcdn.com/tos-alisg-p-0037/o0ehoQHgG7z52CbVAIesAnKgOLj7YVDIPokjeH~tplv-tiktokx-origin.image?...",
  "scrapedAt": "2026-10-14T11:18:36.972Z"
}
```

##### Engagement

```json
{
  "category": "FOOD",
  "rank": 6,
  "videoId": "7693194203555286290",
  "videoUrl": "https://www.tiktok.com/@azixstarr.asmr/video/7693194203555286290",
  "stats.plays": 1000000,
  "stats.likes": 15700,
  "stats.comments": 314,
  "stats.shares": 1487,
  "stats.saves": 1957,
  "derived.engagementRate": 0.0175,
  "derived.ageHours": 212.6,
  "derived.playsPerHour": 4704,
  "createdAt": "2026-10-05T14:42:44.000Z"
}
```

##### Creators

```json
{
  "category": "FOOD",
  "rank": 6,
  "videoUrl": "https://www.tiktok.com/@azixstarr.asmr/video/7693194203555286290",
  "creator.username": "azixstarr.asmr",
  "creator.displayName": "Azixstarr ASMR eating show",
  "creator.profileUrl": "https://www.tiktok.com/@azixstarr.asmr",
  "creator.isVerified": false,
  "creator.followers": 43800,
  "creator.id": "7192231854307673093",
  "creator.secUid": "MS4wLjABAAAAmX9kE0iDkIgTXIZ_5eKMwZVI6Qrn0wxCUo4hTt8iIAEVHhVjFxJXwUohSmTXYHBY",
  "creator.avatarUrl": "https://p16-common-sign.tiktokcdn.com/tos-alisg-avt-0068/ad72426cf5ce4d53c3b2cc8efbcb1936~tplv-tiktokx-cropcenter:1080:1080.jpeg?..."
}
```

##### Sounds & Hashtags

```json
{
  "category": "FOOD",
  "rank": 6,
  "videoUrl": "https://www.tiktok.com/@azixstarr.asmr/video/7693194203555286290",
  "hashtags": [
    "viral",
    "foryou",
    "yummy",
    "greenchili",
    "spicyfood"
  ],
  "mentions": [],
  "music.title": "original sound",
  "music.author": "𝔹 ℍ 𝕌 𝕀 𝕐 𝔸 ℕ❗️",
  "music.isOriginal": true,
  "music.url": "https://www.tiktok.com/music/original-sound-7382935166114614017",
  "music.audioUrl": "https://v16m.tiktokcdn.com/e24a56dd60ce9b3a03884b708c808f94/6ad0b6ae/video/tos/alisg/tos-alisg-v-27dcd7/oIIJudEcW5FKfqQ1UWRkqdgQDfCuFBNDdB4mXY/?...",
  "music.id": "7382935166114614017"
}
```

##### Full Data

```json
{
  "rowType": "video",
  "category": "FOOD",
  "categoryId": 111,
  "categoryName": "Food",
  "rank": 6,
  "videoId": "7693194203555286290",
  "videoUrl": "https://www.tiktok.com/@azixstarr.asmr/video/7693194203555286290",
  "playUrl": "https://www.tiktok.com/aweme/v1/play/?...",
  "coverUrl": "https://p16-common-sign.tiktokcdn.com/tos-alisg-p-0037/o0ehoQHgG7z52CbVAIesAnKgOLj7YVDIPokjeH~tplv-tiktokx-origin.image?...",
  "description": "🌶️ Fresh Green Chili Mixing — Spicy, Tangy & Full of Flavor! 😋🔥 #Viral #ForYou #Yummy #GreenChili #spicyfood ",
  "createdAt": "2026-10-05T14:42:44.000Z",
  "durationSeconds": 16,
  "stats": {
    "plays": 1000000,
    "likes": 15700,
    "comments": 314,
    "shares": 1487,
    "saves": 1957
  },
  "creator": {
    "id": "7192231854307673093",
    "secUid": "MS4wLjABAAAAmX9kE0iDkIgTXIZ_5eKMwZVI6Qrn0wxCUo4hTt8iIAEVHhVjFxJXwUohSmTXYHBY",
    "username": "azixstarr.asmr",
    "displayName": "Azixstarr ASMR eating show",
    "profileUrl": "https://www.tiktok.com/@azixstarr.asmr",
    "avatarUrl": "https://p16-common-sign.tiktokcdn.com/tos-alisg-avt-0068/ad72426cf5ce4d53c3b2cc8efbcb1936~tplv-tiktokx-cropcenter:1080:1080.jpeg?...",
    "isVerified": false,
    "followers": 43800
  },
  "hashtags": [
    "viral",
    "foryou",
    "yummy",
    "greenchili",
    "spicyfood"
  ],
  "mentions": [],
  "music": {
    "id": "7382935166114614017",
    "title": "original sound",
    "author": "𝔹 ℍ 𝕌 𝕀 𝕐 𝔸 ℕ❗️",
    "url": "https://www.tiktok.com/music/original-sound-7382935166114614017",
    "audioUrl": "https://v16m.tiktokcdn.com/e24a56dd60ce9b3a03884b708c808f94/6ad0b6ae/video/tos/alisg/tos-alisg-v-27dcd7/oIIJudEcW5FKfqQ1UWRkqdgQDfCuFBNDdB4mXY/?...",
    "isOriginal": true
  },
  "subtitles": [],
  "language": "en",
  "isAd": false,
  "isSlideshow": false,
  "derived": {
    "engagementRate": 0.0175,
    "ageHours": 212.6,
    "playsPerHour": 4704
  },
  "source": "TIKTOK_EXPLORE",
  "scrapedAt": "2026-10-14T11:18:36.972Z"
}
```

Unavailable optional fields are `null`, and a field group you switch off is `null` too. `subtitles` is `[]` when TikTok has no subtitle track for the video (it's only filled when `includeSubtitles` is on).

#### Rank semantics

- `rank` is the **order TikTok served** the video in that category's Explore feed, starting at 1.
- The Actor never re-ranks locally. If a filter removes earlier videos, the remaining videos **keep their original rank** (so you may see 4, 7, 9…).
- Explore ranking is personalised and changes over time — a rank is a snapshot of when the run happened.
- Beyond the first few dozen videos, Explore behaves like a continuous stream rather than a fixed chart: deeper pages keep bringing new videos, and `rank` records the order this run received them.

#### Engagement & derived metrics

`stats.*` are TikTok's exact integer counts where available. `derived.*` are computed by this Actor and labelled as such:

- `engagementRate = (likes + comments + shares) / plays`
- `ageHours` — hours between posting and scrape time
- `playsPerHour = plays / max(ageHours, 1)`

#### Video URL behavior

- `videoUrl` is always the canonical `https://www.tiktok.com/@user/video/<id>` link.
- `playUrl` prefers TikTok's `https://www.tiktok.com/aweme/v1/play/...` route, which works **without any TikTok cookie or login**. It redirects to TikTok's video CDN, which expects the request header **`Referer: https://www.tiktok.com/`** — send it when downloading (e.g. `curl -L -e https://www.tiktok.com/ "<playUrl>" -o video.mp4`). Without that header the CDN answers `403`.
- `coverUrl`, `creator.avatarUrl` and `music.audioUrl` need no special headers.
- All media links are signed by TikTok and expire after a while — download promptly rather than storing the links long-term.
- Internal session tokens are never included in the output.

#### Run summary

Each run stores a `RUN_SUMMARY` record in the key-value store (it's not a dataset row and is never charged):

```json
{
  "categoriesRequested": 5,
  "categoriesSucceeded": 5,
  "categoriesFailed": 0,
  "videosSaved": 1250,
  "duplicatesSkipped": 44,
  "filteredRows": 212,
  "providerRequests": 85,
  "categories": [
    { "category": "TECHNOLOGY", "status": "SUCCESS", "saved": 250, "stopReason": "result limit reached" }
  ]
}
```

Per-category statuses: `SUCCESS`, `NO_RESULTS`, `UNSUPPORTED_CATEGORY`, `RATE_LIMITED`, `BLOCKED`, `PARTIAL_RESULT`, `TEMPORARY_TIKTOK_ERROR`, `PROVIDER_ERROR`. One failed category never fails the run. If any category failed, a ready-to-use `RETRY_INPUT` record lists just those categories.

### Result depth

You can ask for up to **1,000 unique videos per category**. The Actor keeps pulling the next batch for a category until it has `maxResultsPerCategory` videos. In our tests TikTok kept serving new videos all the way to 1,000 (for example `ALL` and `FOOD`, with no repeats), and a full `ALL` + `FOOD` × 1,000 run finished in under two minutes.

If TikTok stops serving videos it hasn't already returned, the category ends early with the reason in the run summary — you are only charged for what's delivered.

### Login & cookies

None needed. You don't provide a TikTok account, cookies, or a proxy.

### Country support

There is **no country filter** in this version. The Actor reads TikTok's **United States** Explore feed, so the mix of creators and languages reflects what TikTok shows US viewers. Other countries may be added later if they can be validated.

### Pricing

Pay per result: you're charged once per **unique video delivered per category** (`explore-video-result`). You are **not** charged for:

- duplicate videos within a category
- videos removed by your filters
- failed or unsupported categories
- retries or provider requests
- the run summary

There's no run-start fee, so a run that returns nothing costs nothing. See the **Pricing** tab for current rates — this README deliberately doesn't quote figures, since they're set on the platform and can change.

### API & MCP usage

Run from the Apify API:

```bash
curl -X POST "https://api.apify.com/v2/acts/coregent~tiktok-discover-explore-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"categories":["TECHNOLOGY","FOOD"],"maxResultsPerCategory":50}'
```

JavaScript:

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('coregent/tiktok-discover-explore-scraper').call({
  categories: ['TECHNOLOGY'],
  maxResultsPerCategory: 100,
  minViews: 50000,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

The Actor also works from AI agents through the **Apify MCP server** — add `coregent/tiktok-discover-explore-scraper` as a tool and ask, for example, *"Get the top 50 Technology videos on TikTok Explore posted in the last 7 days."*

### Scheduling

Explore changes constantly. Use **Apify Schedules** to run the same input hourly or daily and build a time series of what TikTok is pushing in each category — then compare `rank` and `stats` across runs, or send results to Google Sheets, Slack or a webhook.

### Works well with

- **TikTok Video Scraper** — full details for videos you found on Explore
- **TikTok Profile Scraper** — full profiles for the creators behind them
- **TikTok Viral Video Finder** — score and filter videos for virality
- **TikTok Contact Extractor** — public business contacts for discovered creators

### Limitations

- Up to 1,000 videos per category per run (see *Result depth*).
- United States Explore feed only — no country filter in this version.
- Some fields (`saves`, `language`, `subtitles`, creator `followers`) depend on what TikTok includes and may be `null`.
- Metrics change after scraping, and Explore ranking is personalised and time-dependent.
- Creative Center trend modes (hashtag/creator/music charts) are not included — they're deprecated upstream.

### Compliance

This is an unofficial tool and is not affiliated with, endorsed by, or connected to TikTok or ByteDance. It processes **public** Explore data only — no login, no private content, no messaging or follow automation. Explore ranking changes over time and metrics can change after scraping. You are responsible for making sure your use of the data complies with applicable laws and TikTok's terms.

# Actor input Schema

## `categories` (type: `array`):

TikTok Explore categories to scrape. Each video is returned once per selected category, with its native Explore rank. ALL = TikTok's mixed Explore feed.

## `maxResultsPerCategory` (type: `integer`):

Maximum unique videos to save per category (after filters). Explore is a bounded, rotating feed — a category may return fewer when TikTok stops serving new videos.

## `includeVideoUrls` (type: `boolean`):

Add playUrl (a playback URL usable without TikTok cookies where available). The canonical videoUrl is always included.

## `includeCreator` (type: `boolean`):

Add the lightweight creator object (id, secUid, username, display name, profile URL, avatar, verified).

## `includeHashtags` (type: `boolean`):

Add hashtags\[] and mentions\[] parsed from the video.

## `includeMusic` (type: `boolean`):

Add the music object (id, title, author, music page URL, audio URL, original-sound flag).

## `includeSubtitles` (type: `boolean`):

Add subtitle track links (language, format, URL) where TikTok provides them.

## `minViews` (type: `integer`):

Only keep videos with at least this many plays. 0 = off.

## `minLikes` (type: `integer`):

Only keep videos with at least this many likes. 0 = off.

## `minComments` (type: `integer`):

Only keep videos with at least this many comments. 0 = off.

## `minShares` (type: `integer`):

Only keep videos with at least this many shares. 0 = off.

## `postedWithin` (type: `string`):

Only keep videos posted within this window.

## `maxConcurrency` (type: `integer`):

How many categories to scrape in parallel (pages within a category are always sequential).

## Actor input object example

```json
{
  "categories": [
    "ALL"
  ],
  "maxResultsPerCategory": 20,
  "includeVideoUrls": true,
  "includeCreator": true,
  "includeHashtags": true,
  "includeMusic": true,
  "includeSubtitles": false,
  "minViews": 0,
  "minLikes": 0,
  "minComments": 0,
  "minShares": 0,
  "postedWithin": "any",
  "maxConcurrency": 4
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `engagement` (type: `string`):

No description

## `creators` (type: `string`):

No description

## `music` (type: `string`):

No description

## `full` (type: `string`):

No description

## `runSummary` (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 = {
    "categories": [
        "ALL"
    ],
    "maxResultsPerCategory": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("coregent/tiktok-discover-explore-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 = {
    "categories": ["ALL"],
    "maxResultsPerCategory": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("coregent/tiktok-discover-explore-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 '{
  "categories": [
    "ALL"
  ],
  "maxResultsPerCategory": 20
}' |
apify call coregent/tiktok-discover-explore-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,coregent/tiktok-discover-explore-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/rw9328AJpxseaAvBB/builds/EVlcN7pD9vdcnfMUg/openapi.json
