# TikTok Scraper: Videos by Keyword, Profile, Hashtag & URL (`parseforge/tiktok-scraper`) Actor

Scrape TikTok videos by keyword, profile, hashtag or URL: plays, likes, saves, creator followers, music, country, transcripts. Export CSV, Excel, JSON, XML.

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

## Pricing

from $0.20 / 1,000 videos

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

[![ParseForge](https://raw.githubusercontent.com/ParseForge/apify-assets/main/banner-v4.webp)](https://apify.com/parseforge?fpr=vmoqkp)

### TikTok Scraper API: Videos by Keyword, Profile, Hashtag & URL, with Transcripts

**Scrape TikTok videos by keyword, creator, hashtag or link: 258 videos from three keywords came back in 24 seconds in our last test.** Every video carries plays, likes, comments, shares and saves, the creator with follower count, the sound, hashtags, mentions and media links, and on request the posting country, a transcript and a sample of top comments. No login, no TikTok API key. Export to CSV, JSON, Excel or XML.

TikTok's official Research API is limited to approved academic projects, and its Display API only covers accounts that log in to your app. This Actor reads what TikTok shows logged-out visitors, keeps one fixed schema across all four ways in, and returns one flat row per video.

| Who uses it | What they scrape TikTok for |
|---|---|
| Brand and social teams | TikTok analytics on their own and competitors' creators, run on a schedule |
| Influencer marketers | Creators behind a topic or hashtag, with followers, likes and posting rhythm |
| Trend researchers | TikTok trends: what a keyword or hashtag shows right now, by country |
| Content and SEO teams | TikTok transcripts of the videos that rank for their keywords |
| Data scientists | TikTok datasets with captions, stats and text for sentiment and topic models |

### What it does

The Actor takes keywords, profiles, hashtags and video URLs, alone or together, and returns one row per video.

- 🎬 **Video:** id, link, caption, posting time, duration, size, definition, cover and animated cover, play and download links, slideshow images for photo posts.
- 📊 **Stats:** plays, likes, comments, shares and saves.
- 👤 **Creator:** username, nickname, id, verified, followers, following, total likes, video count, bio, avatar, private flag.
- 🎵 **Sound:** id, title, author, original-sound flag, length, audio link and cover.
- \#️⃣ **Text:** hashtags and mentions, caption language, caption tracks available.
- ➕ **Optional add-ons**, each off by default: full video details (posting country, tagged place, ad flag, caption language) for list modes, a transcript from TikTok's own captions, and up to 100 top comments per video.

### What you can do with TikTok data

**📈 Track creators on a schedule.**

List the creators you follow in `profiles` with `publishedAfter` set to "7 days". Each run returns their new videos with fresh play, like and share counts, and the date floor stops the scroll early, so weekly runs stay fast.

**🔎 See what a keyword or hashtag shows today.**

Put phrases in `keywords` (a region per run) or tags in `hashtags`, sort by most played and keep only videos above a play count. You get the videos and creators that own the topic right now.

**🗣 Mine what videos say, not just their captions.**

Turn on the transcript add-on to get the spoken text of every video that carries TikTok captions, ready for search, summaries or sentiment models.

**💬 Read the room under each video.**

Turn on top comments to get the first comments TikTok shows, with likes, reply counts and commenter, next to the video's stats.

### Why choose this scraper

| | What you get |
|---|---|
| **Four ways in, one schema** | Keywords, profiles, hashtags and video URLs in the same run and the same row layout: 51 columns, 54 with every add-on on. |
| **Transcripts from TikTok's captions** | The spoken text of each captioned video as plain text, English track first. No per-minute transcription fee. |
| **Posting country** | The country a video was posted from, read from the video's own page. |
| **Filters and sorting** | Date range (exact or "7 days"), minimum plays, likes and comments, skip pinned videos and ads, sort by newest, oldest, plays, likes, comments or shares. |
| **Region for keywords** | Pick the country whose TikTok answers the keyword. Japan and the US shared only 17 of their top 30 videos for "cooking" in our test. |
| **Honest errors** | A deleted video, a private profile or a hashtag that does not exist comes back as its own row with the reason, and is never billed. |

### How it compares

All four scrapers below read public TikTok videos by keyword, profile and hashtag. The table lists only what each rival's own Store listing and input form state, checked on September 24, 2026.

| Feature | ParseForge | clockworks/tiktok-scraper | apidojo/tiktok-scraper | xmolodtsov/tiktok-search-scraper |
|---|---|---|---|---|
| Transcript | Add-on, one flat fee per video, from TikTok's captions | Add-on, billed per minute of video | Not in its listing | Not in its listing |
| Comment text | Add-on, 1 to 100 per video, in the same run | Add-on | Separate Actor | Not in its listing |
| Country for keyword results | Included, any country | Paid add-on, through residential proxy | Location-based search | Included |

### What a TikTok video looks like

One row from a verified run on September 24, 2026 (profile `nasa`, all add-ons on). The long signed media links, the transcript and the comment list are shortened here:

```json
{
  "imageUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/o4BjAVnVuiCAcCqAE1iB7Sf3IAXzwqExBJtSUI~tplv-tiktokx-origin.image?...",
  "id": "7686893699099413773",
  "url": "https://www.tiktok.com/@nasa/video/7686893699099413773",
  "description": "Another big week in the sky and beyond at NASA 🚀   🔭 Roman gets a major mission-life boost 🏈 NASA takes to the skies over Pittsburgh 🌕 Artemis III booster stacking nears completion   Here’s what’s new in your NASA Minute!",
  "createdAt": "2026-09-18T16:00:00.000Z",
  "authorUsername": "nasa",
  "authorNickname": "NASA",
  "authorId": "7664638705177150477",
  "authorVerified": "Yes",
  "authorFollowers": 1800000,
  "authorFollowing": 23,
  "authorLikes": 9500000,
  "authorVideoCount": 47,
  "authorBio": "Making the seemingly impossible, possible.✨",
  "authorAvatarUrl": "https://p16-common-sign.tiktokcdn-us.com/tos-useast5-avt-0068-tx/e5143212a59c09a008bf50f487d54d1f~tplv-tiktokx-cropcenter:1080:1080.jpeg?...",
  "authorPrivate": "No",
  "authorUrl": "https://www.tiktok.com/@nasa",
  "playCount": 172000,
  "likeCount": 11700,
  "commentCount": 385,
  "shareCount": 427,
  "saveCount": 941,
  "durationSeconds": 92,
  "width": 720,
  "height": 1280,
  "definition": "720p",
  "musicId": "7686893746084547342",
  "musicTitle": "original sound - NASA",
  "musicAuthor": "NASA",
  "musicOriginal": "No",
  "musicDurationSeconds": 92,
  "musicUrl": "https://v16m.tiktokcdn-us.com/d557797f86da9e8380af305b11f69370/6ab5e535/video/tos/useast5/...",
  "musicCoverUrl": "https://p16-common.tiktokcdn-us.com/tos-useast5-avt-0068-tx/e5143212a59c09a008bf50f487d54d1f~tplv-tiktokx-cropcenter:720:720.jpeg?...",
  "hashtags": [],
  "mentions": [],
  "textLanguage": "en",
  "location": "US",
  "placeName": "Not Disclosed",
  "placeAddress": "Not Disclosed",
  "isAd": "No",
  "isPinned": "No",
  "isSlideshow": "No",
  "slideshowImages": [],
  "subtitleLanguages": ["eng-US"],
  "videoPlayUrl": "https://v16-webapp-prime.us.tiktok.com/video/tos/useast5/...",
  "videoDownloadUrl": "https://v16-webapp-prime.us.tiktok.com/video/tos/useast5/...",
  "dynamicCoverUrl": "https://p16-common-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/o4BjAVnVuiCAcCqAE1iB7Sf3IAXzwqExBJtSUI~tplv-tiktokx-origin.image?...",
  "transcriptLanguage": "eng-US",
  "transcript": "From the skies over Pittsburgh to the path back to the moon, NASA's mission kept moving forward this week. Here's what's new and your NASA minute. NASA's Nancy Grace Roman Space Telescope is off to an excellent start...",
  "comments": [
    {
      "commentId": "7686913515618468621",
      "text": "It’s always great to hear some good news!",
      "likeCount": 449,
      "replyCount": 22,
      "createdAt": "2026-09-18T16:31:42.000Z",
      "authorUsername": "usedgov",
      "authorNickname": "U.S. Department of Education"
    }
  ],
  "sourceType": "profile",
  "sourceInput": "nasa",
  "scrapedAt": "2026-09-24T21:05:15.444Z",
  "error": null
}
```

More rows from the same verification runs:

| Source | Creator | Plays | Likes | Saves | Posted | Country |
|---|---|---|---|---|---|---|
| keyword `cooking` | diy5582 | 538,900 | 8,428 | 945 | 2026-09-23 | add-on |
| keyword `cooking` | meatlicious\_ | 112,400 | 8,783 | 2,132 | 2026-09-20 | add-on |
| video URL | nasa | 1,400,000 | 92,200 | 6,817 | 2026-07-21 | US |
| hashtag `space` | toknerdytome | 150,300 | 13,200 | 315 | 2022-06-22 | US |

A value the source does not give for a video reads `Not Disclosed` (for example a tagged place on a video with none), and a field that does not apply reads `N/A` (for example `isPinned` outside profiles). Transcript and comment columns appear only when their add-on is on.

### Configure the run

Mix keywords, profiles, hashtags and video URLs in one run. `maxVideosPerSource` caps each keyword, profile or hashtag, and `maxItems` caps the whole run. The Input tab lists every option.

Track three creators' videos from the last week, newest first:

```json
{ "profiles": ["nasa", "nfl", "@zachking"], "publishedAfter": "7 days", "sortBy": "newest", "maxVideosPerSource": 50 }
```

Find the most played videos for a keyword in the UK, with transcripts:

```json
{ "keywords": ["skincare routine"], "region": "GB", "sortBy": "most-played", "minPlays": 100000, "includeTranscript": true }
```

Full details and top comments for specific videos:

```json
{ "videoUrls": ["https://www.tiktok.com/@nasa/video/7665075736742530317"], "includeComments": true, "maxCommentsPerVideo": 20 }
```

### Free users

Free-plan runs return up to 10 videos as a preview. [Upgrade your Apify plan](https://console.apify.com/sign-up?fpr=vmoqkp) to collect up to 1,000,000 videos per run.

### Run it

1. [Create a free Apify account with $5 in credit](https://console.apify.com/sign-up?fpr=vmoqkp).
2. Open the [TikTok Scraper](https://apify.com/parseforge/tiktok-scraper?fpr=vmoqkp).
3. Enter `keywords`, `profiles`, `hashtags` or `videoUrls`, add any filters, and click **Start**.
4. Export the results as CSV, Excel, JSON or XML from the **Dataset** tab, or schedule the run to follow creators and topics.

Run it programmatically through the [Apify API](https://docs.apify.com/api/v2?fpr=vmoqkp) or the [ApifyClient](https://docs.apify.com/api/client/js?fpr=vmoqkp) for JavaScript and Python. It plugs into Make, Zapier, Slack, Google Drive, Airbyte and GitHub through Apify's integrations.

### Use with AI agents (MCP)

Give an AI agent live TikTok data through the Model Context Protocol. Add the Actor to Claude, Cursor, or any MCP client:

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=parseforge/tiktok-scraper"
```

Then prompt it in plain language:

- *"Get the 30 most played TikTok videos for 'protein breakfast' in the US and tell me which creators appear more than once."*
- *"Pull NASA's TikTok videos from this month with transcripts and summarize what each one announces."*
- *"Compare plays and saves for the top 50 videos under #booktok and #bookrecs."*

Copy this into ChatGPT, Claude, or Cursor to start:

```
Use the Apify Actor "parseforge/tiktok-scraper" to collect TikTok videos. Input: { "keywords": ["<phrase>"], "profiles": ["<username>"], "hashtags": ["<tag>"], "videoUrls": ["<url>"], "region": "<US>", "publishedAfter": "<7 days>", "sortBy": "<newest|most-played|most-liked>", "maxVideosPerSource": <n>, "includeTranscript": <true|false> }. Each row has id, url, description, createdAt, authorUsername, authorFollowers, playCount, likeCount, commentCount, shareCount, saveCount, musicTitle, hashtags and, with add-ons, location, transcript and comments. Call it with the ApifyClient and my APIFY_TOKEN.
```

### Troubleshooting

**Why did a keyword return an error row?**

TikTok serves public keyword pages only for phrases people search. A rare phrase ("best coffee in buenos aires") has no page and comes back as an error row, not billed. Use a shorter, common phrase; spaces are joined with hyphens for you.

**Why do I get at most about 100 videos per keyword?**

That is where TikTok's public keyword pages stop: between 66 and 98 videos per keyword in our tests, depending on the keyword. Add related keywords or hashtags to go wider.

**Why is `location` "Not Disclosed" on keyword, profile or hashtag rows?**

The posting country lives only on the video's own page. Turn on **Add full video details**, or pass the video links in `videoUrls`, which always include it.

**Why does a video link stop working after a while?**

`videoPlayUrl`, `videoDownloadUrl` and the image links are signed by TikTok and expire, usually within a day. Download what you need soon after the run.

**Why is the transcript empty for some videos?**

About half of TikTok videos carry a caption track. Videos without one come back with an empty `transcript` and are not billed for it.

**Why was the run slower with profiles or hashtags?**

Those two lists are only released to a real browser page, so the Actor opens one page and reuses it for every profile and hashtag in the run. Keywords and video links use plain requests and are faster.

### FAQ

| Question | Answer |
|---|---|
| Do I need a TikTok account or API key? | No. It reads what TikTok shows logged-out visitors. |
| How is this different from TikTok's own API? | The Research API is for approved academic projects and the Display API covers only accounts that log in to your app. This works on any public creator, hashtag, keyword or video. |
| Can I search TikTok by keyword? | Yes, through TikTok's public keyword pages: up to about 100 videos per keyword (66 to 98 in our tests), in the region you pick. TikTok's full in-app search needs a login and is not used. |
| How many videos can I get from a profile? | As many as the profile shows publicly: 288 videos from @nfl in a 52-second test, one page of about 24 per scroll. |
| Does it get TikTok transcripts? | Yes, as an add-on, from TikTok's own caption track, English first when there is one. |
| Does it scrape comments? | A sample, as an add-on: 1 to 100 top comments per video. For every comment of a video, use TikTok Comments Scraper. |
| Can I filter by date, plays or likes? | Yes: date range, minimum plays, likes and comments, skip pinned videos and ads, and sort by date, plays, likes, comments or shares. |
| Does it download the videos? | It returns the video's play and download links. They are signed by TikTok and expire, so fetch the files soon after the run. |
| Does it need a proxy? | Usually not. If TikTok pushes back, the Actor steps up to Apify Proxy (datacenter, then residential) by itself. |
| How many results per run? | Free plan: 10. Paid: up to 1,000,000, bounded by what TikTok shows for each source. |
| Is this an official TikTok product? | No. It is unofficial and reads only public TikTok data. |

### Related actors

- [TikTok Profile Scraper](https://apify.com/parseforge/tiktok-profile-scraper?fpr=vmoqkp): creator profiles with followers, likes and bio.
- [TikTok Hashtag Analytics Scraper](https://apify.com/parseforge/tiktok-hashtag-analytics-scraper?fpr=vmoqkp): views and video counts for hashtags, with their top videos and creators.
- [TikTok Comments Scraper](https://apify.com/parseforge/tiktok-comments-scraper?fpr=vmoqkp): every comment on a video, replies included.
- [Instagram Reel Scraper](https://apify.com/parseforge/instagram-reel-scraper?fpr=vmoqkp): public Instagram reels with their stats.
- [YouTube Transcript Scraper](https://apify.com/parseforge/youtube-transcript-scraper?fpr=vmoqkp): transcripts of YouTube videos.

Browse the full [ParseForge collection](https://apify.com/parseforge?fpr=vmoqkp) for more scrapers.

🆘 **Need help?** Email parseforge@protonmail.com with your run ID, your input, and what you expected.

⚠️ **Disclaimer.** This Actor is unofficial and is not affiliated with, endorsed by, or sponsored by TikTok or ByteDance. It collects only publicly available TikTok data. You are responsible for using the data in compliance with TikTok's terms and applicable laws, including GDPR, CCPA, and PIPL. Do not use it to identify, profile, or target individuals.

# Actor input Schema

## `keywords` (type: `array`):

Find videos by keyword, the way TikTok's public keyword pages list them (up to about 100 videos per keyword). Use common phrases; spaces are joined with hyphens for you ("skincare routine" becomes "skincare-routine").

## `profiles` (type: `array`):

Videos posted by these creators. A username, @username or profile URL, e.g. "nasa" or "https://www.tiktok.com/@nasa".

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

Videos under these hashtags, e.g. "space", "#booktok" or "https://www.tiktok.com/tag/booktok".

## `videoUrls` (type: `array`):

Full details for specific videos. Video links (https://www.tiktok.com/@user/video/123...), short links (vm.tiktok.com/...) or bare video ids.

## `maxItems` (type: `integer`):

Free users: Limited to 10 items (preview). Paid users: Optional, max 1,000,000

## `maxVideosPerSource` (type: `integer`):

How many videos to take from each profile, hashtag or keyword. TikTok's keyword pages stop at about 100 videos.

## `region` (type: `string`):

The country whose TikTok feed answers keyword searches. It changes which videos come back (measured: Japan and the US share about half of their top 30 for the same keyword). Applies to keywords only.

## `publishedAfter` (type: `string`):

Keep only videos posted on or after this date. YYYY-MM-DD, or a relative span like "7 days", "2 weeks", "3 months". On profiles this also stops the scroll early, so it saves time.

## `publishedBefore` (type: `string`):

Keep only videos posted on or before this date (YYYY-MM-DD).

## `minPlays` (type: `integer`):

Keep only videos with at least this many plays.

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

Keep only videos with at least this many likes.

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

Keep only videos with at least this many comments.

## `excludePinned` (type: `boolean`):

Profiles only: leave out the videos a creator pinned to the top of the profile.

## `excludeAds` (type: `boolean`):

Leave out videos TikTok marks as ads.

## `sortBy` (type: `string`):

Order of the videos within each profile, hashtag or keyword. "As TikTok lists them" keeps TikTok's own order.

## `includeVideoDetail` (type: `boolean`):

For profiles, hashtags and keywords: also open each video's own page to add the posting country, tagged place, ad flag, caption language and the hashtag list TikTok stores. Video URLs always include them. Billed per video that returned details.

## `includeTranscript` (type: `boolean`):

Add the spoken text of each video from TikTok's own captions (English track first, when there is one). About half of videos carry captions; videos without them come back with an empty transcript and are not billed for it.

## `includeComments` (type: `boolean`):

Add a sample of each video's comments (text, likes, replies, date, commenter). Billed per video that returned at least one comment.

## `maxCommentsPerVideo` (type: `integer`):

How many comments to add to each video (1 to 100).

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

Off by default: TikTok answers most requests directly. If TikTok blocks a request, the Actor steps up to Apify Proxy (datacenter, then residential) on its own. Turn it on to start from a proxy.

## Actor input object example

```json
{
  "keywords": [
    "cooking"
  ],
  "maxItems": 10,
  "maxVideosPerSource": 30,
  "region": "US",
  "excludePinned": false,
  "excludeAds": false,
  "sortBy": "default",
  "includeVideoDetail": false,
  "includeTranscript": false,
  "includeComments": false,
  "maxCommentsPerVideo": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Key fields per video

## `fullData` (type: `string`):

Complete dataset with all 54 fields

# 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 = {
    "keywords": [
        "cooking"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("parseforge/tiktok-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 = {
    "keywords": ["cooking"],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("parseforge/tiktok-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 '{
  "keywords": [
    "cooking"
  ],
  "maxItems": 10
}' |
apify call parseforge/tiktok-scraper --silent --output-dataset

```

## MCP server setup

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